Skip to content

Commit 53efc0b

Browse files
committed
Added simple http interface to access statistics
1 parent 2e42364 commit 53efc0b

File tree

5 files changed

+402
-23
lines changed

5 files changed

+402
-23
lines changed
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
using NetworkLibrary.Components.Statistics;
2+
using Protobuff.P2P;
3+
using RrlayServerTest;
4+
using System;
5+
using System.Collections.Concurrent;
6+
using System.Collections.Generic;
7+
using System.Diagnostics;
8+
using System.Diagnostics.CodeAnalysis;
9+
using System.Linq;
10+
using System.Net;
11+
using System.Numerics;
12+
using System.Runtime.CompilerServices;
13+
using System.Runtime.Intrinsics.Arm;
14+
using System.Text;
15+
using System.Text.Json;
16+
using System.Threading.Tasks;
17+
18+
namespace RelayServer
19+
{
20+
internal class HttpSimpleVisuals
21+
{
22+
HttpListener listener = new HttpListener();
23+
private SecureProtoRelayServer? server;
24+
string p = "<html><body><body style=\"background-color:black;\"><font color=\"white\"><pre style=\"font-size: large; color: white;\">{0}</pre>";
25+
string page = "<script>setTimeout(function(){ location.reload();},1000);</script></body></html>";
26+
27+
PerformanceCounter cpuCounter;
28+
PerformanceCounter ramCounter;
29+
30+
PerformanceCounter total_cpu; //= new PerformanceCounter("Process", "% Processor Time", "_Total");
31+
PerformanceCounter process_cpu; //= new PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName);
32+
33+
DateTime LastUpdate = DateTime.Now.AddSeconds(-2);
34+
private TcpStatistics TcpGeneralStats;
35+
private UdpStatistics udpGeneralStats;
36+
private ConcurrentDictionary<Guid, TcpStatistics> tctSessionStats;
37+
private ConcurrentDictionary<IPEndPoint, UdpStatistics> udpSessionStats;
38+
private GeneralStats generalStatJsonObject;
39+
40+
public HttpSimpleVisuals(SecureProtoRelayServer s)
41+
{
42+
ArgumentNullException.ThrowIfNull(s);
43+
this.server = s;
44+
45+
46+
}
47+
48+
49+
50+
public void BeginService()
51+
{
52+
//>netsh http add iplisten ipaddress=0.0.0.0:20012
53+
//netsh http add urlacl url=http://*:20012/ user=everyone
54+
listener.Prefixes.Add("http://*:20012/");
55+
listener.Prefixes.Add("http://*:20012/generalstats/");
56+
57+
listener.Start();
58+
59+
Task.Run(() =>
60+
{
61+
while (true)
62+
{
63+
HttpListenerContext context = listener.GetContext();
64+
HttpListenerRequest req = context.Request;
65+
if (req.HttpMethod == "GET")
66+
{
67+
if (req.RawUrl.Equals("/generalstats", StringComparison.OrdinalIgnoreCase))
68+
{
69+
PrepareJsonResponse(context);
70+
}
71+
else if (req.RawUrl.Equals("/text", StringComparison.OrdinalIgnoreCase))
72+
{
73+
PreparePrettyJsonPageResponse(context);
74+
}
75+
else
76+
{
77+
PrepareTextResponse(context);
78+
79+
}
80+
}
81+
82+
}
83+
});
84+
}
85+
86+
#region Response
87+
private void PrepareTextResponse(HttpListenerContext context)
88+
{
89+
using HttpListenerResponse resp = context.Response;
90+
resp.Headers.Set("Content-Type", "text/html");
91+
92+
Update();
93+
94+
string data =
95+
"Session Count: " + tctSessionStats.Count + "\n" +
96+
"Cpu Usage: " + PerformanceStatistics.GetCpuUsage() + "\n" +
97+
"Memory Usage: " + PerformanceStatistics.GetMemoryUsage() + "\n" +
98+
TcpGeneralStats.ToString() + "\n\n" +
99+
udpGeneralStats.ToString();
100+
101+
var page_ = string.Format(p, data) + page;
102+
103+
byte[] buffer = Encoding.UTF8.GetBytes(page_);
104+
resp.ContentLength64 = buffer.Length;
105+
106+
using Stream ros = resp.OutputStream;
107+
ros.Write(buffer, 0, buffer.Length);
108+
}
109+
private void PrepareJsonResponse(HttpListenerContext context)
110+
{
111+
using HttpListenerResponse resp2 = context.Response;
112+
113+
resp2.Headers.Set("Content-Type", "application/json; charset=utf-8");
114+
resp2.Headers.Set("Access-Control-Allow-Origin", "*");
115+
byte[] buffer_ = Encoding.UTF8.GetBytes(GetGeneralStatistics());
116+
117+
resp2.ContentLength64 = buffer_.Length;
118+
using Stream stream = resp2.OutputStream;
119+
stream.Write(buffer_, 0, buffer_.Length);
120+
}
121+
private void PreparePrettyJsonPageResponse(HttpListenerContext context)
122+
{
123+
using HttpListenerResponse resp2 = context.Response;
124+
125+
resp2.Headers.Set("Content-Type", "text/html");
126+
resp2.Headers.Set("Access-Control-Allow-Origin", "*");
127+
byte[] buffer_ = Encoding.UTF8.GetBytes(Resources.StatisticsPage);
128+
129+
resp2.ContentLength64 = buffer_.Length;
130+
using Stream stream = resp2.OutputStream;
131+
stream.Write(buffer_, 0, buffer_.Length);
132+
}
133+
134+
#endregion
135+
136+
public bool Update()
137+
{
138+
if ((DateTime.Now - LastUpdate).TotalMilliseconds < 900)
139+
return false;
140+
LastUpdate = DateTime.Now;
141+
server.GetTcpStatistics(out TcpGeneralStats, out tctSessionStats);
142+
server.GetUdpStatistics(out udpGeneralStats, out udpSessionStats);
143+
return true;
144+
}
145+
146+
public string GetGeneralStatistics()
147+
{
148+
if (Update())
149+
{
150+
generalStatJsonObject = new GeneralStats()
151+
{
152+
ResourceUsage = new ResourceUsage()
153+
{
154+
TotalSessions = tctSessionStats.Count.ToString(),
155+
CpuUsage = PerformanceStatistics.GetCpuUsage(),
156+
RamUsage = PerformanceStatistics.GetMemoryUsage()
157+
},
158+
TcpGeneralStats = TcpGeneralStats.Stringify(),
159+
UdpGeneralStats = udpGeneralStats.Stringify()
160+
};
161+
}
162+
163+
return GetJson(generalStatJsonObject);
164+
165+
}
166+
167+
public string GetSessionStatistics()
168+
{
169+
Update();
170+
171+
var stats = new Dictionary<Guid, StatisticsJson>();
172+
foreach (var item in tctSessionStats)
173+
{
174+
var stat = new StatisticsJson();
175+
stat.TcpData = item.Value.Stringify();
176+
stat.TcpEndpoint = new IpEndpointJsonData(server.GetIPEndPoint(item.Key));
177+
stats[item.Key] = stat;
178+
179+
}
180+
181+
foreach (var item in udpSessionStats)
182+
{
183+
if (server.TryGetClientId(item.Key, out var clientId)
184+
&& stats.ContainsKey(clientId))
185+
{
186+
stats[clientId].UDpData = item.Value.Stringify();
187+
stats[clientId].UdpEndpoint = new IpEndpointJsonData(item.Key);
188+
}
189+
}
190+
return GetJson(stats);
191+
}
192+
193+
private string GetJson<T>(T data) where T : class
194+
{
195+
return JsonSerializer.Serialize<T>(data, new JsonSerializerOptions() { WriteIndented = true });
196+
}
197+
198+
public class StatisticsJson
199+
{
200+
public IpEndpointJsonData UdpEndpoint { get; set; }
201+
public IpEndpointJsonData TcpEndpoint { get; set; }
202+
203+
public TcpStatisticsStringData TcpData { get; set; }
204+
205+
public UdpStatisticsStringData UDpData { get; set; }
206+
207+
}
208+
public class GeneralStats
209+
{
210+
public ResourceUsage ResourceUsage { get; set; }
211+
public TcpStatisticsStringData TcpGeneralStats { get; set; }
212+
public UdpStatisticsStringData UdpGeneralStats { get; set; }
213+
214+
}
215+
216+
public class ResourceUsage
217+
{
218+
public string TotalSessions { get; set; }
219+
public string CpuUsage { get; set; }
220+
public string RamUsage { get; set; }
221+
}
222+
223+
public class IpEndpointJsonData
224+
{
225+
public string Ip { get; set; }
226+
public string Port { get; set; }
227+
public IpEndpointJsonData(IPEndPoint ep)
228+
{
229+
Ip = ep.Address.MapToIPv4().ToString();
230+
Port = ep.Port.ToString();
231+
}
232+
}
233+
234+
235+
236+
}
237+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace RelayServer
9+
{
10+
internal class PerformanceStatistics
11+
{
12+
private static Process process;
13+
private static TimeSpan lastProctime;
14+
private static DateTime lastRequestTime;
15+
private static string lastCpuUsage;
16+
private static string lastMemoryUsage;
17+
18+
static PerformanceStatistics()
19+
{
20+
process = Process.GetCurrentProcess();
21+
lastProctime=process.TotalProcessorTime;
22+
lastRequestTime = DateTime.Now;
23+
}
24+
public static string GetCpuUsage()
25+
{
26+
if((DateTime.Now - lastRequestTime).TotalMilliseconds < 900)
27+
{
28+
return lastCpuUsage;
29+
}
30+
var currentProcessorTime = process.TotalProcessorTime;
31+
var currentTimeStamp = DateTime.Now;
32+
double CPUUsage = (currentProcessorTime.TotalMilliseconds - lastProctime.TotalMilliseconds) / currentTimeStamp.Subtract(lastRequestTime).TotalMilliseconds / Convert.ToDouble(Environment.ProcessorCount);
33+
lastRequestTime = currentTimeStamp;
34+
lastProctime = currentProcessorTime;
35+
lastCpuUsage = (CPUUsage * 100).ToString("N3") + "%";
36+
return lastCpuUsage;
37+
38+
}
39+
40+
public static string GetMemoryUsage()
41+
{
42+
if ((DateTime.Now - lastRequestTime).TotalMilliseconds < 900)
43+
{
44+
return lastMemoryUsage;
45+
}
46+
47+
process = Process.GetCurrentProcess();
48+
const double f = 1024.0 * 1024.0;
49+
lastMemoryUsage = (process.WorkingSet64 / f).ToString("N3") + "MB";
50+
return lastMemoryUsage;
51+
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)