首页 新闻 会员 周边 捐助

求教:.net6 用Nlog做操作日志

0
悬赏园豆:20 [已解决问题] 解决于 2023-07-08 18:19

各位大哥好,公司需求需要在WebApi中加一个审计日志类似的功能,
主要抓取:IP、接口入参、回参;存在数据库和日志文件中,自己百度写的一个不是很好用。
想请问有参考文章或者代码可以参考吗?

qiu_Perfect的主页 qiu_Perfect | 初学一级 | 园豆:123
提问于:2023-06-18 16:58
< >
分享
最佳答案
0

你好,实现审计日志的方式有很多种,以下是其中一种基于 ASP.NET Core 的实现方式,供你参考。

首先,在启动类中添加以下配置,启用 ASP.NET Core 内置的日志:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 省略其它配置

        // 添加内置日志服务
        services.AddLogging(logging =>
        {
            logging.AddConfiguration(Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
            logging.AddFile("logs/{Date}.txt");
        });
        
        // 添加授权服务
        services.AddAuthorization(options =>
        {
            // 添加自定义授权规则
            options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("admin"));
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // 添加中间件,启用日志
        app.UseSerilogRequestLogging();
        
        // 省略其它配置
    }
}

在上述代码中,我们通过 AddLogging 方法配置了日志记录器。

并且通过 UseSerilogRequestLogging 中间件,记录了请求和响应的详细信息,包括请求方法、URL、IP 地址、响应状态码、请求参数、响应结果等。

接下来,我们在需要保留审计日志的中间件中,添加如下代码来记录日志:

private readonly RequestDelegate _next;

public AuditLoggingMiddleware(RequestDelegate next)
{
    _next = next;
}

public async Task InvokeAsync(HttpContext context, ILogger<AuditLoggingMiddleware> logger)
{
    // 获取请求函数信息和请求参数
    var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
    var methodName = controllerActionDescriptor.ControllerName + "." + controllerActionDescriptor.ActionName;
    var requestBody = await context.Request.GetRawBodyStringAsync(Encoding.UTF8);

    // 执行当前请求
    var originalBodyStream = context.Response.Body;
    var newBodyStream = new MemoryStream();
    context.Response.Body = newBodyStream;
    await _next(context);
    
    // 获取请求结果
    var responseBody = await GetResponseBody(context.Response);

    // 记录日志
    logger.LogInformation(
        "Method Name: {methodName} | Request Body: {requestBody} | Response Body: {responseBody}",
        methodName,
        requestBody,
        responseBody);

    // 写回响应结果
    newBodyStream.Seek(0, SeekOrigin.Begin);
    await newBodyStream.CopyToAsync(originalBodyStream);
}

private async Task<string> GetResponseBody(HttpResponse response)
{
    response.Body.Seek(0, SeekOrigin.Begin);
    string responseBody = await new StreamReader(response.Body).ReadToEndAsync();
    response.Body.Seek(0, SeekOrigin.Begin);
    return responseBody;
}

在上述代码中,我们编写了一个中间件 AuditLoggingMiddleware 来记录审计日志。

在 InvokeAsync 方法中,我们使用 ILogger<AuditLoggingMiddleware> 记录了当前请求的方法名、请求参数和响应结果。

注意:为了避免请求的 Response.Body 被多次读取,我们需要添加读取响应结果的方法 GetResponseBody。该方法将 Response.Body 的指针重置,在读取 Response.Body 的内容后再将指针重置。

最后,将中间件添加到管道中即可:

app.UseMiddleware<AuditLoggingMiddleware>();

以上就是一种基于 ASP.NET Core 的审计日志实现方式,供你参考。如果需要存储到数据库中,可在 ILogger 中使用 EF Core 进行数据库操作,或者手动写入数据库中。

收获园豆:20
小九九呀 | 菜鸟二级 |园豆:383 | 2023-06-18 18:53
其他回答(2)
0

你这种场景我以前也遇到过。

实际上就是写一个中间件来做路由转发。

