CacheLog(record);
}
- private void CacheLog(QueuedLog log)
- {
- CacheLog(log.Log);
- }
-
private void CacheLog(SharedAdminLog log)
{
// TODO ADMIN LOGS remove redundant data and don't do a dictionary lookup per log
using System.Text.Json;
using System.Text.Json.Serialization;
using Content.Server.Administration.Logs.Converters;
+using Content.Server.Database;
using Robust.Server.GameObjects;
using Robust.Server.Player;
_sawmill.Debug($"Admin log converters found: {string.Join(" ", converterNames)}");
}
- private (JsonDocument json, HashSet<Guid> players, Dictionary<int, string?> entities) ToJson(
+ private (JsonDocument Json, HashSet<Guid> Players, List<AdminLogEntity> Entities) ToJson(
Dictionary<string, object?> properties)
{
- var entities = new Dictionary<int, string?>();
+ var entities = new Dictionary<EntityUid, AdminLogEntity>();
var players = new HashSet<Guid>();
var parsed = new Dictionary<string, object?>();
? metadata.EntityName
: null;
- entities.TryAdd((int) uid, entityName);
+ // TODO set the id too whenever we feel like running a migration for 10 hours
+ entities.TryAdd(uid, new AdminLogEntity { Name = entityName });
if (_entityManager.TryGetComponent(uid, out ActorComponent? actor))
{
}
}
- return (JsonSerializer.SerializeToDocument(parsed, _jsonOptions), players, entities);
+ return (JsonSerializer.SerializeToDocument(parsed, _jsonOptions), players, entities.Values.ToList());
}
}
// Per update
private TimeSpan _nextUpdateTime;
- private readonly ConcurrentQueue<QueuedLog> _logQueue = new();
- private readonly ConcurrentQueue<QueuedLog> _preRoundLogQueue = new();
+ private readonly ConcurrentQueue<AdminLog> _logQueue = new();
+ private readonly ConcurrentQueue<AdminLog> _preRoundLogQueue = new();
// Per round
private int _currentRoundId;
_nextUpdateTime = _timing.RealTime.Add(_queueSendDelay);
// TODO ADMIN LOGS array pool
- var copy = new List<QueuedLog>(_logQueue.Count + _preRoundLogQueue.Count);
+ var copy = new List<AdminLog>(_logQueue.Count + _preRoundLogQueue.Count);
copy.AddRange(_logQueue);
_logQueue.Clear();
}
else
{
- foreach (var queued in _preRoundLogQueue)
+ foreach (var log in _preRoundLogQueue)
{
- queued.Log.RoundId = _currentRoundId;
- CacheLog(queued);
+ log.RoundId = _currentRoundId;
+ CacheLog(log);
}
copy.AddRange(_preRoundLogQueue);
{
Interlocked.Exchange(ref _currentLogId, 0);
+ if (!_preRoundLogQueue.IsEmpty)
+ {
+ // This technically means that you could get pre-round logs from
+ // a previous round passed onto the next one
+ // If this happens please file a complaint with your nearest lottery
+ foreach (var log in _preRoundLogQueue)
+ {
+ log.Id = NextLogId;
+ }
+ }
+
if (_metricsEnabled)
{
PreRoundQueueCapReached.Set(0);
}
}
- private async void Add(LogType type, LogImpact impact, string message, JsonDocument json, HashSet<Guid> players, Dictionary<int, string?> entities)
+ private void Add(LogType type, LogImpact impact, string message, JsonDocument json, HashSet<Guid> players, List<AdminLogEntity> entities)
{
- var logId = NextLogId;
- var date = DateTime.UtcNow;
-
var log = new AdminLog
{
- Id = logId,
+ Id = NextLogId,
RoundId = _currentRoundId,
Type = type,
Impact = impact,
- Date = date,
+ Date = DateTime.UtcNow,
Message = message,
Json = json,
- Players = new List<AdminLogPlayer>(players.Count)
+ Players = new List<AdminLogPlayer>(players.Count),
+ Entities = entities
};
- var queued = new QueuedLog(log, entities);
-
foreach (var id in players)
{
var player = new AdminLogPlayer
{
- LogId = logId,
+ LogId = log.Id,
PlayerUserId = id
};
if (_runLevel == GameRunLevel.PreRoundLobby)
{
- _preRoundLogQueue.Enqueue(queued);
+ _preRoundLogQueue.Enqueue(log);
}
else
{
- _logQueue.Enqueue(queued);
+ _logQueue.Enqueue(log);
CacheLog(log);
}
}
+++ /dev/null
-using Content.Server.Database;
-
-namespace Content.Server.Administration.Logs;
-
-public readonly struct QueuedLog
-{
- public QueuedLog(AdminLog log, Dictionary<int, string?> entities)
- {
- Log = log;
- Entities = entities;
- }
-
- public AdminLog Log { get; }
-
- public Dictionary<int, string?> Entities { get; }
-
- public void Deconstruct(out AdminLog log, out Dictionary<int, string?> entities)
- {
- log = Log;
- entities = Entities;
- }
-}
using Microsoft.EntityFrameworkCore;
using Robust.Shared.Enums;
using Robust.Shared.Network;
-using Robust.Shared.Utility;
namespace Content.Server.Database
{
return (server, false);
}
- public virtual async Task AddAdminLogs(List<QueuedLog> logs)
+ public async Task AddAdminLogs(List<AdminLog> logs)
{
await using var db = await GetDb();
-
- var entities = new Dictionary<int, AdminLogEntity>();
-
- foreach (var (log, entityData) in logs)
- {
- var logEntities = new List<AdminLogEntity>(entityData.Count);
- foreach (var (id, name) in entityData)
- {
- var entity = entities.GetOrNew(id);
- entity.Name = name;
- logEntities.Add(entity);
- }
-
- log.Entities = logEntities;
- db.DbContext.AdminLog.Add(log);
- }
-
+ db.DbContext.AdminLog.AddRange(logs);
await db.DbContext.SaveChangesAsync();
}
#region Admin Logs
Task<Server> AddOrGetServer(string serverName);
- Task AddAdminLogs(List<QueuedLog> logs);
+ Task AddAdminLogs(List<AdminLog> logs);
IAsyncEnumerable<string> GetAdminLogMessages(LogFilter? filter = null);
IAsyncEnumerable<SharedAdminLog> GetAdminLogs(LogFilter? filter = null);
IAsyncEnumerable<JsonDocument> GetAdminLogsJson(LogFilter? filter = null);
return server;
}
- public Task AddAdminLogs(List<QueuedLog> logs)
+ public Task AddAdminLogs(List<AdminLog> logs)
{
DbWriteOpsMetric.Inc();
return RunDbCommand(() => _db.AddAdminLogs(logs));
using System.Net;
using System.Threading;
using System.Threading.Tasks;
-using Content.Server.Administration.Logs;
using Content.Server.IP;
using Content.Server.Preferences.Managers;
using Content.Shared.CCVar;
using Microsoft.EntityFrameworkCore;
using Robust.Shared.Configuration;
using Robust.Shared.Network;
-using Robust.Shared.Utility;
namespace Content.Server.Database
{
return round.Id;
}
- public override async Task AddAdminLogs(List<QueuedLog> logs)
- {
- await using var db = await GetDb();
-
- var nextId = 1;
- if (await db.DbContext.AdminLog.AnyAsync())
- {
- nextId = db.DbContext.AdminLog.Max(round => round.Id) + 1;
- }
-
- var entities = new Dictionary<int, AdminLogEntity>();
-
- foreach (var (log, entityData) in logs)
- {
- log.Id = nextId++;
-
- var logEntities = new List<AdminLogEntity>(entityData.Count);
- foreach (var (id, name) in entityData)
- {
- var entity = entities.GetOrNew(id);
- entity.Name = name;
- logEntities.Add(entity);
- }
-
- foreach (var player in log.Players)
- {
- player.LogId = log.Id;
- }
-
- log.Entities = logEntities;
- db.DbContext.AdminLog.Add(log);
- }
-
- await db.DbContext.SaveChangesAsync();
- }
-
public override async Task<int> AddAdminNote(AdminNote note)
{
await using (var db = await GetDb())