diff --git a/.github/renovate.json5 b/.github/renovate.json5 index ae41fb76e6929..043373b802aec 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -12,5 +12,13 @@ ], "git-submodules": { "enabled": true - } + }, + "packageRules": [ + { + // TODO: <= 1.7.0-rc.1 for invalid response on monitoring endpoint, last failed version 1.8.0-rc.1 - https://github.com/open-telemetry/opentelemetry-dotnet/issues/5506 + "allowedVersions": "<= 1.7.0-rc.1", + "matchManagers": [ "nuget" ], + "matchPackageNames": [ "OpenTelemetry.Exporter.Prometheus.AspNetCore" ] + } + ] } diff --git a/ArchiSteamFarm.OfficialPlugins.Monitoring/MonitoringPlugin.cs b/ArchiSteamFarm.OfficialPlugins.Monitoring/MonitoringPlugin.cs index d64caf32f2244..9d8c668954b4f 100644 --- a/ArchiSteamFarm.OfficialPlugins.Monitoring/MonitoringPlugin.cs +++ b/ArchiSteamFarm.OfficialPlugins.Monitoring/MonitoringPlugin.cs @@ -50,6 +50,21 @@ internal sealed class MonitoringPlugin : OfficialPlugin, IWebServiceProvider, IG 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, SharedInfo.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; [JsonInclude] @@ -106,6 +121,18 @@ private void InitializeMeter() { Meter = new Meter(MeterName, Version.ToString()); + Meter.CreateObservableGauge( + $"{MetricNamePrefix}_build_info", + static () => BuildInfo, + description: "Build information about ASF in form of label values" + ); + + Meter.CreateObservableGauge( + $"{MetricNamePrefix}_runtime_info", + static () => RuntimeInfo, + description: "Runtime information about ASF in form of label values" + ); + Meter.CreateObservableGauge( $"{MetricNamePrefix}_ipc_banned_ips", static () => ApiAuthenticationMiddleware.GetCurrentlyBannedIPs().Count(), @@ -150,13 +177,15 @@ private void InitializeMeter() { description: "Number of Steam groups each bot is in" ); + // Keep in mind that we use a unit here and the unit needs to be a suffix to the name Meter.CreateObservableGauge( - $"{MetricNamePrefix}_bot_farming_minutes_remaining", static () => { + $"{MetricNamePrefix}_bot_farming_time_remaining_{Units.Minutes}", static () => { ICollection bots = Bot.Bots?.Values ?? Array.Empty(); return bots.Select(static bot => new Measurement(bot.CardsFarmer.TimeRemaining.TotalMinutes, new KeyValuePair(TagNames.BotName, bot.BotName), new KeyValuePair(TagNames.SteamID, bot.SteamID))); }, - description: "Approximate number of minutes remaining until each bot has finished farming all cards" + Units.Minutes, + "Approximate number of minutes remaining until each bot has finished farming all cards" ); Meter.CreateObservableGauge( diff --git a/ArchiSteamFarm.OfficialPlugins.Monitoring/TagNames.cs b/ArchiSteamFarm.OfficialPlugins.Monitoring/TagNames.cs index bbe3ea1543cb5..8945c3ea5f844 100644 --- a/ArchiSteamFarm.OfficialPlugins.Monitoring/TagNames.cs +++ b/ArchiSteamFarm.OfficialPlugins.Monitoring/TagNames.cs @@ -27,5 +27,10 @@ internal static class TagNames { internal const string BotName = "bot"; internal const string BotState = "state"; internal const string CurrencyCode = "currency"; + internal const string Framework = "framework"; + internal const string OS = "operating_system"; + internal const string Runtime = "runtime"; internal const string SteamID = "steamid"; + internal const string Variant = "variant"; + internal const string Version = "version"; } diff --git a/ArchiSteamFarm.OfficialPlugins.Monitoring/Units.cs b/ArchiSteamFarm.OfficialPlugins.Monitoring/Units.cs new file mode 100644 index 0000000000000..e77f20da17a60 --- /dev/null +++ b/ArchiSteamFarm.OfficialPlugins.Monitoring/Units.cs @@ -0,0 +1,28 @@ +// ---------------------------------------------------------------------------------------------- +// _ _ _ ____ _ _____ +// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___ +// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \ +// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | +// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| +// ---------------------------------------------------------------------------------------------- +// | +// Copyright 2015-2024 Ɓukasz "JustArchi" Domeradzki +// Contact: JustArchi@JustArchi.net +// | +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// | +// http://www.apache.org/licenses/LICENSE-2.0 +// | +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ArchiSteamFarm.OfficialPlugins.Monitoring; + +internal static class Units { + internal const string Minutes = "minutes"; +} diff --git a/ArchiSteamFarm/Core/OS.cs b/ArchiSteamFarm/Core/OS.cs index 38c61ef4639e8..89758026026c2 100644 --- a/ArchiSteamFarm/Core/OS.cs +++ b/ArchiSteamFarm/Core/OS.cs @@ -37,10 +37,20 @@ using ArchiSteamFarm.Localization; using ArchiSteamFarm.Storage; using ArchiSteamFarm.Web; +using JetBrains.Annotations; namespace ArchiSteamFarm.Core; internal static class OS { + [PublicAPI] + public static string? Description => TrimAndNullifyEmptyString(RuntimeInformation.OSDescription); + + [PublicAPI] + public static string? Framework => TrimAndNullifyEmptyString(RuntimeInformation.FrameworkDescription); + + [PublicAPI] + public static string? Runtime => TrimAndNullifyEmptyString(RuntimeInformation.RuntimeIdentifier); + // We need to keep this one assigned and not calculated on-demand internal static readonly string ProcessFileName = Environment.ProcessPath ?? throw new InvalidOperationException(nameof(ProcessFileName)); @@ -58,25 +68,7 @@ internal static string Version { return BackingVersion; } - string framework = RuntimeInformation.FrameworkDescription.Trim(); - - if (framework.Length == 0) { - framework = "Unknown Framework"; - } - - string runtime = RuntimeInformation.RuntimeIdentifier.Trim(); - - if (runtime.Length == 0) { - runtime = "Unknown Runtime"; - } - - string description = RuntimeInformation.OSDescription.Trim(); - - if (description.Length == 0) { - description = "Unknown OS"; - } - - BackingVersion = $"{framework}; {runtime}; {description}"; + BackingVersion = $"{Framework ?? "Unknown Framework"}; {Runtime ?? "Unknown Runtime"}; {Description ?? "Unknown OS"}"; return BackingVersion; } @@ -296,6 +288,14 @@ private static void MinimizeConsoleWindow() { } } + private static string? TrimAndNullifyEmptyString(string s) { + ArgumentNullException.ThrowIfNull(s); + + s = s.Trim(); + + return s.Length == 0 ? null : s; + } + [SupportedOSPlatform("Windows")] private static void WindowsDisableQuickEditMode() { if (!OperatingSystem.IsWindows()) { diff --git a/ArchiSteamFarm/SharedInfo.cs b/ArchiSteamFarm/SharedInfo.cs index 990ac7587e2ef..cab40f8e6efc8 100644 --- a/ArchiSteamFarm/SharedInfo.cs +++ b/ArchiSteamFarm/SharedInfo.cs @@ -102,7 +102,7 @@ internal static string HomeDirectory { internal static string PublicIdentifier => $"{AssemblyName}{(BuildInfo.IsCustomBuild ? "-custom" : PluginsCore.HasCustomPluginsLoaded ? "-modded" : "")}"; internal static Version Version => Assembly.GetExecutingAssembly().GetName().Version ?? throw new InvalidOperationException(nameof(Version)); - private static Guid ModuleVersion => Assembly.GetExecutingAssembly().ManifestModule.ModuleVersionId; + internal static Guid ModuleVersion => Assembly.GetExecutingAssembly().ManifestModule.ModuleVersionId; private static string? CachedHomeDirectory; diff --git a/Directory.Packages.props b/Directory.Packages.props index 84663360580a7..b77795948641f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,7 +10,7 @@ - +