public class CalculateExecutionTimeMiddleware
    {
        private readonly RequestDelegate _next;//下一个中间件
        private readonly ILogger<CalculateExecutionTimeMiddleware> _logger;
        private readonly IRecordLogRepository _recordLogRepository;

        Stopwatch stopwatch;
        public CalculateExecutionTimeMiddleware(
            RequestDelegate next,
            ILogger<CalculateExecutionTimeMiddleware> logger,
            IRecordLogRepository recordLogRepository)
        {
            _recordLogRepository = recordLogRepository;

            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }
            this._next = next;
            _logger = logger;
        }

        public async Task Invoke(HttpContext context)
        {
            stopwatch = new Stopwatch();
            stopwatch.Start();//在下一个中间价处理前,启动计时器
            await _next.Invoke(context);

            stopwatch.Stop();//所有的中间件处理完后,停止秒表。
            //记录日志
            string msg = $@"接口{context.Request.Path}耗时{stopwatch.ElapsedMilliseconds}ms";
            //记录日志
            this._logger.LogInformation(msg);
            var userAgent = context.Request.Headers["User-Agent"].FirstOrDefault();
            await _recordLogRepository.AddAsync(new ZhiKeCore.Models.RecordLog
            {
                CostTime = stopwatch.ElapsedMilliseconds,
                Content = msg,
                UserAgent = userAgent,
                ReqRoute = context.Request.Path
            });
        }
    }

    public static class CalculateExecutionTimeMiddlewareExtensions
    {
        public static IApplicationBuilder UseCalculateExecutionTime(
            this IApplicationBuilder app, 
            IRecordLogRepository recordLogRepository)
        {

            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }
            return app.UseMiddleware<CalculateExecutionTimeMiddleware>(recordLogRepository);
        }
    }

参考这篇:

楠木大叔 | 园豆:2083 (老鸟四级) | 2023-06-18 17:48
0

当使用.NET 6和NLog来实现Web API中的审计日志功能时,以下是一般的步骤和建议:

安装NLog:使用NuGet包管理器或在项目文件中添加NLog的依赖项。在.NET 6中,你可以使用NLog.Extensions.Hosting包。

配置NLog:在项目中创建一个NLog的配置文件(通常是一个XML文件),指定日志输出的目标(如数据库和文件),以及日志的格式和级别等设置。你可以参考NLog官方文档来了解如何配置和使用NLog。

创建审计日志类:在你的Web API项目中创建一个审计日志类,负责收集需要记录的信息,如IP、接口入参和回参等。可以在请求处理前后,或在适当的时机调用审计日志类的方法来收集和记录信息。

记录日志:在审计日志类中,使用NLog的Logger来记录日志信息。可以在配置文件中指定要使用的日志器名称,然后在代码中获取相应的Logger实例。

实现数据库记录:如果你希望将审计日志存储到数据库中,可以使用.NET提供的数据库访问技术(如ADO.NET、Entity Framework等)来实现数据库记录的功能。根据NLog的配置,将审计日志的信息插入到数据库表中。

实现日志文件记录:NLog已经提供了多种日志目标(targets),包括文件目标(File Target)。根据NLog的配置,将审计日志的信息写入到指定的日志文件中。

测试和调试:在开发过程中,对审计日志功能进行充分的测试和调试,确保日志记录和存储正常工作。可以模拟各种情况,验证日志的正确性和完整性。

日志格式和内容:根据需求,可以定义适合审计目的的日志格式和内容。这可以包括请求的URL、HTTP方法、请求头、用户身份验证信息等。

请注意,以上步骤仅为一般指导,并根据你的具体需求和技术栈可能会有所不同。你可以参考NLog官方文档和示例代码,了解更多关于配置和使用NLog的细节。同时,你还可以搜索和阅读相关的博客文章和教程,以获得更多实践经验和最佳实践。

最后,如果你遇到具体的问题,欢迎随时提问,我会尽力提供帮助。

Technologyforgood | 园豆:7541 (大侠五级) | 2023-06-21 22:29
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册