Skip to content

Commit

Permalink
Add request statistics tracking functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
jvyden committed Aug 23, 2023
1 parent c305f3c commit 0145d92
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 5 deletions.
3 changes: 2 additions & 1 deletion Refresh.GameServer/Configuration/GameServerConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Refresh.GameServer.Configuration;
[SuppressMessage("ReSharper", "RedundantDefaultMemberInitializer")]
public class GameServerConfig : Config
{
public override int CurrentConfigVersion => 7;
public override int CurrentConfigVersion => 8;
public override int Version { get; set; } = 0;

protected override void Migrate(int oldVer, dynamic oldConfig) {}
Expand All @@ -25,4 +25,5 @@ protected override void Migrate(int oldVer, dynamic oldConfig) {}
public string InstanceDescription { get; set; } = "A server running Refresh!";
public bool MaintenanceMode { get; set; } = false;
public bool RequireGameLoginToRegister { get; set; } = false;
public bool TrackRequestStatistics { get; set; } = false;
}
2 changes: 2 additions & 0 deletions Refresh.GameServer/Database/GameDatabaseContext.Activity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ public DatabaseList<Event> GetRecentActivityForLevel(GameLevel level, int count,
.Where(e => e._StoredDataType == 1 && e.StoredSequentialId == level.LevelId)
.Where(e => e.Timestamp < timestamp && e.Timestamp >= endTimestamp)
.OrderByDescending(e => e.Timestamp), skip, count);

public int GetTotalEventCount() => this._realm.All<Event>().Count();
}
45 changes: 45 additions & 0 deletions Refresh.GameServer/Database/GameDatabaseContext.Statistics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Refresh.GameServer.Types;

namespace Refresh.GameServer.Database;

public partial class GameDatabaseContext // Statistics
{
public RequestStatistics GetRequestStatistics()
{
RequestStatistics? statistics = this._realm.All<RequestStatistics>().FirstOrDefault();
if (statistics != null) return statistics;

statistics = new RequestStatistics();
this._realm.Write(() =>
{
this._realm.Add(statistics);
});

return statistics;
}

public void IncrementApiRequests()
{
RequestStatistics statistics = this.GetRequestStatistics();
this._realm.Write(() => {
statistics.TotalRequests++;
statistics.ApiRequests++;
});
}
public void IncrementLegacyApiRequests()
{
RequestStatistics statistics = this.GetRequestStatistics();
this._realm.Write(() => {
statistics.TotalRequests++;
statistics.LegacyApiRequests++;
});
}
public void IncrementGameRequests()
{
RequestStatistics statistics = this.GetRequestStatistics();
this._realm.Write(() => {
statistics.TotalRequests++;
statistics.GameRequests++;
});
}
}
3 changes: 2 additions & 1 deletion Refresh.GameServer/Database/GameDatabaseProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected GameDatabaseProvider(IDateTimeProvider time)
this._time = time;
}

protected override ulong SchemaVersion => 75;
protected override ulong SchemaVersion => 76;

protected override string Filename => "refreshGameServer.realm";

Expand Down Expand Up @@ -61,6 +61,7 @@ protected GameDatabaseProvider(IDateTimeProvider time)
typeof(GameAnnouncement),
typeof(QueuedRegistration),
typeof(EmailVerificationCode),
typeof(RequestStatistics),
//grief report items
typeof(GameReport),
typeof(InfoBubble),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Refresh.GameServer.Types;

