首页 > 其他分享 >如何在.net6webapi中记录每次接口请求的日志

如何在.net6webapi中记录每次接口请求的日志

时间:2023-06-27 17:57:56浏览次数:38  
标签:net6webapi 记录 Serilog app 接口 new 日志 builder

为什么在软件设计中一定要有日志系统?

在软件设计中日志模块是必不可少的一部分,可以帮助开发人员更好的了解程序的运行情况,提高软件的可靠性,安全性和性能,日志通常能帮我们解决如下问题:

  • 调试和故障排查:日志可以记录程序运行时的各种信息,包括错误,异常,警告等,方便开发人员在出现问题时进行调试和故障排查。
  • 性能优化:日志可以记录程序的运行时间,资源占用等信息,帮助开发人员进行性能优化。
  • 安全审计:日志可以记录用户的操作行为,方便进行安全审计和追踪。
  • 统计分析:日志可以记录用户的访问情况,使用习惯等信息,方便进行统计分析和用户行为研究。
  • 业务监控:日志可以记录业务数据的变化情况,方便进行业务监控和数据分析。
  • 数据还原:日志记录每次请求的请求及响应数据,可以在数据丢失的情况下还原数据。

如何在.net6webapi中添加日志?

1.添加日志组件

.net6有自带的logging组件,还有很多优秀的开源log组件,如NLog,serilog,这里我们使用serilog组件来构建日志模块。

新建.net6,asp net web api项目之后,为其添加如下四个包

 

dotnet add package Serilog.AspNetCore//核心包
dotnet add package Serilog.Formatting.Compact
dotnet add Serilog.Sinks.File//提供记录到文件
dotnet add Serilog.Sinks.MSSqlServer//提供记录到sqlserver

2.新建SeriLogExtend扩展类型,配置日志格式并注入

    public static class SeriLogExtend
    {
        public static void AddSerilLog(this ConfigureHostBuilder configureHostBuilder)
        {
            //输出模板
            string outputTemplate = "{NewLine}【{Level:u3}】{Timestamp:yyyy-MM-dd HH:mm:ss.fff}" +
                                    "{NewLine}#Msg#{Message:lj}" +
                                    "{NewLine}#Pro #{Properties:j}" +
                                    "{NewLine}#Exc#{Exception}" +
                                     new string('-', 50);

            // 配置Serilog
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // 排除Microsoft的日志
                .Enrich.FromLogContext() // 注册日志上下文
                .WriteTo.Console(outputTemplate: outputTemplate) // 输出到控制台
                .WriteTo.MSSqlServer("Server=.;Database=testdb;User ID=sa;Password=123;TrustServerCertificate=true", sinkOptions: GetSqlServerSinkOptions(), columnOptions: GetColumnOptions())
                .WriteTo.Logger(configure => configure // 输出到文件
                            .MinimumLevel.Debug()
                            .WriteTo.File(  //单个日志文件,总日志,所有日志存到这里面
                                $"logs\\log.txt",
                                rollingInterval: RollingInterval.Day,
                                outputTemplate: outputTemplate)
                            .WriteTo.File( //每天生成一个新的日志,按天来存日志
                                "logs\\{Date}-log.txt", //定输出到滚动日志文件中,每天会创建一个新的日志,按天来存日志
                                retainedFileCountLimit: 7,
                                outputTemplate: outputTemplate
                            ))
                .CreateLogger();

            configureHostBuilder.UseSerilog(Log.Logger); // 注册serilog

            /// <summary>
            /// 设置日志sqlserver配置
            /// </summary>
            /// <returns></returns>
            MSSqlServerSinkOptions GetSqlServerSinkOptions()
            {
                var sqlsinkotpions = new MSSqlServerSinkOptions();
                sqlsinkotpions.TableName = "sys_Serilog";//表名称
                sqlsinkotpions.SchemaName = "dbo";//数据库模式
                sqlsinkotpions.AutoCreateSqlTable = true;//是否自动创建表
                return sqlsinkotpions;
            }

            /// <summary>
            /// 设置日志sqlserver 列配置
            /// </summary>
            /// <returns></returns>
            ColumnOptions GetColumnOptions()
            {
                var customColumnOptions = new ColumnOptions();

                customColumnOptions.Store.Remove(StandardColumn.MessageTemplate);//删除多余的这两列
                customColumnOptions.Store.Remove(StandardColumn.Properties);

                var columlist = new List<SqlColumn>();
                columlist.Add(new SqlColumn("RequestJson", SqlDbType.NVarChar, true, 2000));//添加一列,用于记录请求参数string
                columlist.Add(new SqlColumn("ResponseJson", SqlDbType.NVarChar, true, 2000));//添加一列,用于记录响应数据
                customColumnOptions.AdditionalColumns = columlist;
                return customColumnOptions;
            }
        }
    }

