Updated
This commit is contained in:
37
EonaCat.Logger.LogServer/Services/IAnalyticsService.cs
Normal file
37
EonaCat.Logger.LogServer/Services/IAnalyticsService.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using LogCentral.Server.Data;
|
||||
using LogCentral.Server.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public interface IAnalyticsService
|
||||
{
|
||||
Task<Dictionary<string, object>> GetAnalyticsAsync(DateTime startDate, DateTime endDate);
|
||||
}
|
||||
|
||||
public class AnalyticsService : IAnalyticsService
|
||||
{
|
||||
private readonly LogCentralDbContext _context;
|
||||
|
||||
public AnalyticsService(LogCentralDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, object>> GetAnalyticsAsync(DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var logs = await _context.LogEntries
|
||||
.Where(l => l.Timestamp >= startDate && l.Timestamp <= endDate)
|
||||
.ToListAsync();
|
||||
|
||||
return new Dictionary<string, object>
|
||||
{
|
||||
["totalEvents"] = logs.Count(l => l.Level == 7),
|
||||
["topEvents"] = logs
|
||||
.Where(l => l.Level == 7)
|
||||
.GroupBy(l => l.Message)
|
||||
.Select(g => new { Event = g.Key, Count = g.Count() })
|
||||
.OrderByDescending(x => x.Count)
|
||||
.Take(10)
|
||||
.ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
33
EonaCat.Logger.LogServer/Services/ILogService.cs
Normal file
33
EonaCat.Logger.LogServer/Services/ILogService.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using LogCentral.Server.Models;
|
||||
|
||||
namespace LogCentral.Server.Services;
|
||||
|
||||
public interface ILogService
|
||||
{
|
||||
Task AddLogsAsync(List<LogEntry> entries);
|
||||
Task<LogEntry?> GetLogByIdAsync(string id);
|
||||
Task<PagedResult<LogEntry>> GetLogsAsync(LogQueryParams queryParams);
|
||||
Task<Dictionary<string, object>> GetStatsAsync(string? app, string? env);
|
||||
Task<bool> ValidateApiKeyAsync(string apiKey);
|
||||
}
|
||||
|
||||
public class LogQueryParams
|
||||
{
|
||||
public string? Search { get; set; }
|
||||
public string? Application { get; set; }
|
||||
public string? Environment { get; set; }
|
||||
public int? Level { get; set; }
|
||||
public DateTime? StartDate { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
public int Page { get; set; } = 1;
|
||||
public int PageSize { get; set; } = 50;
|
||||
}
|
||||
|
||||
public class PagedResult<T>
|
||||
{
|
||||
public List<T> Items { get; set; } = new();
|
||||
public int TotalCount { get; set; }
|
||||
public int Page { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize);
|
||||
}
|
||||
30
EonaCat.Logger.LogServer/Services/ISearchService.cs
Normal file
30
EonaCat.Logger.LogServer/Services/ISearchService.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using LogCentral.Server.Data;
|
||||
using LogCentral.Server.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LogCentral.Server.Services;
|
||||
|
||||
public interface ISearchService
|
||||
{
|
||||
Task<List<LogEntry>> SearchAsync(string query, int limit = 100);
|
||||
}
|
||||
|
||||
public class SearchService : ISearchService
|
||||
{
|
||||
private readonly LogCentralDbContext _context;
|
||||
|
||||
public SearchService(LogCentralDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<List<LogEntry>> SearchAsync(string query, int limit = 100)
|
||||
{
|
||||
return await _context.LogEntries
|
||||
.Where(l => EF.Functions.Like(l.Message, $"%{query}%") ||
|
||||
EF.Functions.Like(l.Exception ?? "", $"%{query}%"))
|
||||
.OrderByDescending(l => l.Timestamp)
|
||||
.Take(limit)
|
||||
.ToListAsync();
|
||||
}
|
||||
}
|
||||
106
EonaCat.Logger.LogServer/Services/LogService.cs
Normal file
106
EonaCat.Logger.LogServer/Services/LogService.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using LogCentral.Server.Data;
|
||||
using LogCentral.Server.Models;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace LogCentral.Server.Services;
|
||||
|
||||
public class LogService : ILogService
|
||||
{
|
||||
private readonly LogCentralDbContext _context;
|
||||
|
||||
public LogService(LogCentralDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task AddLogsAsync(List<LogEntry> entries)
|
||||
{
|
||||
await _context.LogEntries.AddRangeAsync(entries);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<LogEntry?> GetLogByIdAsync(string id)
|
||||
{
|
||||
return await _context.LogEntries.FindAsync(id);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<LogEntry>> GetLogsAsync(LogQueryParams queryParams)
|
||||
{
|
||||
var query = _context.LogEntries.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(queryParams.Search))
|
||||
{
|
||||
query = query.Where(l =>
|
||||
l.Message.Contains(queryParams.Search) ||
|
||||
l.Exception!.Contains(queryParams.Search) ||
|
||||
l.Category.Contains(queryParams.Search));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(queryParams.Application))
|
||||
query = query.Where(l => l.ApplicationName == queryParams.Application);
|
||||
|
||||
if (!string.IsNullOrEmpty(queryParams.Environment))
|
||||
query = query.Where(l => l.Environment == queryParams.Environment);
|
||||
|
||||
if (queryParams.Level.HasValue)
|
||||
query = query.Where(l => l.Level == queryParams.Level.Value);
|
||||
|
||||
if (queryParams.StartDate.HasValue)
|
||||
query = query.Where(l => l.Timestamp >= queryParams.StartDate.Value);
|
||||
|
||||
if (queryParams.EndDate.HasValue)
|
||||
query = query.Where(l => l.Timestamp <= queryParams.EndDate.Value);
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
var items = await query
|
||||
.OrderByDescending(l => l.Timestamp)
|
||||
.Skip((queryParams.Page - 1) * queryParams.PageSize)
|
||||
.Take(queryParams.PageSize)
|
||||
.ToListAsync();
|
||||
|
||||
return new PagedResult<LogEntry>
|
||||
{
|
||||
Items = items,
|
||||
TotalCount = totalCount,
|
||||
Page = queryParams.Page,
|
||||
PageSize = queryParams.PageSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, object>> GetStatsAsync(string? app, string? env)
|
||||
{
|
||||
var query = _context.LogEntries.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(app))
|
||||
query = query.Where(l => l.ApplicationName == app);
|
||||
|
||||
if (!string.IsNullOrEmpty(env))
|
||||
query = query.Where(l => l.Environment == env);
|
||||
|
||||
var last24Hours = DateTime.UtcNow.AddHours(-24);
|
||||
var stats = new Dictionary<string, object>
|
||||
{
|
||||
["totalLogs"] = await query.CountAsync(),
|
||||
["last24Hours"] = await query.Where(l => l.Timestamp >= last24Hours).CountAsync(),
|
||||
["errorCount"] = await query.Where(l => l.Level >= 4).CountAsync(),
|
||||
["warningCount"] = await query.Where(l => l.Level == 3).CountAsync(),
|
||||
["applications"] = await _context.LogEntries
|
||||
.Select(l => l.ApplicationName)
|
||||
.Distinct()
|
||||
.CountAsync(),
|
||||
["byLevel"] = await query
|
||||
.GroupBy(l => l.Level)
|
||||
.Select(g => new { Level = g.Key, Count = g.Count() })
|
||||
.ToListAsync()
|
||||
};
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
public async Task<bool> ValidateApiKeyAsync(string apiKey)
|
||||
{
|
||||
return await _context.Applications
|
||||
.AnyAsync(a => a.ApiKey == apiKey && a.IsActive);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user