Asp.NetCore 请求日志拦截

本文详细介绍如何在ASP.NET Core中使用全局过滤器记录请求和响应日志,包括创建自定义过滤器类、配置全局应用及查看日志的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、首先创建一个全局过滤器

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

public class CustomerActionFilter: ActionFilterAttribute
    {
        private readonly ILogger _logger;
        private const string key = "enterTime";


        public CustomerActionFilter(ILogger<CustomerActionFilter> logger)
        {   
            _logger = logger;
        }


        public async override void OnActionExecuting(ActionExecutingContext context)
        {
            var actionDescriptor = string.Empty;
            try
            {
                #region 记录请求日志
                string requestBody = "";
                Stream stream = context.HttpContext.Request.Body;

                long contentLen = context.HttpContext.Request.ContentLength == null ? 0 : context.HttpContext.Request.ContentLength.Value;
                if (contentLen > 0 && stream != null)
                {
                	context.HttpContext.Request.EnableBuffering();
                    using (var buffer = new MemoryStream())
                    {
                        await context.HttpContext.Request.Body.CopyToAsync(buffer);
                        buffer.Position = 0;

                        var data = buffer.ToArray();
                        requestBody = Encoding.UTF8.GetString(data);
                        context.HttpContext.Request.Body.Position = 0;
                    }
                }

                long enterTime = DateTime.Now.Ticks;
                context.ActionDescriptor.Properties[key] = enterTime;
                context.HttpContext.Request.Headers.Append(key, new Microsoft.Extensions.Primitives.StringValues(enterTime.ToString()));
                //[POST_Request] {requestid} http://dev.localhost/messagr/api/message/send {data}
                actionDescriptor = ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ControllerName + "/" + ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ActionName;
                var url = context.HttpContext.Request.Host + context.HttpContext.Request.Path + context.HttpContext.Request.QueryString;
                _logger.LogError(string.Format("[{0}_Request] [{1}] {2} {3}\r\n{4}"
                , actionDescriptor
                , context.HttpContext.Request.Method
                , enterTime
                , url, requestBody));
                #endregion

            }
            catch (Exception e)
            {
                _logger.LogError(e.Message + e.StackTrace);

            }
            finally
            {
                base.OnActionExecuting(context);
            }
        }
        public override void OnActionExecuted(ActionExecutedContext context)
        {

            string responseBody = string.Empty;
            try
            {

                long enterTime = 0;
                var costTime = string.Empty;
                if (context.HttpContext.Request.Headers.TryGetValue(key, out var request_entertime))
                {
                    enterTime = Convert.ToInt64(request_entertime);
                    costTime = new TimeSpan(DateTime.Now.Ticks - enterTime).ToString();
                }
                dynamic result = context.Result.GetType().Name == "EmptyResult" ? new { Value = "无返回结果" } : context.Result as dynamic;
                if (result != null)
                {
                    responseBody = Newtonsoft.Json.JsonConvert.SerializeObject(result.Value);
                }
                var actionDescriptor = ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ControllerName + "/" + ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ActionName;
                _logger.LogDebug(string.Format("[{0}_Response] {1} CostTime:{2}\r\n{3}"
                , actionDescriptor
                , enterTime
                , costTime
                , responseBody));
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message + e.StackTrace);
            }
            finally
            {
                base.OnActionExecuted(context);
            }
        }
    }

2、下一步就是将该类注入的全局应用中

Startup.cs

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options=> {
                options.Filters.Add<CustomerActionFilter>();
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
		}

3、查看日志

这里我采用serilog 记录日志

2020-03-18 17:06:04.886 +08:00 [Debug] [demo/SubmitRecord_Request] [POST] 637201479648849057 localhost:63839/demo/CabSubmitRecord
{
    "id":55,
    "source":"数据来源"
}

2020-03-18 17:06:06.228 +08:00 [Debug] [demo/SubmitRecord_Response] 637201479648849057 CostTime:00:00:01.3289646
{"success":false,"message":"只有未提交的存件记录才能提交"}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值