Skip to content

Commit

Permalink
Add basic metrics with Prometheus export
Browse files Browse the repository at this point in the history
  • Loading branch information
Simyon264 committed May 5, 2024
1 parent a0eb21a commit 7eac821
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 3 deletions.
5 changes: 4 additions & 1 deletion Server/Api/ReplayController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.Extensions.Caching.Memory;
using Serilog;
using Server.Helpers;
using Server.Metrics;
using Shared.Models;

namespace Server.Api;
Expand All @@ -18,11 +19,13 @@ public class ReplayController : ControllerBase
{
private readonly ReplayDbContext _context;
private readonly IMemoryCache _cache;
private readonly ReplayMetrics _metrics;

public ReplayController(ReplayDbContext context, IMemoryCache cache)
public ReplayController(ReplayDbContext context, IMemoryCache cache, ReplayMetrics metrics)
{
_context = context;
_cache = cache;
_metrics = metrics;
}

[HttpPost]
Expand Down
32 changes: 32 additions & 0 deletions Server/Metrics/ReplayMetrics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Diagnostics.Metrics;

namespace Server.Metrics;

public class ReplayMetrics
{
/// <summary>
/// Records the number of replays that have been parsed.
/// </summary>
private readonly Counter<int> _replayParsedCounter;
/// <summary>
/// Records the number of replays that have failed to parse.
/// </summary>
private readonly Counter<int> _replayParsedErrorCounter;

public ReplayMetrics(IMeterFactory meterFactory)
{
var meter = meterFactory.Create("ReplayBrowser");
_replayParsedCounter = meter.CreateCounter<int>("replay_browser.replay.parsed", null, "The number of replays that have been parsed.");
_replayParsedErrorCounter = meter.CreateCounter<int>("replay_browser.replay.error", null, "The number of replays that have failed to parse.");
}

public void ReplayParsed(string url)
{
_replayParsedCounter.Add(1);
}

public void ReplayError(string url)
{
_replayParsedErrorCounter.Add(1, new KeyValuePair<string, object?>("replay_browser.replay.url", url));
}
}
76 changes: 76 additions & 0 deletions Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.EntityFrameworkCore;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
using Serilog;
using Serilog.AspNetCore;
using Server;
using Server.Api;
using Server.Metrics;
using Server.ReplayParser;

Log.Logger = new LoggerConfiguration()
Expand Down Expand Up @@ -47,7 +50,10 @@
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"));
});

builder.Services.AddSingleton<ReplayMetrics>();

ReplayParser.Context = builder.Services.BuildServiceProvider().GetService<ReplayParserDbContext>(); // GOD THIS IS STUPID

Check warning on line 55 in Server/Program.cs

View workflow job for this annotation

GitHub Actions / deploy

Possible null reference assignment.
ReplayParser.Metrics = builder.Services.BuildServiceProvider().GetService<ReplayMetrics>();

Check warning on line 56 in Server/Program.cs

View workflow job for this annotation

GitHub Actions / deploy

Possible null reference assignment.

builder.Services.AddCors(options =>
{
Expand All @@ -68,6 +74,75 @@
builder.Services.AddMemoryCache();

builder.Services.AddMvc();

builder.Services.AddOpenTelemetry().WithMetrics(providerBuilder =>
{
providerBuilder.AddPrometheusExporter();


providerBuilder.AddMeter("Microsoft.AspNetCore.Hosting",
"Microsoft.AspNetCore.Server.Kestrel");

providerBuilder.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation()
.AddProcessInstrumentation();

providerBuilder.AddMeter(
"Microsoft.Extensions.Diagnostics.ResourceMonitoring",
"Microsoft.AspNetCore.Routing",
"Microsoft.AspNetCore.Diagnostics",
"System.Net.Http",
"ReplayBrowser");

providerBuilder.AddView("http.server.request.duration",
new ExplicitBucketHistogramConfiguration
{
Boundaries = new double[]
{
0, 0.005, 0.01, 0.025, 0.05,
0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10
}
});

providerBuilder.AddView("http.server.request.size",
new ExplicitBucketHistogramConfiguration
{
Boundaries = new double[]
{
0, 100, 1024, 1024 * 10, 1024 * 100, 1024 * 1024, 1024 * 1024 * 10, 1024 * 1024 * 100
}
});

providerBuilder.AddView("http.server.response.size",
new ExplicitBucketHistogramConfiguration
{
Boundaries = new double[]
{
0, 100, 1024, 1024 * 10, 1024 * 100, 1024 * 1024, 1024 * 1024 * 10, 1024 * 1024 * 100
}
});

providerBuilder.AddView("http.server.response.duration",
new ExplicitBucketHistogramConfiguration
{
Boundaries = new double[]
{
0, 0.005, 0.01, 0.025, 0.05,
0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10
}
});

providerBuilder.AddView("http.server.response.status",
new ExplicitBucketHistogramConfiguration
{
Boundaries = new double[]
{
0, 100, 200, 300, 400, 500
}
});
});

var app = builder.Build();

var webSocketOptions = new WebSocketOptions()
Expand Down Expand Up @@ -112,6 +187,7 @@
token.Cancel();
}
});
app.MapPrometheusScrapingEndpoint();

app.Run();
}
Expand Down
8 changes: 6 additions & 2 deletions Server/ReplayParser/ReplayParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.EntityFrameworkCore;
using Serilog;
using Server.Api;
using Server.Metrics;
using Server.ReplayLoading;
using Shared;
using Shared.Models;
Expand All @@ -13,7 +14,8 @@ namespace Server.ReplayParser;
public static class ReplayParser
{
public static ReplayDbContext Context { get; set; }

Check warning on line 16 in Server/ReplayParser/ReplayParser.cs

View workflow job for this annotation

GitHub Actions / deploy

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

public static ReplayMetrics Metrics { get; set; }

public static List<string> Queue = new();
/// <summary>
/// Since the Replay Meta file was added just yesterday, we want to cut off all replays that were uploaded before that.
Expand Down Expand Up @@ -58,7 +60,7 @@ public static async Task ConsumeQueue(CancellationToken token)

// Since replays are like 200mb long, we want to parrallelize this.
var tasks = new List<Task>();
for (var i = 0; i < 10; i++)
for (var i = 0; i < 1; i++)
{
if (Queue.Count == 0)
{
Expand Down Expand Up @@ -110,10 +112,12 @@ public static async Task ConsumeQueue(CancellationToken token)
await AddReplayToDb(parsedReplay);
await AddParsedReplayToDb(replay);
Log.Information("Parsed " + replay);
Metrics.ReplayParsed(replay);
}
catch (Exception e)
{
Log.Error(e, "Error while parsing " + replay);
Metrics.ReplayError(replay);
}
}, tokenSource.Token));
}
Expand Down
9 changes: 9 additions & 0 deletions Server/Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.Design" Version="1.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.2" />
<PackageReference Include="OpenTelemetry" Version="1.8.1" />
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.7.0-rc.1" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.8.1" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNet" Version="1.8.0-beta.2" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.8.1" />
<PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.11" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.8.1" />
<PackageReference Include="OpenTelemetry.Instrumentation.Process" Version="0.5.0-beta.5" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.8.0" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
Expand Down

0 comments on commit 7eac821

Please sign in to comment.