add OS platform type to temporary stats

This commit is contained in:
Jesse Plamondon-Willard
2026-03-26 22:42:35 -04:00
parent 87bfc1b093
commit 88c2250738
6 changed files with 24 additions and 6 deletions
+3
View File
@@ -6,6 +6,9 @@
* Improved performance.
* Improved error message when a mod is blocked by Windows Smart App Control.
* For mod authors:
* Added OS metrics to the [metrics API](technical/web.md#modsmetrics).
## 4.5.2
Released 14 March 2026 for Stardew Valley 1.6.14 or later. See [build attestation](https://github.com/Pathoschild/SMAPI/attestations/21366863).
@@ -28,7 +28,7 @@ public class ModSearchModel
public ISemanticVersion GameVersion { get; set; }
/// <summary>The OS on which the player plays.</summary>
public Platform Platform { get; set; }
public Platform? Platform { get; set; }
/*********
@@ -83,7 +83,7 @@ internal class ModsApiController : Controller
public async Task<IEnumerable<ModEntryModel>> PostAsync([FromBody] ModSearchModel? model, [FromRoute] string version)
{
ApiMetricsModel metrics = MetricsManager.GetMetricsForNow();
metrics.TrackRequest(model?.ApiVersion, model?.GameVersion);
metrics.TrackRequest(model?.ApiVersion, model?.GameVersion, model?.Platform);
if (model?.Mods == null)
return Array.Empty<ModEntryModel>();
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using StardewModdingAPI.Toolkit.Framework.UpdateData;
using StardewModdingAPI.Toolkit.Utilities;
namespace StardewModdingAPI.Web.Framework.Metrics;
@@ -14,7 +15,7 @@ internal class ApiMetricsModel
public int ApiRequests { get; private set; }
/// <summary>The metrics by mod site.</summary>
public Dictionary<ModSiteKey, MetricsModel> Sites { get; } = new();
public Dictionary<ModSiteKey, MetricsModel> Sites { get; } = [];
/// <summary>The number of update-check requests by SMAPI version.</summary>
public Dictionary<string, long> ByApiVersion { get; } = new(StringComparer.OrdinalIgnoreCase);
@@ -22,6 +23,9 @@ internal class ApiMetricsModel
/// <summary>The number of update-check requests by game version.</summary>
public Dictionary<string, long> ByGameVersion { get; } = new(StringComparer.OrdinalIgnoreCase);
/// <summary>The number of update-check requests by OS platform.</summary>
public Dictionary<string, long> ByPlatform { get; } = [];
/*********
** Public methods
@@ -29,15 +33,18 @@ internal class ApiMetricsModel
/// <summary>Track an update-check request received by the API.</summary>
/// <param name="apiVersion">The SMAPI version installed by the player.</param>
/// <param name="gameVersion">The game version installed by the player.</param>
public void TrackRequest(ISemanticVersion? apiVersion, ISemanticVersion? gameVersion)
/// <param name="platform">The OS platform used by the player.</param>
public void TrackRequest(ISemanticVersion? apiVersion, ISemanticVersion? gameVersion, Platform? platform)
{
this.ApiRequests++;
string apiVersionStr = apiVersion?.ToString() ?? "<none specified>";
string gameVersionStr = gameVersion?.ToString() ?? "<none specified>";
string platformStr = platform?.ToString() ?? "<none specified>";
this.ByApiVersion[apiVersionStr] = this.ByApiVersion.GetValueOrDefault(apiVersionStr) + 1;
this.ByGameVersion[gameVersionStr] = this.ByGameVersion.GetValueOrDefault(gameVersionStr) + 1;
this.ByPlatform[platformStr] = this.ByPlatform.GetValueOrDefault(platformStr) + 1;
}
/// <summary>Track the update-check result for a specific update key.</summary>
@@ -49,6 +49,7 @@ internal static class MetricsManager
var byDate = new Dictionary<string, ApiMetricsModel>();
var byApiVersion = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
var byGameVersion = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
var byPlatform = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
foreach ((string hourlyKey, ApiMetricsModel hourly) in MetricsManager.Metrics)
{
// totals
@@ -76,6 +77,10 @@ internal static class MetricsManager
foreach ((string gameVersion, long count) in hourly.ByGameVersion)
byGameVersion[gameVersion] = byGameVersion.GetValueOrDefault(gameVersion) + count;
// by platform
foreach ((string platform, long count) in hourly.ByPlatform)
byPlatform[platform] = byPlatform.GetValueOrDefault(platform) + count;
daily.AggregateFrom(hourly);
}
@@ -90,6 +95,7 @@ internal static class MetricsManager
TotalErrorCacheMisses: totals.ErrorCacheMisses,
ByApiVersion: byApiVersion,
ByGameVersion: byGameVersion,
ByPlatform: byPlatform,
BySite: bySite,
ByDate: byDate
);
@@ -13,8 +13,9 @@ namespace StardewModdingAPI.Web.Framework.Metrics;
/// <param name="TotalCacheHits">The number of times an update key returned data from the cache.</param>
/// <param name="TotalSuccessCacheMisses">The number of times an update key successfully fetched data from a remote mod site.</param>
/// <param name="TotalErrorCacheMisses">The number of times an update key could not fetch data from a remote mod site (e.g. mod page didn't exist or mod site returned an API error).</param>
/// <param name="ByApiVersion">The number of update-check request by SMAPI version.</param>
/// <param name="ByGameVersion">The number of update-check request by game version.</param>
/// <param name="ByApiVersion">The number of update-check requests by SMAPI version.</param>
/// <param name="ByGameVersion">The number of update-check requests by game version.</param>
/// <param name="ByGameVersion">The number of update-check requests by OS platform.</param>
/// <param name="BySite">The metrics grouped by site.</param>
/// <param name="ByDate">The metrics grouped by UTC date.</param>
internal record MetricsSummary(
@@ -28,6 +29,7 @@ internal record MetricsSummary(
int TotalErrorCacheMisses,
IDictionary<string, long> ByApiVersion,
IDictionary<string, long> ByGameVersion,
IDictionary<string, long> ByPlatform,
IDictionary<ModSiteKey, MetricsModel> BySite,
IDictionary<string, ApiMetricsModel> ByDate
);