diff --git a/ArchiSteamFarm.OfficialPlugins.Monitoring/MonitoringPlugin.cs b/ArchiSteamFarm.OfficialPlugins.Monitoring/MonitoringPlugin.cs index 7915ea6cc45e9..e7aa39ed5b04a 100644 --- a/ArchiSteamFarm.OfficialPlugins.Monitoring/MonitoringPlugin.cs +++ b/ArchiSteamFarm.OfficialPlugins.Monitoring/MonitoringPlugin.cs @@ -23,7 +23,6 @@ using System; using System.Collections.Concurrent; -using System.Collections.Frozen; using System.Collections.Generic; using System.Composition; using System.Diagnostics.CodeAnalysis; @@ -47,30 +46,13 @@ namespace ArchiSteamFarm.OfficialPlugins.Monitoring; [Export(typeof(IPlugin))] [SuppressMessage("ReSharper", "MemberCanBeFileLocal")] -internal sealed class MonitoringPlugin : OfficialPlugin, IDisposable, IOfficialGitHubPluginUpdates, IWebInterface, IWebServiceProvider, IBotTradeOfferResults { +internal sealed class MonitoringPlugin : OfficialPlugin, IBot, IBotTradeOfferResults, IDisposable, IOfficialGitHubPluginUpdates, IWebInterface, IWebServiceProvider { private const string MeterName = SharedInfo.AssemblyName; - private const string MetricNamePrefix = "asf"; - private const string UnknownLabelValueFallback = "unknown"; - private static readonly Measurement BuildInfo = new( - 1, - new KeyValuePair(TagNames.Version, SharedInfo.Version.ToString()), - new KeyValuePair(TagNames.Variant, Core.BuildInfo.Variant) - ); - - private static readonly Measurement RuntimeInfo = new( - 1, - new KeyValuePair(TagNames.Framework, OS.Framework ?? UnknownLabelValueFallback), - new KeyValuePair(TagNames.Runtime, OS.Runtime ?? UnknownLabelValueFallback), - new KeyValuePair(TagNames.OS, OS.Description ?? UnknownLabelValueFallback) - ); - private static bool Enabled => ASF.GlobalConfig?.IPC ?? GlobalConfig.DefaultIPC; - private static FrozenSet>? PluginMeasurements; - [JsonInclude] public override string Name => nameof(MonitoringPlugin); @@ -85,6 +67,20 @@ internal sealed class MonitoringPlugin : OfficialPlugin, IDisposable, IOfficialG public void Dispose() => Meter?.Dispose(); + public Task OnBotDestroy(Bot bot) { + ArgumentNullException.ThrowIfNull(bot); + + TradeStatistics.TryRemove(bot, out _); + + return Task.CompletedTask; + } + + public Task OnBotInit(Bot bot) { + ArgumentNullException.ThrowIfNull(bot); + + return Task.CompletedTask; + } + public Task OnBotTradeOfferResults(Bot bot, IReadOnlyCollection tradeResults) { ArgumentNullException.ThrowIfNull(bot); ArgumentNullException.ThrowIfNull(tradeResults); @@ -117,6 +113,10 @@ public void OnConfiguringServices(IServiceCollection services) { InitializeMeter(); + if (Meter == null) { + throw new InvalidOperationException(nameof(Meter)); + } + services.AddOpenTelemetry().WithMetrics( builder => { builder.AddPrometheusExporter(static config => config.ScrapeEndpointPath = "/Api/metrics"); @@ -130,29 +130,31 @@ public void OnConfiguringServices(IServiceCollection services) { public override Task OnLoaded() => Task.CompletedTask; - [MemberNotNull(nameof(Meter))] private void InitializeMeter() { if (Meter != null) { return; } - PluginMeasurements = new HashSet>(3) { - new(PluginsCore.ActivePlugins.Count), - new(PluginsCore.ActivePlugins.Count(static plugin => plugin is OfficialPlugin), new KeyValuePair(TagNames.PluginType, "official")), - new(PluginsCore.ActivePlugins.Count(static plugin => plugin is not OfficialPlugin), new KeyValuePair(TagNames.PluginType, "custom")) - }.ToFrozenSet(); - Meter = new Meter(MeterName, Version.ToString()); Meter.CreateObservableGauge( $"{MetricNamePrefix}_build_info", - static () => BuildInfo, + static () => new Measurement( + 1, + new KeyValuePair(TagNames.Version, SharedInfo.Version.ToString()), + new KeyValuePair(TagNames.Variant, BuildInfo.Variant) + ), description: "Build information about ASF in form of label values" ); Meter.CreateObservableGauge( $"{MetricNamePrefix}_runtime_info", - static () => RuntimeInfo, + static () => new Measurement( + 1, + new KeyValuePair(TagNames.Framework, OS.Framework ?? UnknownLabelValueFallback), + new KeyValuePair(TagNames.Runtime, OS.Runtime ?? UnknownLabelValueFallback), + new KeyValuePair(TagNames.OS, OS.Description ?? UnknownLabelValueFallback) + ), description: "Runtime information about ASF in form of label values" ); @@ -164,7 +166,11 @@ private void InitializeMeter() { Meter.CreateObservableGauge( $"{MetricNamePrefix}_active_plugins", - static () => PluginMeasurements, + static () => new HashSet>(3) { + new(PluginsCore.ActivePlugins.Count), + new(PluginsCore.ActivePlugins.Count(static plugin => plugin is OfficialPlugin), new KeyValuePair(TagNames.PluginType, "official")), + new(PluginsCore.ActivePlugins.Count(static plugin => plugin is not OfficialPlugin), new KeyValuePair(TagNames.PluginType, "custom")) + }, description: "Number of plugins currently loaded in ASF" );