2017-08-03 193 views
3

我希望自動記錄每個請求。在之前的.Net Framwork WebAPI項目中,我曾經註冊過一個delegateHandler來完成這個任務。如何在.NET Core WebAPI中自動記錄每個請求?

WebApiConfig.cs

public static void Register(HttpConfiguration config) 
{ 
    config.MessageHandlers.Add(new AutoLogDelegateHandler()); 
} 

AutoLogDelegateHandler.cs

public class AutoLogDelegateHandler : DelegatingHandler 
{ 

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     var requestBody = request.Content.ReadAsStringAsync().Result; 

     return await base.SendAsync(request, cancellationToken) 
      .ContinueWith(task => 
      { 
       HttpResponseMessage response = task.Result; 

       //Log use log4net 
       _LogHandle(request, requestBody, response); 

       return response; 
      }); 
    } 
} 

日誌內容的示例:

------------------------------------------------------ 
2017-08-02 19:34:58,840 
uri: /emp/register 
body: { 
    "timeStamp": 1481013427, 
    "id": "0322654451", 
    "type": "t3", 
    "remark": "system auto reg" 
} 
response: {"msg":"c556f652fc52f94af081a130dc627433","success":"true"} 
------------------------------------------------------ 

但在.NET核心的WebAPI項目,沒有WebApiConfig ,或Global.asax的註冊功能GlobalConfiguration.Configure(WebApiConfig.Register);

那麼有沒有什麼辦法可以在.NET Core WebAPI中實現這一點?

回答

4

您可以創建自己的篩選器屬性...

public class InterceptionAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
    var x = "This is my custom line of code I need executed before any of the controller actions, for example log stuff"; 
    base.OnActionExecuting(actionContext); 
    } 
} 

...你將與GlobalFilters註冊,但既然你說你正在使用.NET的核心,這是你可以試試出發......

docs.microsoft.com

您可以將它添加到MvcOptions.Filters全球註冊一個過濾器(所有控制器和動作) 收集 啓動類中的ConfigureServices方法:

讓我們知道它是否工作。

P.S. 這是whole tutorial on intercepting requests with WebAPI,以防有人需要更多細節。

+3

是的,它的工作原理。我創建了一個'AutoLogAttribute',並在'OnActionExecuted'處記錄了每個請求。然後通過將它添加到Startup類中的ConfigureServices方法中的MvcOptions.Filters集合來全局註冊該過濾器。 – wtf512

+0

真棒,我很高興它的作品 – Eedoh

+0

正確的答案是,它已經記錄了你。 – davidfowl

0

演示:

AutologArribute.cs(新文件)

/// <summary> 
/// <see cref="https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#Dependency injection"/> 
/// </summary> 
public class AutoLogAttribute : TypeFilterAttribute 
    { 
     public AutoLogAttribute() : base(typeof(AutoLogActionFilterImpl)) 
     { 

     } 

     private class AutoLogActionFilterImpl : IActionFilter 
     { 
      private readonly ILogger _logger; 
      public AutoLogActionFilterImpl(ILoggerFactory loggerFactory) 
      { 
       _logger = loggerFactory.CreateLogger<AutoLogAttribute>(); 
      } 

      public void OnActionExecuting(ActionExecutingContext context) 
      { 
       // perform some business logic work 
      } 

      public void OnActionExecuted(ActionExecutedContext context) 
      { 
       //TODO: log body content and response as well 
       _logger.LogDebug($"path: {context.HttpContext.Request.Path}"); 
      } 
     } 
    } 

StartUp.cs

public void ConfigureServices(IServiceCollection services) 
{ 
    //.... 

    // https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#filter-scopes-and-order-of-execution 
    services.AddMvc(opts=> { 
     opts.Filters.Add(new AutoLogAttribute()); 
    }); 

    //.... 
} 
6

ActionFilter會工作,直到你需要登錄通過MVC中間件處理的請求(作爲控制器動作)。

如果您需要記錄所有傳入請求,那麼您需要使用中間件方法。

良好的視覺explanationenter image description here

注意,中間件順序是很重要的,如果你的日誌應在管道開始執行完成,中間件應該是第一個之一。從docs

簡單的例子:

public void Configure(IApplicationBuilder app) 
    { 
     app.Use(async (context, next) => 
     { 
      // Do loging 
      // Do work that doesn't write to the Response. 
      await next.Invoke(); 
      // Do logging or other work that doesn't write to the Response. 
     });