lampac/Lampac/Controllers/OpenStatController.cs
lampac-talks f843f04fd4 chore: initial commit 154.3
Signed-off-by: lampac-talks <lampac-talks@users.noreply.github.com>
2026-01-30 16:23:09 +03:00

196 lines
6.4 KiB
C#

using Lampac.Engine;
using Lampac.Engine.Middlewares;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Shared;
using Shared.Engine;
using Shared.Engine.Pools;
using Shared.Models.AppConf;
using Shared.PlaywrightCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
namespace Lampac.Controllers
{
public class OpenStatController : BaseController
{
public OpenStatConf openstat => AppInit.conf.openstat;
public bool IsDeny(out string ermsg)
{
ermsg = "Включите openstat в init.conf\n\n\"openstat\": {\n \"enable\": true\n}";
if (!openstat.enable || (!string.IsNullOrEmpty(openstat.token) && openstat.token != HttpContext.Request.Query["token"].ToString()))
return true;
return false;
}
#region browser/context
[HttpGet]
[AllowAnonymous]
[Route("/stats/browser/context")]
public ActionResult BrowserContext()
{
if (IsDeny(out string ermsg))
return Content(ermsg, "text/plain; charset=utf-8");
return Json(new
{
Chromium = new
{
open = Chromium.ContextsCount,
req_keepopen = Chromium.stats_keepopen,
req_newcontext = Chromium.stats_newcontext,
ping = new
{
Chromium.stats_ping.status,
Chromium.stats_ping.time,
Chromium.stats_ping.ex
}
},
Firefox = new
{
open = Firefox.ContextsCount,
req_keepopen = Firefox.stats_keepopen,
req_newcontext = Firefox.stats_newcontext
}
});
}
#endregion
#region request
[HttpGet]
[AllowAnonymous]
[Route("/stats/request")]
public ActionResult Requests()
{
if (IsDeny(out string ermsg))
return Content(ermsg, "text/plain; charset=utf-8");
var now = DateTime.UtcNow;
long req_min = 0;
if (memoryCache.TryGetValue($"stats:request:{now.Hour}:{now.AddMinutes(-1).Minute}", out CounterRequestInfo _counter))
req_min = _counter.Value;
long req_hour = req_min;
for (int i = 1; i < 60; i++)
{
var cutoff = now.AddMinutes(-i);
if (memoryCache.TryGetValue($"stats:request:{cutoff.Hour}:{cutoff.Minute}", out CounterRequestInfo _r))
req_hour += _r.Value;
}
var responseStats = RequestStatisticsTracker.GetResponseTimeStatsLastMinute();
var httpResponseMs = new Dictionary<string, object>
{
["avg"] = Math.Round(responseStats.Average, 2)
};
foreach (var percentile in responseStats.PercentileAverages.OrderBy(x => x.Key))
httpResponseMs.Add(percentile.Key.ToString(), Math.Round(percentile.Value, 2));
return Json(new
{
req_min,
req_hour,
tcpConnections = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections().Length,
nws_online = NativeWebSocket.CountConnection,
soks_online = soks.connections,
http_active = RequestStatisticsTracker.ActiveHttpRequests,
http_response_ms = httpResponseMs
});
}
#endregion
#region rch
[HttpGet]
[AllowAnonymous]
[Route("/stats/rch")]
public ActionResult Rhc()
{
if (IsDeny(out string ermsg))
return Content(ermsg, "text/plain; charset=utf-8");
var now = DateTime.UtcNow;
int receive = 0, send = 0;
if (memoryCache.TryGetValue("stats:nws", out CounterNws _c))
{
receive = _c.receive;
send = _c.send;
}
return Json(new
{
clients = RchClient.clients.Count,
counter = new
{
receive,
send
},
rchIds = RchClient.rchIds.Count
});
}
#endregion
#region TempDb
[HttpGet]
[AllowAnonymous]
[Route("/stats/tempdb")]
public ActionResult TempDb()
{
if (IsDeny(out string ermsg))
return Content(ermsg, "text/plain; charset=utf-8");
return Json(new
{
HybridCache = HybridCache.Stat_ContTempDb,
HybridFileCache = HybridFileCache.Stat_ContTempDb,
ProxyLink = ProxyLink.Stat_ContLinks,
ProxyAPI = ProxyAPI.Stat_ContCacheFiles,
ProxyTmdb = ProxyTmdb.Stat_ContCacheFiles,
ProxyImg = ProxyImg.Stat_ContCacheFiles,
ProxyCub = ProxyCub.Stat_ContCacheFiles,
SemaphorManager = SemaphorManager.Stat_ContSemaphoreLocks,
rch = new
{
clients = RchClient.clients.Count,
Ids = RchClient.rchIds.Count
},
pool = new
{
msm = new
{
PoolInvk.msm.SmallPoolInUseSize,
PoolInvk.msm.LargePoolInUseSize,
PoolInvk.msm.SmallBlocksFree,
PoolInvk.msm.SmallPoolFreeSize,
PoolInvk.msm.LargeBuffersFree,
PoolInvk.msm.LargePoolFreeSize
},
StringBuilder = new
{
Rent = StringBuilderPool.RentNew,
Free = StringBuilderPool.FreeCont,
StringBuilderPool.GC
},
MemoryStream = MemoryStreamPool.Count == 0 ? null : new
{
MemoryStreamPool.Count,
MemoryStreamPool.GC
}
},
memoryCache = memoryCache.GetCurrentStatistics()
});
}
#endregion
}
}