namespace Refresh.GameServer.Endpoints.ApiV3.DataTypes.Response;

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class ApiRequestStatisticsResponse : IApiResponse, IDataConvertableFrom<ApiRequestStatisticsResponse, RequestStatistics>
{
public required long TotalRequests { get; set; }
public required long ApiRequests { get; set; }
public required long LegacyApiRequests { get; set; }
public required long GameRequests { get; set; }

public static ApiRequestStatisticsResponse? FromOld(RequestStatistics? old)
{
if (old == null) return null;

return new ApiRequestStatisticsResponse
{
TotalRequests = old.TotalRequests,
ApiRequests = old.ApiRequests,
LegacyApiRequests = old.LegacyApiRequests,
GameRequests = old.GameRequests,
};
}

public static IEnumerable<ApiRequestStatisticsResponse> FromOldList(IEnumerable<RequestStatistics> oldList) => oldList.Select(FromOld)!;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ public class ApiStatisticsResponse : IApiResponse
public required int TotalLevels { get; set; }
public required int TotalUsers { get; set; }
public required int TotalPhotos { get; set; }
public required int TotalEvents { get; set; }
public required int CurrentRoomCount { get; set; }
public required int CurrentIngamePlayersCount { get; set; }

public required ApiRequestStatisticsResponse RequestStatistics { get; set; }
}
26 changes: 23 additions & 3 deletions Refresh.GameServer/Endpoints/ApiV3/InstanceApiEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,36 @@ public class InstanceApiEndpoints : EndpointGroup
{
[ApiV3Endpoint("statistics"), Authentication(false)]
[DocSummary("Retrieves various statistics about the Refresh instance.")]
public ApiResponse<ApiStatisticsResponse> GetStatistics(RequestContext context, GameDatabaseContext database, MatchService match)
=> new ApiStatisticsResponse
public ApiResponse<ApiStatisticsResponse> GetStatistics(RequestContext context, GameDatabaseContext database, MatchService match, GameServerConfig config)
{
ApiRequestStatisticsResponse requestStatistics;
if (!config.TrackRequestStatistics)
{
requestStatistics = new ApiRequestStatisticsResponse
{
TotalRequests = -1,
ApiRequests = -1,
LegacyApiRequests = -1,
GameRequests = -1,
};
}
else
{
requestStatistics = ApiRequestStatisticsResponse.FromOld(database.GetRequestStatistics())!;
}

return new ApiStatisticsResponse
{
TotalLevels = database.GetTotalLevelCount(),
TotalUsers = database.GetTotalUserCount(),
TotalPhotos = database.GetTotalPhotoCount(),
TotalEvents = database.GetTotalEventCount(),
CurrentRoomCount = match.Rooms.Count(),
CurrentIngamePlayersCount = match.TotalPlayers,
RequestStatistics = requestStatistics,
};

}

[ApiV3Endpoint("instance"), Authentication(false), AllowDuringMaintenance]
[DocSummary("Retrieves various information and metadata about the Refresh instance.")]
public ApiResponse<ApiInstanceResponse> GetInstanceInformation(RequestContext context,
Expand Down
3 changes: 3 additions & 0 deletions Refresh.GameServer/RefreshGameServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ protected virtual void SetupServices()

this._server.AddService<RoleService>();
this._server.AddService<SmtpService>();

if (this._config!.TrackRequestStatistics)
this._server.AddService<RequestStatisticTrackingService>();
}

protected virtual void SetupWorkers()
Expand Down
37 changes: 37 additions & 0 deletions Refresh.GameServer/Services/RequestStatisticTrackingService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Reflection;
using Bunkum.CustomHttpListener.Request;
using Bunkum.HttpServer;
using Bunkum.HttpServer.Database;
using Bunkum.HttpServer.Responses;
using Bunkum.HttpServer.Services;
using NotEnoughLogs;
using Refresh.GameServer.Database;
using Refresh.GameServer.Endpoints;

namespace Refresh.GameServer.Services;

public class RequestStatisticTrackingService : Service
{
internal RequestStatisticTrackingService(LoggerContainer<BunkumContext> logger) : base(logger)
{}

public override Response? OnRequestHandled(ListenerContext context, MethodInfo method, Lazy<IDatabaseContext> database)
{
GameDatabaseContext gameDatabase = (GameDatabaseContext)database.Value;

if (context.Uri.AbsolutePath.StartsWith(GameEndpointAttribute.BaseRoute))
{
gameDatabase.IncrementGameRequests();
}
else if(context.Uri.AbsolutePath.StartsWith(LegacyApiEndpointAttribute.BaseRoute))
{
gameDatabase.IncrementLegacyApiRequests();
}
else
{
gameDatabase.IncrementApiRequests();
}

return null;
}
}
11 changes: 11 additions & 0 deletions Refresh.GameServer/Types/RequestStatistics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Realms;

namespace Refresh.GameServer.Types;

public partial class RequestStatistics : IRealmObject
{
public long TotalRequests { get; set; }
public long ApiRequests { get; set; }
public long LegacyApiRequests { get; set; }
public long GameRequests { get; set; }
}

0 comments on commit 0145d92

Please sign in to comment.