网站首页 网站源码
using Dpz.Core.Public.ViewModel.AppLogs;
using Seq.Api;
using Seq.Api.Model.Events;
namespace Dpz.Core.Service.RepositoryServiceImpl;
public class AppLogEntryService(
IConfiguration configuration,
ILogger<AppLogEntryService> logger)
: IAppLogEntryService
{
private SeqConnection GetSeqConnection()
{
var logApiHost = configuration["LogApiHost"];
if (string.IsNullOrEmpty(logApiHost))
throw new Exception("configuration no LogApiHost node");
var apiKey = configuration["LogSeq:ApiKey"];
if (string.IsNullOrEmpty(apiKey))
throw new Exception("configuration no LogSeq.Apikey node");
var connection = configuration["AgileConfig:env"] != "PROD"
? new SeqConnection(logApiHost, configuration["LogApiKey"])
: new SeqConnection(logApiHost, apiKey);
return connection;
}
public async Task<ResultSetPart?> GetPageAsync(string? filter = null, string? startAtId = null,
string? afterId = null, int pageSize = 20)
{
using var connection = GetSeqConnection();
var part = await connection.Events.PageAsync(
filter: filter,
startAtId: startAtId,
afterId: afterId,
render: true,
count: pageSize);
return part;
}
public async Task<List<AccessSummary>> GetLatestAccessNumberAsync(int? days)
{
var startDate = days == null
? DateTime.Now.Date.AddHours(8)
: DateTime.Now.Date.AddHours(8).AddDays(days.Value - 1);
using var connection = GetSeqConnection();
var filters = new List<string>
{
"Program = 'Dpz.Core.Web'",
"SourceContext = 'Serilog.AspNetCore.RequestLoggingMiddleware'",
"RequestPath <> '/chathub'",
"RequestPath <> '/notification'",
"RequestPath <> '/notification/negotiate'",
"RequestPath <> '/chathub/negotiate'",
"RequestPath <> '/chat/init'"
};
var filter = string.Join(" and ", filters);
try
{
var query =
$"""
select count(@Id) from stream
where {filter}
group by time(1d)
""";
var part = await connection.Data.QueryAsync(query, startDate, DateTime.Now.AddHours(8));
var list = part.Slices.Select(x => new AccessSummary
{
Date = Convert.ToDateTime(x.Time).ToString("yyyy/MM/dd"),
Count = Convert.ToInt32(x.Rows.FirstOrDefault()?.FirstOrDefault() ?? 0)
}).ToList();
return list;
}
catch (Exception e)
{
logger.LogError(e, "get latest access number fail");
return new List<AccessSummary>();
}
}
}
上述代码定义了一个名为 AppLogEntryService
的服务类,主要用于与 Seq 日志管理系统进行交互。Seq 是一个用于集中管理和查询日志的工具。该服务实现了 IAppLogEntryService
接口,提供了两个主要功能:获取日志分页和获取最新的访问统计。
以下是代码的主要功能和结构的详细解释:
public AppLogEntryService(
IConfiguration configuration,
ILogger<AppLogEntryService> logger)
IConfiguration
和 ILogger<AppLogEntryService>
。IConfiguration
用于读取应用程序的配置设置(如日志 API 的主机和 API 密钥)。ILogger<AppLogEntryService>
用于记录日志。private SeqConnection GetSeqConnection()
SeqConnection
对象,该对象用于与 Seq API 进行交互。LogApiHost
和 LogSeq:ApiKey
,并根据环境(是否为生产环境)选择合适的 API 密钥。public async Task<ResultSetPart?> GetPageAsync(string? filter = null, string? startAtId = null,
string? afterId = null, int pageSize = 20)
GetSeqConnection
方法建立与 Seq 的连接,并调用 PageAsync
方法获取日志数据。ResultSetPart
对象,包含分页的日志信息。public async Task<List<AccessSummary>> GetLatestAccessNumberAsync(int? days)
AccessSummary
对象的列表。days
,表示要查询的天数。days
参数计算起始日期,并构建一组过滤条件,排除特定的请求路径。AccessSummary
对象的列表,包含日期和访问计数。AppLogEntryService
类提供了与 Seq 日志系统的交互功能,允许用户分页获取日志和获取最近的访问统计信息。通过使用配置和日志记录,它确保了服务的灵活性和可维护性。