rework metrics

This commit is contained in:
Stanley Dimant
2022-08-26 02:22:19 +02:00
parent 7c1395df77
commit ace31926db
21 changed files with 179 additions and 244 deletions

View File

@@ -55,12 +55,9 @@ namespace MareSynchronosServer.Hubs
}, userEntry.CharacterIdentification).ConfigureAwait(false);
}
await _metricsClient.DecGaugeAsync(new GaugeRequest()
{ GaugeName = MetricsAPI.GaugePairs, Value = ownPairData.Count + otherPairData.Count }).ConfigureAwait(false);
await _metricsClient.DecGaugeAsync(new GaugeRequest()
{ GaugeName = MetricsAPI.GaugePairsPaused, Value = ownPairData.Count(c => c.IsPaused) }).ConfigureAwait(false);
await _metricsClient.DecGaugeAsync(new GaugeRequest()
{ GaugeName = MetricsAPI.GaugeUsersRegistered, Value = 1 }).ConfigureAwait(false);
_mareMetrics.DecGauge(MetricsAPI.GaugePairs, ownPairData.Count + otherPairData.Count);
_mareMetrics.DecGauge(MetricsAPI.GaugePairsPaused, ownPairData.Count(c => c.IsPaused));
_mareMetrics.IncCounter(MetricsAPI.CounterUsersRegisteredDeleted, 1);
_dbContext.RemoveRange(otherPairData);
_dbContext.Remove(userEntry);
@@ -162,17 +159,15 @@ namespace MareSynchronosServer.Hubs
await Clients.Users(otherEntries).SendAsync(Api.OnUserReceiveCharacterData, characterCache, user.CharacterIdentification).ConfigureAwait(false);
await _metricsClient.IncreaseCounterAsync(new IncreaseCounterRequest()
{ CounterName = MetricsAPI.CounterUserPushData, Value = 1 }).ConfigureAwait(false);
await _metricsClient.IncreaseCounterAsync(new IncreaseCounterRequest()
{ CounterName = MetricsAPI.CounterUserPushDataTo, Value = otherEntries.Count }).ConfigureAwait(false);
_mareMetrics.IncCounter(MetricsAPI.CounterUserPushData);
_mareMetrics.IncCounter(MetricsAPI.CounterUserPushDataTo, otherEntries.Count);
}
[Authorize(AuthenticationSchemes = SecretKeyGrpcAuthenticationHandler.AuthScheme)]
[HubMethodName(Api.SendUserPairedClientAddition)]
public async Task SendPairedClientAddition(string uid)
{
if (uid == AuthenticatedUserId) return;
if (uid == AuthenticatedUserId || string.IsNullOrWhiteSpace(uid)) return;
uid = uid.Trim();
var user = await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId).ConfigureAwait(false);
@@ -223,7 +218,7 @@ namespace MareSynchronosServer.Hubs
}
}
await _metricsClient.IncGaugeAsync(new GaugeRequest() {GaugeName = MetricsAPI.GaugePairs, Value = 1}).ConfigureAwait(false);
_mareMetrics.IncGauge(MetricsAPI.GaugePairs);
}
[Authorize(AuthenticationSchemes = SecretKeyGrpcAuthenticationHandler.AuthScheme)]
@@ -263,11 +258,11 @@ namespace MareSynchronosServer.Hubs
if (isPaused)
{
await _metricsClient.IncGaugeAsync(new GaugeRequest() { GaugeName = MetricsAPI.GaugePairsPaused, Value = 1 }).ConfigureAwait(false);
_mareMetrics.IncGauge(MetricsAPI.GaugePairsPaused);
}
else
{
await _metricsClient.DecGaugeAsync(new GaugeRequest() { GaugeName = MetricsAPI.GaugePairsPaused, Value = 1 }).ConfigureAwait(false);
_mareMetrics.DecGauge(MetricsAPI.GaugePairsPaused);
}
}
@@ -311,7 +306,7 @@ namespace MareSynchronosServer.Hubs
}
}
await _metricsClient.DecGaugeAsync(new GaugeRequest() { GaugeName = MetricsAPI.GaugePairs, Value = 1 }).ConfigureAwait(false);
_mareMetrics.DecGauge(MetricsAPI.GaugePairs);
}
private ClientPair OppositeEntry(string otherUID) =>

View File