然后再program.cs中调用这个扩展方法

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers(options =>
{
    options.Filters.Add(typeof(RequestLoggingFilter));
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Host.AddSerilLog();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

这里我设计的日志信息只包括了

  1. Message:日志信息
  2. Level:等级
  3. TimeStamp:记录日志时间
  4. Exception:异常信息
  5. RequestJson:请求参数json
  6. ResponseJson:响应结果json

其中前面四种为日志默认,后两种为我主动添加,在实际的设计中还有可能有不同的信息,如:

  • IP:请求日志
  • Action:请求方法
  • Token:请求token
  • User:请求的用户

日志的设计应该根据实际的情况而来,其应做到足够详尽,能帮助开发者定位,解决问题,而又不能过于重复臃肿,白白占用系统空间,我这边的示例仅供大家参考

3.添加RequestLoggingFilter过滤器,用以记录每次请求的日志

    public class RequestLoggingFilter : IActionFilter
    {
        private readonly Serilog.ILogger _logger;//注入serilog
        private Stopwatch _stopwatch;//统计程序耗时

        public RequestLoggingFilter(Serilog.ILogger logger)
        {
            _logger = logger;
            _stopwatch = Stopwatch.StartNew();
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            _stopwatch.Stop();
            var request = context.HttpContext.Request;
            var response = context.HttpContext.Response;
            _logger
                .ForContext("RequestJson",request.QueryString)//请求字符串
                .ForContext("ResponseJson", JsonConvert.SerializeObject(context.Result))//响应数据json
                .Information("Request {Method} {Path} responded {StatusCode} in {Elapsed:0.0000} ms",//message
                request.Method,
                request.Path,
                response.StatusCode,
                _stopwatch.Elapsed.TotalMilliseconds);
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
        }
    }

在program.cs中将该过滤器添加进所有控制器之中

builder.Services.AddControllers(options =>
{
    options.Filters.Add(typeof(RequestLoggingFilter));
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Host.AddSerilLog();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

测试效果

在控制器添加一个测试方法并将其调用一次

[HttpGet]
public dynamic Get123(string model)
{
    return new { name = "123", id = 2 };
}

 

控制台输出

 数据库记录

 项目根目录下logs文件夹中日志文件记录

 

标签:net6webapi,记录,Serilog,app,接口,new,日志,builder
From: https://www.cnblogs.com/SaoJian/p/17509392.html

相关文章

  • 【lazada接口系列】获得lazada商品详情API接口采集商品规格信息调用示例
    ​Lazada商品详情API接口的作用是获取Lazada电商平台上的某一商品的详情信息,包括商品的名称、销售价格、库存数量、图片、商品描述、品牌、产地、售后保障等信息。开发者可以使用该API接口获取到商品的原始数据,进行分析、筛选等操作。通过该接口获取到的商品详情数据可以结合其......
  • 接口测试--什么是接口?什么是接口测试?
    一.什么是接口?接口:简单来说就是系统之间传输数据的通道。【就好像手机充电,必须要用充电线一样】接口的特点:(1)一定的规范要求(协议)(2)能灵活自定义的部分(开发)测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。二.接口都有哪些类型?接口一般分为两......
  • Spring REST 接口自定义404不能捕获NoHandlerFoundException问题
    SpringREST接口自定义404以及解决不能捕获NoHandlerFoundException问题  一、自定义404响应内容版本说明:SpringBoot2.0.1.RELEASEREST风格默认PostMan请求的404响应如下:{"timestamp":"2018-06-07T05:23:27.196+0000","status":404,"error":&quo......
  • jmeter测试dubbo接口
    jmeter测试dubbo接口一.Windows环境通过jdbc给lottery接口造用户测试数据1.将mysql-connector-java-5.1.22-bin.jar放到D:\apache-jmeter-5.5\lib\ext目录下2.在测试计划中,添加mysql-connector-java-5.1.22-bin.jar包路径3.添加-线程组-添加-配置元件-jdbcconnectionconfig......
  • jmeter测试websocket接口
    Jmeter测试websocket接口一.Websocket接口原理1.打开网页:从http协议,升级到websocket协议,请求简历websocket连接2.服务器返回建立成功成功3.客户端向服务端发送匹配请求4.服务端选择一个客服上线5.服务器返回客服id6.客户端向服务器发送消息7.服务器推送消息给指定的客服8.服务器向......
  • jmeter测试dubbo接口
    Jmeter测试dubbo接口一.dubbo插件准备1.把jmeter-plugins-dubbo-2.7.4.1-jar-with-dependencies.jar包放在D:\apache-jmeter-5.5\lib\ext目录2.重新打开jmeter客户端在线程组-添加-取样器-dubbosimple,添加dubbo接口请求二.Jmeter测试lottery接口1.配置zookeeper参数由于du......
  • C#学习笔记 -- 接口
    接口1、什么是接口接口指定一组函数成员,而不实现他们的引用类型只能类和结构来实现接口例子//声明实现接口的CA类classCA:IInfo{  publicstringName;  publicintAge;​  //在类中实现接口的方法  publicstringGetAge() { ......
  • jmeter测试tcp接口
    Jmeter测试tcp接口一.tcp接口结构Tcp接口:只有ip和port传参数据类型根据开发定义的类型需要添加一个ascii码的十进制字节结束符,tcp才会关闭二.Tcp接口环境搭建在testfan-tcp-server.jar目录下,启动cmd命令行,输入:java-jartestfan-tcp-server.jar三.Jmeter测试tcp接口1.添加tc......
  • jmeter测试签名接口
    Jmeter测试签名接口一.了解签名规则1.常见的签名规则:业务数据+当前时间戳2.签名方式:md5(大部分)二.接口信息1.Ip和端口号:10.196.104:80802.接口路径:/pinter/com/userInfo3.请求类型:post4.数据类型:json5.请求参数:{ "phoneNum":"123434", "optCode":"testfan", "timestamp":"......
  • 查看nginx日志
    查看nginx日志一、查看nginx访问日志1.查看nginx中项目日志存放路径cd/etc/nginx/conf.dcatoa.conf2.在项目nginx中,查看访问日志cd/var/log/nginxtail-foa.access.log二、增加统计时间此处统计的是:nginx从接收到客户端请求,转发给toamcat,服务端处理完成,返回到ngin......