mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-18 14:07:53 +03:00
## Mirror of PR #26284: [Add Prometheus stats for admin count](https://github.com/space-wizards/space-station-14/pull/26284) from <img src="https://avatars.githubusercontent.com/u/10567778?v=4" alt="space-wizards" width="22"/> [space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14) ###### `a1817a12dbb385275f4273c1abf48fac0a989ddd` PR opened by <img src="https://avatars.githubusercontent.com/u/8107459?v=4" width="16"/><a href="https://github.com/PJB3005"> PJB3005</a> at 2024-03-20 10:12:29 UTC --- PR changed 2 files with 106 additions and 1 deletions. The PR had the following labels: - Status: Needs Review --- <details open="true"><summary><h1>Original Body</h1></summary> > Fixes #20828 > > Reports time series for admin count. Counts are separated by state (active, AFK, or deadminned) and admin rank. > > Requires engine master </details> Co-authored-by: SimpleStation14 <Unknown>
99 lines
3.3 KiB
C#
99 lines
3.3 KiB
C#
using System.Diagnostics.Metrics;
|
|
using System.Runtime.InteropServices;
|
|
using Content.Server.Afk;
|
|
using Robust.Server.DataMetrics;
|
|
|
|
namespace Content.Server.Administration.Managers;
|
|
|
|
// Handles metrics reporting for active admin count and such.
|
|
|
|
public sealed partial class AdminManager
|
|
{
|
|
private Dictionary<int, (int active, int afk, int deadminned)>? _adminOnlineCounts;
|
|
|
|
private const int SentinelRankId = -1;
|
|
|
|
[Dependency] private readonly IMetricsManager _metrics = default!;
|
|
[Dependency] private readonly IAfkManager _afkManager = default!;
|
|
[Dependency] private readonly IMeterFactory _meterFactory = default!;
|
|
|
|
private void InitializeMetrics()
|
|
{
|
|
_metrics.UpdateMetrics += MetricsOnUpdateMetrics;
|
|
|
|
var meter = _meterFactory.Create("SS14.AdminManager");
|
|
|
|
meter.CreateObservableGauge(
|
|
"admins_online_count",
|
|
MeasureAdminCount,
|
|
null,
|
|
"The count of online admins");
|
|
}
|
|
|
|
private void MetricsOnUpdateMetrics()
|
|
{
|
|
_sawmill.Verbose("Updating metrics");
|
|
|
|
var dict = new Dictionary<int, (int active, int afk, int deadminned)>();
|
|
|
|
foreach (var (session, reg) in _admins)
|
|
{
|
|
var rankId = reg.RankId ?? SentinelRankId;
|
|
|
|
ref var counts = ref CollectionsMarshal.GetValueRefOrAddDefault(dict, rankId, out _);
|
|
|
|
if (reg.Data.Active)
|
|
{
|
|
if (_afkManager.IsAfk(session))
|
|
counts.afk += 1;
|
|
else
|
|
counts.active += 1;
|
|
}
|
|
else
|
|
{
|
|
counts.deadminned += 1;
|
|
}
|
|
}
|
|
|
|
// Neither prometheus-net nor dotnet-counters seem to handle stuff well if we STOP returning measurements.
|
|
// i.e. if the last admin with a rank disconnects.
|
|
// So if we have EVER reported a rank, always keep reporting it.
|
|
if (_adminOnlineCounts != null)
|
|
{
|
|
foreach (var rank in _adminOnlineCounts.Keys)
|
|
{
|
|
CollectionsMarshal.GetValueRefOrAddDefault(dict, rank, out _);
|
|
}
|
|
}
|
|
|
|
// Make sure "no rank" is always available. Avoid "no data".
|
|
CollectionsMarshal.GetValueRefOrAddDefault(dict, SentinelRankId, out _);
|
|
|
|
_adminOnlineCounts = dict;
|
|
}
|
|
|
|
private IEnumerable<Measurement<int>> MeasureAdminCount()
|
|
{
|
|
if (_adminOnlineCounts == null)
|
|
yield break;
|
|
|
|
foreach (var (rank, (active, afk, deadminned)) in _adminOnlineCounts)
|
|
{
|
|
yield return new Measurement<int>(
|
|
active,
|
|
new KeyValuePair<string, object?>("state", "active"),
|
|
new KeyValuePair<string, object?>("rank", rank == SentinelRankId ? "none" : rank.ToString()));
|
|
|
|
yield return new Measurement<int>(
|
|
afk,
|
|
new KeyValuePair<string, object?>("state", "afk"),
|
|
new KeyValuePair<string, object?>("rank", rank == SentinelRankId ? "none" : rank.ToString()));
|
|
|
|
yield return new Measurement<int>(
|
|
deadminned,
|
|
new KeyValuePair<string, object?>("state", "deadminned"),
|
|
new KeyValuePair<string, object?>("rank", rank == SentinelRankId ? "none" : rank.ToString()));
|
|
}
|
|
}
|
|
}
|