@@ -19,7 +19,7 @@ namespace MareSynchronosServer.Hubs
{
public partial class MareHub : Hub
{
private readonly MetricsService.MetricsServiceClient _metricsClient;
private readonly MareMetrics _mareMetrics;
private readonly AuthService.AuthServiceClient _authServiceClient;
private readonly FileService.FileServiceClient _fileServiceClient;
private readonly SystemInfoService _systemInfoService;
@@ -27,10 +27,10 @@ namespace MareSynchronosServer.Hubs
private readonly ILogger<MareHub> _logger;
private readonly MareDbContext _dbContext;
private readonly Uri cdnFullUri;
public MareHub(MetricsService.MetricsServiceClient metricsClient, AuthService.AuthServiceClient authServiceClient, FileService.FileServiceClient fileServiceClient,
public MareHub(MareMetrics mareMetrics, AuthService.AuthServiceClient authServiceClient, FileService.FileServiceClient fileServiceClient,
MareDbContext mareDbContext, ILogger<MareHub> logger, SystemInfoService systemInfoService, IConfiguration configuration, IHttpContextAccessor contextAccessor)
{
_metricsClient = metricsClient;
_mareMetrics = mareMetrics;
_authServiceClient = authServiceClient;
_fileServiceClient = fileServiceClient;
_systemInfoService = systemInfoService;
@@ -44,7 +44,7 @@ namespace MareSynchronosServer.Hubs
[Authorize(AuthenticationSchemes = SecretKeyGrpcAuthenticationHandler.AuthScheme)]
public async Task<ConnectionDto> Heartbeat(string characterIdentification)
{
await _metricsClient.IncreaseCounterAsync(new() { CounterName = MetricsAPI.CounterInitializedConnections, Value = 1 }).ConfigureAwait(false);
_mareMetrics.IncCounter(MetricsAPI.CounterInitializedConnections);
var userId = Context.User!.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
@@ -66,7 +66,7 @@ namespace MareSynchronosServer.Hubs
}
else if (string.IsNullOrEmpty(user.CharacterIdentification))
{
await _metricsClient.IncGaugeAsync(new GaugeRequest() { GaugeName = MetricsAPI.GaugeAuthorizedConnections, Value = 1 }).ConfigureAwait(false);
_mareMetrics.IncGauge(MetricsAPI.GaugeAuthorizedConnections);
}
user.LastLoggedIn = DateTime.UtcNow;
@@ -91,18 +91,18 @@ namespace MareSynchronosServer.Hubs
public override async Task OnConnectedAsync()
{
_logger.LogInformation("Connection from {ip}", contextAccessor.GetIpAddress());
await _metricsClient.IncGaugeAsync(new GaugeRequest() { GaugeName = MetricsAPI.GaugeConnections, Value = 1 }).ConfigureAwait(false);
_mareMetrics.IncGauge(MetricsAPI.GaugeConnections);
await base.OnConnectedAsync().ConfigureAwait(false);
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await _metricsClient.DecGaugeAsync(new GaugeRequest() { GaugeName = MetricsAPI.GaugeConnections, Value = 1 }).ConfigureAwait(false);
_mareMetrics.DecGauge(MetricsAPI.GaugeConnections);
var user = await _dbContext.Users.SingleOrDefaultAsync(u => u.UID == AuthenticatedUserId).ConfigureAwait(false);
if (user != null && !string.IsNullOrEmpty(user.CharacterIdentification))
{
await _metricsClient.DecGaugeAsync(new GaugeRequest() { GaugeName = MetricsAPI.GaugeAuthorizedConnections, Value = 1 }).ConfigureAwait(false);
_mareMetrics.DecGauge(MetricsAPI.GaugeAuthorizedConnections);
_logger.LogInformation("Disconnect from {id}", AuthenticatedUserId);

View File

@@ -29,6 +29,7 @@
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="6.0.0" />
<PackageReference Include="prometheus-net.AspNetCore" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -6,8 +6,8 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using MareSynchronosShared.Data;
using MareSynchronosShared.Metrics;
namespace MareSynchronosServer
{
@@ -36,6 +36,11 @@ namespace MareSynchronosServer
context.RemoveRange(unfinishedRegistrations);
context.RemoveRange(looseFiles);
context.SaveChanges();
var metrics = services.GetRequiredService<MareMetrics>();
metrics.SetGaugeTo(MetricsAPI.GaugePairs, context.ClientPairs.Count());
metrics.SetGaugeTo(MetricsAPI.GaugePairsPaused, context.ClientPairs.Count(p => p.IsPaused));
}
if (args.Length == 0 || args[0] != "dry")

View File

@@ -16,6 +16,9 @@ using MareSynchronosShared.Authentication;
using MareSynchronosShared.Data;
using MareSynchronosShared.Protos;
using Grpc.Net.Client.Configuration;
using Prometheus;
using MareSynchronosShared.Metrics;
using System.Collections.Generic;
namespace MareSynchronosServer
{
@@ -60,6 +63,22 @@ namespace MareSynchronosServer
}
};
services.AddSingleton(new MareMetrics(new List<string>
{
MetricsAPI.CounterInitializedConnections,
MetricsAPI.CounterUserPushData,
MetricsAPI.CounterUserPushDataTo,
MetricsAPI.CounterUsersRegisteredDeleted,
}, new List<string>
{
MetricsAPI.GaugeAuthorizedConnections,
MetricsAPI.GaugeConnections,
MetricsAPI.GaugePairs,
MetricsAPI.GaugePairsPaused,
MetricsAPI.GaugeAvailableIOWorkerThreads,
MetricsAPI.GaugeAvailableWorkerThreads
}));
services.AddGrpcClient<AuthService.AuthServiceClient>(c =>
{
c.Address = new Uri(mareConfig.GetValue<string>("ServiceAddress"));
@@ -67,13 +86,6 @@ namespace MareSynchronosServer
{
c.ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } };
});
services.AddGrpcClient<MetricsService.MetricsServiceClient>(c =>
{
c.Address = new Uri(mareConfig.GetValue<string>("ServiceAddress"));
}).ConfigureChannel(c =>
{
c.ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } };
});
services.AddGrpcClient<FileService.FileServiceClient>(c =>
{
c.Address = new Uri(mareConfig.GetValue<string>("StaticFileServiceAddress"));
@@ -134,6 +146,9 @@ namespace MareSynchronosServer
app.UseWebSockets();
var metricServer = new KestrelMetricServer(4981);
metricServer.Start();
app.UseAuthentication();
app.UseAuthorization();

View File

@@ -16,16 +16,16 @@ namespace MareSynchronosServer;
public class SystemInfoService : IHostedService, IDisposable
{
private readonly MetricsService.MetricsServiceClient metricsClient;
private readonly MareMetrics _mareMetrics;
private readonly IServiceProvider _services;
private readonly ILogger<SystemInfoService> _logger;
private readonly IHubContext<MareHub> _hubContext;
private Timer _timer;
public SystemInfoDto SystemInfoDto { get; private set; } = new();
public SystemInfoService(MetricsService.MetricsServiceClient metricsClient, IServiceProvider services, ILogger<SystemInfoService> logger, IHubContext<MareHub> hubContext)
public SystemInfoService(MareMetrics mareMetrics, IServiceProvider services, ILogger<SystemInfoService> logger, IHubContext<MareHub> hubContext)
{
this.metricsClient = metricsClient;
_mareMetrics = mareMetrics;
_services = services;
_logger = logger;
_hubContext = hubContext;
@@ -48,10 +48,8 @@ public class SystemInfoService : IHostedService, IDisposable
using var scope = _services.CreateScope();
using var db = scope.ServiceProvider.GetService<MareDbContext>()!;
metricsClient.SetGauge(new SetGaugeRequest()
{ GaugeName = MetricsAPI.GaugeAvailableWorkerThreads, Value = workerThreads });
metricsClient.SetGauge(new SetGaugeRequest()
{ GaugeName = MetricsAPI.GaugeAvailableIOWorkerThreads, Value = ioThreads });
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeAvailableWorkerThreads, workerThreads);
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeAvailableIOWorkerThreads, ioThreads);
var users = db.Users.Count(c => c.CharacterIdentification != null);

View File

@@ -5,7 +5,6 @@ using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MareSynchronosServices.Metrics;
using MareSynchronosShared.Data;
using MareSynchronosShared.Metrics;
using MareSynchronosShared.Protos;

View File

@@ -1,5 +1,4 @@
using MareSynchronosServices.Authentication;
using MareSynchronosServices.Metrics;
using MareSynchronosShared.Data;
using MareSynchronosShared.Metrics;
using MareSynchronosShared.Models;
@@ -140,9 +139,9 @@ namespace MareSynchronosServices
.Where(u => u.OtherUser.UID == user.UID).ToList();
metrics.DecGaugeBy(MetricsAPI.GaugePairs, ownPairData.Count + otherPairData.Count);
metrics.DecGaugeBy(MetricsAPI.GaugePairsPaused, ownPairData.Count + ownPairData.Count(c => c.IsPaused));
metrics.DecGaugeBy(MetricsAPI.GaugeUsersRegistered, ownPairData.Count + 1);
metrics.DecGauge(MetricsAPI.GaugePairs, ownPairData.Count + otherPairData.Count);
metrics.DecGauge(MetricsAPI.GaugePairsPaused, ownPairData.Count + ownPairData.Count(c => c.IsPaused));
metrics.DecGauge(MetricsAPI.GaugeUsersRegistered, ownPairData.Count + 1);
dbContext.RemoveRange(otherPairData);
dbContext.Remove(auth);

View File

@@ -9,9 +9,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Discord;
using Discord.Rest;
using Discord.WebSocket;
using MareSynchronosServices.Metrics;
using MareSynchronosShared.Data;
using MareSynchronosShared.Metrics;
using MareSynchronosShared.Models;
@@ -262,7 +260,7 @@ public class DiscordBot : IHostedService
logger.LogInformation("User registered: {userUID}", user.UID);
metrics.IncGaugeBy(MetricsAPI.GaugeUsersRegistered, 1);
metrics.IncGauge(MetricsAPI.GaugeUsersRegistered, 1);
lodestoneAuth.StartedAt = null;
lodestoneAuth.User = user;

View File

@@ -1,85 +0,0 @@
using MareSynchronosShared.Data;
using MareSynchronosShared.Metrics;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Prometheus;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MareSynchronosServices.Metrics;
public class MareMetrics
{
public MareMetrics(IServiceProvider services)
{
using var scope = services.CreateScope();
using var dbContext = scope.ServiceProvider.GetService<MareDbContext>();
gauges[MetricsAPI.GaugeUsersRegistered].IncTo(dbContext.Users.Count());
gauges[MetricsAPI.GaugePairs].IncTo(dbContext.ClientPairs.Count());
gauges[MetricsAPI.GaugePairsPaused].IncTo(dbContext.ClientPairs.Count(p => p.IsPaused));
gauges[MetricsAPI.GaugeFilesTotal].IncTo(dbContext.Files.Count());
}
private readonly Dictionary<string, Counter> counters = new()
{
{ MetricsAPI.CounterInitializedConnections, Prometheus.Metrics.CreateCounter(MetricsAPI.CounterInitializedConnections, "Initialized Connections") },
{ MetricsAPI.CounterUserPushData, Prometheus.Metrics.CreateCounter(MetricsAPI.CounterUserPushData, "Users pushing data") },
{ MetricsAPI.CounterUserPushDataTo, Prometheus.Metrics.CreateCounter(MetricsAPI.CounterUserPushDataTo, "Users Receiving Data") },
{ MetricsAPI.CounterAuthenticationRequests, Prometheus.Metrics.CreateCounter(MetricsAPI.CounterAuthenticationRequests, "Authentication Requests") },
{ MetricsAPI.CounterAuthenticationCacheHits, Prometheus.Metrics.CreateCounter(MetricsAPI.CounterAuthenticationCacheHits, "Authentication Requests Cache Hits") },
{ MetricsAPI.CounterAuthenticationFailures, Prometheus.Metrics.CreateCounter(MetricsAPI.CounterAuthenticationFailures, "Authentication Requests Failed") },
{ MetricsAPI.CounterAuthenticationSuccesses, Prometheus.Metrics.CreateCounter(MetricsAPI.CounterAuthenticationSuccesses, "Authentication Requests Success") },
};
private readonly Dictionary<string, Gauge> gauges = new()
{
{ MetricsAPI.GaugeConnections, Prometheus.Metrics.CreateGauge(MetricsAPI.GaugeConnections, "Unauthorized Connections") },
{ MetricsAPI.GaugeAuthorizedConnections, Prometheus.Metrics.CreateGauge(MetricsAPI.GaugeAuthorizedConnections, "Authorized Connections") },
{ MetricsAPI.GaugeAvailableIOWorkerThreads, Prometheus.Metrics.CreateGauge(MetricsAPI.GaugeAvailableIOWorkerThreads, "Available Threadpool IO Workers") },
{ MetricsAPI.GaugeAvailableWorkerThreads, Prometheus.Metrics.CreateGauge(MetricsAPI.GaugeAvailableWorkerThreads, "Aavailable Threadpool Workers") },
{ MetricsAPI.GaugeUsersRegistered, Prometheus.Metrics.CreateGauge(MetricsAPI.GaugeUsersRegistered, "Total Registrations") },
{ MetricsAPI.GaugePairs, Prometheus.Metrics.CreateGauge(MetricsAPI.GaugePairs, "Total Pairs") },
{ MetricsAPI.GaugePairsPaused, Prometheus.Metrics.CreateGauge(MetricsAPI.GaugePairsPaused, "Total Paused Pairs") },
{ MetricsAPI.GaugeFilesTotal, Prometheus.Metrics.CreateGauge(MetricsAPI.GaugeFilesTotal, "Total uploaded files") },
{ MetricsAPI.GaugeFilesTotalSize, Prometheus.Metrics.CreateGauge(MetricsAPI.GaugeFilesTotalSize, "Total uploaded files (bytes)") },
};
public void SetGaugeTo(string gaugeName, double value)
{
if (gauges.ContainsKey(gaugeName))
{
gauges[gaugeName].IncTo(value);
}
}
public void IncGaugeBy(string gaugeName, double value)
{
if (gauges.ContainsKey(gaugeName))
{
gauges[gaugeName].Inc(value);
}
}
public void DecGaugeBy(string gaugeName, double value)
{
if (gauges.ContainsKey(gaugeName))
{
gauges[gaugeName].Dec(value);
}
}
public void IncCounter(string counterName)
{
IncCounterBy(counterName, 1);
}
public void IncCounterBy(string counterName, double value)
{
if (counters.ContainsKey(counterName))
{
counters[counterName].Inc(value);
}
}
}

View File

@@ -1,7 +1,11 @@
using MareSynchronosServices;
using MareSynchronosShared.Data;
using MareSynchronosShared.Metrics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Linq;
public class Program
{
@@ -10,6 +14,15 @@ public class Program
var hostBuilder = CreateHostBuilder(args);
var host = hostBuilder.Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
using var dbContext = services.GetRequiredService<MareDbContext>();
var metrics = services.GetRequiredService<MareMetrics>();
metrics.SetGaugeTo(MetricsAPI.GaugeUsersRegistered, dbContext.Users.Count());
}
host.Run();
}

View File

@@ -1,40 +0,0 @@
using Grpc.Core;
using MareSynchronosServices.Metrics;
using MareSynchronosShared.Protos;
using System.Threading.Tasks;
namespace MareSynchronosServices.Services;
public class MetricsService : MareSynchronosShared.Protos.MetricsService.MetricsServiceBase
{
private readonly MareMetrics metrics;
public MetricsService(MareMetrics metrics)
{
this.metrics = metrics;
}
public override Task<Empty> IncreaseCounter(IncreaseCounterRequest request, ServerCallContext context)
{
metrics.IncCounterBy(request.CounterName, request.Value);
return Task.FromResult(new Empty());
}
public override Task<Empty> SetGauge(SetGaugeRequest request, ServerCallContext context)
{
metrics.SetGaugeTo(request.GaugeName, request.Value);
return Task.FromResult(new Empty());
}
public override Task<Empty> DecGauge(GaugeRequest request, ServerCallContext context)
{
metrics.DecGaugeBy(request.GaugeName, request.Value);
return Task.FromResult(new Empty());
}
public override Task<Empty> IncGauge(GaugeRequest request, ServerCallContext context)
{
metrics.IncGaugeBy(request.GaugeName, request.Value);
return Task.FromResult(new Empty());
}
}

View File

@@ -1,16 +1,15 @@
using MareSynchronosServer;
using MareSynchronosServices.Authentication;
using MareSynchronosServices.Discord;
using MareSynchronosServices.Metrics;
using MareSynchronosServices.Services;
using MareSynchronosShared.Authentication;
using MareSynchronosShared.Data;
using MareSynchronosShared.Metrics;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Prometheus;
using System.Collections.Generic;
namespace MareSynchronosServices;
@@ -34,7 +33,16 @@ public class Startup
options.EnableThreadSafetyChecks(false);
}, Configuration.GetValue("DbContextPoolSize", 1024));
services.AddSingleton<MareMetrics>();
services.AddSingleton(new MareMetrics(new List<string> {
MetricsAPI.CounterAuthenticationRequests,
MetricsAPI.CounterAuthenticationFailures,
MetricsAPI.CounterAuthenticationCacheHits,
MetricsAPI.CounterAuthenticationSuccesses
}, new List<string>
{
MetricsAPI.GaugeUsersRegistered
}));
services.AddSingleton<SecretKeyAuthenticationHandler>();
services.AddSingleton<CleanupService>();
services.AddTransient(_ => Configuration);
@@ -47,13 +55,12 @@ public class Startup
{
app.UseRouting();
var metricServer = new KestrelMetricServer(4980);
var metricServer = new KestrelMetricServer(4982);
metricServer.Start();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<AuthenticationService>();
endpoints.MapGrpcService<MetricsService>();
});
}
}

