Web API审核日志记录

我需要审核对我的Web API的日志调用,理想情况下我想使用属性,例如:

[HttpPost, Auditing] public dynamic MyAPICall() 

Attribute应该能够在执行之前和之后拦截API调用,以便记录参数以及API调用运行多长时间。

使用MVC,我可以创建一个ActionFilterAttribute衍生物并覆盖OnActionExecuted和OnActionExecuting。

在Web API世界中是否可以等效?

我会使用消息处理程序而不是属性。

 public class LoggingHandler : DelegatingHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { LogRequest(request); return base.SendAsync(request, cancellationToken).ContinueWith(task => { var response = task.Result; LogResponse(response); return response; }); } private void LogRequest(HttpRequestMessage request) { (request.Content ?? new StringContent("")).ReadAsStringAsync().ContinueWith(x => { Logger.Info("{4:yyyy-MM-dd HH:mm:ss} {5} {0} request [{1}]{2} - {3}", request.GetCorrelationId(), request.Method, request.RequestUri, x.Result, DateTime.Now, Username(request)); }); } private void LogResponse(HttpResponseMessage response) { var request = response.RequestMessage; (response.Content ?? new StringContent("")).ReadAsStringAsync().ContinueWith(x => { Logger.Info("{3:yyyy-MM-dd HH:mm:ss} {4} {0} response [{1}] - {2}", request.GetCorrelationId(), response.StatusCode, x.Result, DateTime.Now, Username(request)); }); } private string Username(HttpRequestMessage request) { var values = new List().AsEnumerable(); if (request.Headers.TryGetValues("my-custom-header-for-current-user", out values) == false) return ""; return values.First(); } } 

为此目的,Http消息处理程序应该是一个很好的可扩展点。 但请注意,并发请求内容读取可能存在一些问题。 例如,Model Binder可能会尝试读取请求内容,而LoggingHandler正在读取它并且无法反序列化模型。 要防止此类问题,只需将Wait调用添加到LogRequestLoggingInfo方法即可。

 public class LoggingHandler : DelegatingHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // Log the request information LogRequestLoggingInfo(request); // Execute the request return base.SendAsync(request, cancellationToken).ContinueWith(task => { var response = task.Result; // Extract the response logging info then persist the information LogResponseLoggingInfo(response); return response; }); } private void LogRequestLoggingInfo(HttpRequestMessage request) { if (request.Content != null) { request.Content.ReadAsByteArrayAsync() .ContinueWith(task => { var result = Encoding.UTF8.GetString(task.Result); // Log it somewhere }).Wait(); // !!! Here is the fix !!! } } private void LogResponseLoggingInfo(HttpResponseMessage response) { if (response.Content != null) { response.Content.ReadAsByteArrayAsync() .ContinueWith(task => { var responseMsg = Encoding.UTF8.GetString(task.Result); // Log it somewhere }); } } } 

你可以在这里阅读更多相关信息。

我想你有兴趣看看Web API跟踪http://www.asp.net/web-api/overview/testing-and-debugging/tracing-in-aspnet-web-api 。 它允许您查看Web API的内部机制。

在您的情况下,我假设您对操作的输入和输出特别感兴趣。 因此,您可以像下面的示例一样修改TraceWriter以过滤掉冗余信息:

 public class ActionAuditor : ITraceWriter { private const string TargetOperation = "ExecuteAsync"; private const string TargetOpeartor = "ReflectedHttpActionDescriptor"; public void Trace(HttpRequestMessage request, string category, TraceLevel level, Action traceAction) { var rec = new TraceRecord(request, category, level); traceAction(rec); if (rec.Operation == TargetOperation && rec.Operator == TargetOpeartor) { if (rec.Kind == TraceKind.Begin) { // log the input of the action } else { // log the output of the action } } } } 

我曾经使用过一个库,它允许您使用Action Filters记录与ASP.NET Web API控制器的交互。

它可以使用调用者信息,参数,输出,持续时间,exception等记录操作方法调用。

看看Audit.WebApi 。