mirror of
https://github.com/DrizzleTime/Foxel.git
synced 2026-05-12 02:20:28 +08:00
182 lines
5.8 KiB
C#
182 lines
5.8 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Foxel.Models;
|
|
using Foxel.Models.DataBase;
|
|
using Foxel.Models.Response.Log;
|
|
|
|
namespace Foxel.Services.Management;
|
|
|
|
public class LogManagementService(IDbContextFactory<MyDbContext> contextFactory) : ILogManagementService
|
|
{
|
|
public async Task<PaginatedResult<LogResponse>> GetLogsAsync(int page, int pageSize, string? searchQuery = null, LogLevel? level = null, DateTime? startDate = null, DateTime? endDate = null)
|
|
{
|
|
await using var context = await contextFactory.CreateDbContextAsync();
|
|
|
|
var query = context.Logs.AsQueryable();
|
|
|
|
if (!string.IsNullOrEmpty(searchQuery))
|
|
{
|
|
query = query.Where(l => l.Message.Contains(searchQuery) ||
|
|
l.Category.Contains(searchQuery) ||
|
|
(l.Exception != null && l.Exception.Contains(searchQuery)));
|
|
}
|
|
|
|
if (level.HasValue)
|
|
{
|
|
query = query.Where(l => l.Level == level.Value);
|
|
}
|
|
|
|
if (startDate.HasValue)
|
|
{
|
|
query = query.Where(l => l.Timestamp >= startDate.Value);
|
|
}
|
|
|
|
if (endDate.HasValue)
|
|
{
|
|
query = query.Where(l => l.Timestamp <= endDate.Value);
|
|
}
|
|
|
|
var totalCount = await query.CountAsync();
|
|
|
|
var logs = await query
|
|
.OrderByDescending(l => l.Timestamp)
|
|
.Skip((page - 1) * pageSize)
|
|
.Take(pageSize)
|
|
.Select(l => new LogResponse
|
|
{
|
|
Id = l.Id,
|
|
Level = l.Level,
|
|
Message = l.Message,
|
|
Category = l.Category,
|
|
EventId = l.EventId,
|
|
Timestamp = l.Timestamp,
|
|
Exception = l.Exception,
|
|
RequestPath = l.RequestPath,
|
|
RequestMethod = l.RequestMethod,
|
|
StatusCode = l.StatusCode,
|
|
IPAddress = l.IPAddress,
|
|
UserId = l.UserId,
|
|
Properties = l.Properties
|
|
})
|
|
.ToListAsync();
|
|
|
|
return new PaginatedResult<LogResponse>
|
|
{
|
|
Data = logs,
|
|
TotalCount = totalCount,
|
|
Page = page,
|
|
PageSize = pageSize
|
|
};
|
|
}
|
|
|
|
public async Task<LogResponse> GetLogByIdAsync(int id)
|
|
{
|
|
await using var context = await contextFactory.CreateDbContextAsync();
|
|
|
|
var log = await context.Logs.FirstOrDefaultAsync(l => l.Id == id);
|
|
if (log == null)
|
|
throw new KeyNotFoundException($"找不到ID为 {id} 的日志");
|
|
|
|
return new LogResponse
|
|
{
|
|
Id = log.Id,
|
|
Level = log.Level,
|
|
Message = log.Message,
|
|
Category = log.Category,
|
|
EventId = log.EventId,
|
|
Timestamp = log.Timestamp,
|
|
Exception = log.Exception,
|
|
RequestPath = log.RequestPath,
|
|
RequestMethod = log.RequestMethod,
|
|
StatusCode = log.StatusCode,
|
|
IPAddress = log.IPAddress,
|
|
UserId = log.UserId,
|
|
Properties = log.Properties
|
|
};
|
|
}
|
|
|
|
public async Task<bool> DeleteLogAsync(int id)
|
|
{
|
|
await using var context = await contextFactory.CreateDbContextAsync();
|
|
|
|
var log = await context.Logs.FirstOrDefaultAsync(l => l.Id == id);
|
|
if (log == null)
|
|
throw new KeyNotFoundException($"找不到ID为 {id} 的日志");
|
|
|
|
context.Logs.Remove(log);
|
|
await context.SaveChangesAsync();
|
|
return true;
|
|
}
|
|
|
|
public async Task<BatchDeleteResult> BatchDeleteLogsAsync(List<int> ids)
|
|
{
|
|
await using var context = await contextFactory.CreateDbContextAsync();
|
|
|
|
var result = new BatchDeleteResult();
|
|
|
|
var logs = await context.Logs.Where(l => ids.Contains(l.Id)).ToListAsync();
|
|
result.SuccessCount = logs.Count;
|
|
result.FailedCount = ids.Count - logs.Count;
|
|
|
|
if (logs.Any())
|
|
{
|
|
context.Logs.RemoveRange(logs);
|
|
await context.SaveChangesAsync();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> ClearLogsByDateAsync(DateTime beforeDate)
|
|
{
|
|
await using var context = await contextFactory.CreateDbContextAsync();
|
|
|
|
var logsToDelete = await context.Logs
|
|
.Where(l => l.Timestamp < beforeDate)
|
|
.ToListAsync();
|
|
|
|
if (logsToDelete.Any())
|
|
{
|
|
context.Logs.RemoveRange(logsToDelete);
|
|
await context.SaveChangesAsync();
|
|
}
|
|
|
|
return logsToDelete.Count;
|
|
}
|
|
|
|
public async Task<int> ClearAllLogsAsync()
|
|
{
|
|
await using var context = await contextFactory.CreateDbContextAsync();
|
|
|
|
var totalCount = await context.Logs.CountAsync();
|
|
|
|
if (totalCount > 0)
|
|
{
|
|
await context.Database.ExecuteSqlRawAsync("DELETE FROM \"Logs\"");
|
|
}
|
|
|
|
return totalCount;
|
|
}
|
|
|
|
public async Task<LogStatistics> GetLogStatisticsAsync()
|
|
{
|
|
await using var context = await contextFactory.CreateDbContextAsync();
|
|
|
|
// 使用UTC时间避免PostgreSQL时区问题
|
|
var todayUtc = DateTime.UtcNow.Date;
|
|
var tomorrowUtc = todayUtc.AddDays(1);
|
|
|
|
var totalCount = await context.Logs.CountAsync();
|
|
var todayCount = await context.Logs.CountAsync(l => l.Timestamp >= todayUtc && l.Timestamp < tomorrowUtc);
|
|
var errorCount = await context.Logs.CountAsync(l => l.Level == LogLevel.Error || l.Level == LogLevel.Critical);
|
|
var warningCount = await context.Logs.CountAsync(l => l.Level == LogLevel.Warning);
|
|
|
|
return new LogStatistics
|
|
{
|
|
TotalCount = totalCount,
|
|
TodayCount = todayCount,
|
|
ErrorCount = errorCount,
|
|
WarningCount = warningCount
|
|
};
|
|
}
|
|
}
|