View File

@@ -0,0 +1,57 @@
using MareSynchronosShared.Data;
using Microsoft.Extensions.DependencyInjection;
using Prometheus;
namespace MareSynchronosShared.Metrics;
public class MareMetrics
{
public MareMetrics(List<string> countersToServe, List<string> gaugesToServe)
{
foreach(var counter in countersToServe)
{
counters.Add(counter, Prometheus.Metrics.CreateCounter(counter, counter));
}
foreach(var gauge in gaugesToServe)
{
gauges.Add(gauge, Prometheus.Metrics.CreateGauge(gauge, gauge));
}
}
private readonly Dictionary<string, Counter> counters = new(StringComparer.Ordinal);
private readonly Dictionary<string, Gauge> gauges = new(StringComparer.Ordinal);
public void SetGaugeTo(string gaugeName, double value)
{
if (gauges.ContainsKey(gaugeName))
{
gauges[gaugeName].IncTo(value);
}
}
public void IncGauge(string gaugeName, double value = 1.0)
{
if (gauges.ContainsKey(gaugeName))
{
gauges[gaugeName].Inc(value);
}
}
public void DecGauge(string gaugeName, double value = 1.0)
{
if (gauges.ContainsKey(gaugeName))
{
gauges[gaugeName].Dec(value);
}
}
public void IncCounter(string counterName, double value = 1.0)
{
if (counters.ContainsKey(counterName))
{
counters[counterName].Inc(value);
}
}
}

View File

@@ -8,6 +8,7 @@ public class MetricsAPI
public const string GaugeAvailableWorkerThreads = "mare_available_threadpool";
public const string GaugeAvailableIOWorkerThreads = "mare_available_threadpool_io";
public const string GaugeUsersRegistered = "mare_users_registered";
public const string CounterUsersRegisteredDeleted = "mare_users_registered_deleted";
public const string GaugePairs = "mare_pairs";
public const string GaugePairsPaused = "mare_pairs_paused";
public const string GaugeFilesTotal = "mare_files";

View File

@@ -10,13 +10,6 @@ service AuthService {
rpc ClearUnauthorized (Empty) returns (Empty);
}
service MetricsService {
rpc IncreaseCounter (IncreaseCounterRequest) returns (Empty);
rpc SetGauge (SetGaugeRequest) returns (Empty);
rpc DecGauge (GaugeRequest) returns (Empty);
rpc IncGauge (GaugeRequest) returns (Empty);
}
service FileService {
rpc UploadFile (UploadFileRequest) returns (Empty);
rpc GetFileSizes (FileSizeRequest) returns (FileSizeResponse);
@@ -43,21 +36,6 @@ message FileSizeResponse {
map<string, int64> hashToFileSize = 1;
}
message GaugeRequest {
string gaugeName = 1;
double value = 2;
}
message SetGaugeRequest {
string gaugeName = 1;
double value = 2;
}
message IncreaseCounterRequest {
string counterName = 1;
double value = 2;
}
message RemoveAuthRequest {
string uid = 1;
}

View File

@@ -16,13 +16,13 @@ namespace MareSynchronosStaticFilesServer;
public class CleanupService : IHostedService, IDisposable
{
private readonly MetricsService.MetricsServiceClient _metrics;
private readonly MareMetrics _metrics;
private readonly ILogger<CleanupService> _logger;
private readonly IServiceProvider _services;
private readonly IConfiguration _configuration;
private Timer? _timer;
public CleanupService(MetricsService.MetricsServiceClient metrics, ILogger<CleanupService> logger, IServiceProvider services, IConfiguration configuration)
public CleanupService(MareMetrics metrics, ILogger<CleanupService> logger, IServiceProvider services, IConfiguration configuration)
{
_metrics = metrics;
_logger = logger;
@@ -30,31 +30,22 @@ public class CleanupService : IHostedService, IDisposable
_configuration = configuration.GetRequiredSection("MareSynchronos");
}
public async Task StartAsync(CancellationToken cancellationToken)
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Cleanup Service started");
_ = Task.Run(async () =>
{
_logger.LogInformation("Calculating initial files");
DirectoryInfo dir = new DirectoryInfo(_configuration["CacheDirectory"]);
var allFiles = dir.GetFiles();
await _metrics.SetGaugeAsync(new SetGaugeRequest()
{
GaugeName = MetricsAPI.GaugeFilesTotalSize,
Value = allFiles.Sum(f => f.Length)
});
await _metrics.SetGaugeAsync(new SetGaugeRequest()
{
GaugeName = MetricsAPI.GaugeFilesTotal,
Value = allFiles.Length
});
_metrics.SetGaugeTo(MetricsAPI.GaugeFilesTotalSize, allFiles.Sum(f => f.Length));
_metrics.SetGaugeTo(MetricsAPI.GaugeFilesTotal, allFiles.Length);
_logger.LogInformation("Initial file calculation finished, starting periodic cleanup task");
_timer = new Timer(CleanUp, null, TimeSpan.FromSeconds(15), TimeSpan.FromMinutes(10));
});
return Task.CompletedTask;
}
private void CleanUp(object? state)
@@ -86,8 +77,8 @@ public class CleanupService : IHostedService, IDisposable
}
else if (fi.LastAccessTime < prevTime)
{
_metrics.DecGauge(new() { GaugeName = MetricsAPI.GaugeFilesTotalSize, Value = fi.Length });
_metrics.DecGauge(new() { GaugeName = MetricsAPI.GaugeFilesTotal, Value = 1 });
_metrics.DecGauge(MetricsAPI.GaugeFilesTotalSize, fi.Length);
_metrics.DecGauge(MetricsAPI.GaugeFilesTotal);
_logger.LogInformation("File outdated: {fileName}", fileName);
dbContext.Files.Remove(file);
fi.Delete();
@@ -101,8 +92,8 @@ public class CleanupService : IHostedService, IDisposable
{
if (!allFilesHashes.Contains(file.Name.ToUpperInvariant()))
{
_metrics.DecGauge(new() { GaugeName = MetricsAPI.GaugeFilesTotalSize, Value = file.Length });
_metrics.DecGauge(new() { GaugeName = MetricsAPI.GaugeFilesTotal, Value = 1 });
_metrics.DecGauge(MetricsAPI.GaugeFilesTotalSize, file.Length);
_metrics.DecGauge(MetricsAPI.GaugeFilesTotal);
file.Delete();
_logger.LogInformation("File not in DB, deleting: {fileName}", file.FullName);
}
@@ -131,8 +122,8 @@ public class CleanupService : IHostedService, IDisposable
removedHashes.Add(oldestFile.Name.ToLower());
allLocalFiles.Remove(oldestFile);
totalCacheSizeInBytes -= oldestFile.Length;
_metrics.DecGauge(new() { GaugeName = MetricsAPI.GaugeFilesTotalSize, Value = oldestFile.Length });
_metrics.DecGauge(new() { GaugeName = MetricsAPI.GaugeFilesTotal, Value = 1 });
_metrics.DecGauge(MetricsAPI.GaugeFilesTotalSize, oldestFile.Length);
_metrics.DecGauge(MetricsAPI.GaugeFilesTotal);
oldestFile.Delete();
}

View File

@@ -17,9 +17,9 @@ public class FileService : MareSynchronosShared.Protos.FileService.FileServiceBa
private readonly string _basePath;
private readonly MareDbContext _mareDbContext;
private readonly ILogger<FileService> _logger;
private readonly MetricsService.MetricsServiceClient _metricsClient;
private readonly MareMetrics _metricsClient;
public FileService(MareDbContext mareDbContext, IConfiguration configuration, ILogger<FileService> logger, MetricsService.MetricsServiceClient metricsClient)
public FileService(MareDbContext mareDbContext, IConfiguration configuration, ILogger<FileService> logger, MareMetrics metricsClient)
{
_basePath = configuration.GetRequiredSection("MareSynchronos")["CacheDirectory"];
_mareDbContext = mareDbContext;
@@ -37,10 +37,8 @@ public class FileService : MareSynchronosShared.Protos.FileService.FileServiceBa
await File.WriteAllBytesAsync(filePath, byteData);
file.Uploaded = true;
await _metricsClient.IncGaugeAsync(new GaugeRequest()
{ GaugeName = MetricsAPI.GaugeFilesTotalSize, Value = byteData.Length }).ConfigureAwait(false);
await _metricsClient.IncGaugeAsync(new GaugeRequest()
{ GaugeName = MetricsAPI.GaugeFilesTotal, Value = 1 }).ConfigureAwait(false);
_metricsClient.IncGauge(MetricsAPI.GaugeFilesTotal, 1);
_metricsClient.IncGauge(MetricsAPI.GaugeFilesTotalSize, byteData.Length);
await _mareDbContext.SaveChangesAsync().ConfigureAwait(false);
_logger.LogInformation("User {user} uploaded file {hash}", request.Uploader, request.Hash);
@@ -62,10 +60,8 @@ public class FileService : MareSynchronosShared.Protos.FileService.FileServiceBa
{
_mareDbContext.Files.Remove(file);
await _metricsClient.DecGaugeAsync(new GaugeRequest()
{ GaugeName = MetricsAPI.GaugeFilesTotalSize, Value = fi.Length }).ConfigureAwait(false);
await _metricsClient.DecGaugeAsync(new GaugeRequest()
{ GaugeName = MetricsAPI.GaugeFilesTotal, Value = 1 }).ConfigureAwait(false);
_metricsClient.DecGauge(MetricsAPI.GaugeFilesTotal, 1);
_metricsClient.DecGauge(MetricsAPI.GaugeFilesTotalSize, fi.Length);
}
}
catch (Exception ex)

View File

@@ -21,6 +21,7 @@
<PackageReference Include="Grpc.Net.Client" Version="2.47.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="6.0.0" />
<PackageReference Include="prometheus-net.AspNetCore" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,6 +1,7 @@
using Grpc.Net.Client.Configuration;
using MareSynchronosShared.Authentication;
using MareSynchronosShared.Data;
using MareSynchronosShared.Metrics;
using MareSynchronosShared.Protos;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
@@ -10,7 +11,9 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Prometheus;
using System;
using System.Collections.Generic;
namespace MareSynchronosStaticFilesServer;
@@ -44,6 +47,13 @@ public class Startup
}
};
services.AddSingleton(new MareMetrics(new List<string> {
}, new List<string>
{
MetricsAPI.GaugeFilesTotalSize,
MetricsAPI.GaugeFilesTotal
}));
services.AddGrpcClient<AuthService.AuthServiceClient>(c =>
{
c.Address = new Uri(mareSettings.GetValue<string>("ServiceAddress"));
@@ -51,13 +61,6 @@ public class Startup
{
c.ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } };
});
services.AddGrpcClient<MetricsService.MetricsServiceClient>(c =>
{
c.Address = new Uri(mareSettings.GetValue<string>("ServiceAddress"));
}).ConfigureChannel(c =>
{
c.ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } };
});
services.AddDbContextPool<MareDbContext>(options =>
{
@@ -89,6 +92,9 @@ public class Startup
app.UseRouting();
var metricServer = new KestrelMetricServer(4982);
metricServer.Start();
app.UseAuthentication();
app.UseAuthorization();

View File

@@ -22,7 +22,7 @@
"MareSynchronos": {
"CacheSizeHardLimitInGiB": -1,
"UnusedFileRetentionPeriodInDays": 7,
"CacheDirectory": "G:\\ServerTest", // do not delete this key and set it to the path where the files will be stored
"CacheDirectory": "G:\\ServerTest",
"ServiceAddress": "http://localhost:5002"
},
"AllowedHosts": "*"