asp.net-mvc 如何将日志记录添加到 MVC4 WebApi
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11420783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Add Logging to MVC4 WebApi
提问by maxfridbe
I am trying to create a [LoggedApiCall]filter for a Get()on an ApiControllerAccording to this: ASP.NET Web API ActionFilter example
我想创建一个[LoggedApiCall]用于过滤器Get()上的ApiController根据是:的ASP.NET Web API ActionFilter例子
I have created a System.Web.HttpFilters.ActionFilterAttribute.
The override allows for OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
我创建了一个System.Web.HttpFilters.ActionFilterAttribute. 覆盖允许OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
I cannot seem to find a way to get the IP of the caller from the HttpActionExecutedContext
我似乎无法找到一种方法来从 HttpActionExecutedContext
Perhaps I am going about logging every API call the wrong way?
也许我打算以错误的方式记录每个 API 调用?
采纳答案by Dean Ward
We use the following filter which we add to HttpConfiguration.Filters. Some code:
我们使用以下过滤器添加到HttpConfiguration.Filters. 一些代码:
internal class LoggingFilter : IExceptionFilter, IActionFilter
{
private readonly ILog log;
public LoggingFilter(ILog log)
{
if (log == null)
{
throw new ArgumentNullException("log");
}
this.log = log;
}
public bool AllowMultiple
{
get { return false; }
}
Task IExceptionFilter.ExecuteExceptionFilterAsync(HttpActionExecutedContext actionContext, CancellationToken cancellationToken)
{
if (actionContext == null)
{
throw new ArgumentNullException("actionContext");
}
this.log.Error(string.Format("Unexpected error while executing {0}", this.BuildLogEntry(actionContext.ActionContext)), actionContext.Exception);
return TaskHelpers.Completed();
}
Task<HttpResponseMessage> IActionFilter.ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
if (actionContext == null)
{
throw new ArgumentNullException("actionContext");
}
if (continuation == null)
{
throw new ArgumentNullException("continuation");
}
if (!this.log.IsDebugEnabled)
{
// no point running at all if logging isn't currently enabled
return continuation();
}
string logEntry = this.BuildLogEntry(actionContext);
IDisposable logContext = this.log.DebugTiming("Executing {0}", logEntry);
Task<string> requestContent;
if (actionContext.Request.Content != null)
{
requestContent = actionContext.Request.Content.ReadAsStringAsync().ContinueWith(requestResult => string.IsNullOrEmpty(requestResult.Result) ? "N/A" : requestResult.Result);
}
else
{
requestContent = TaskHelpers.FromResult("N/A");
}
return requestContent.ContinueWith(
requestResult =>
{
this.log.DebugFormat("{0}, Request = {1}", logEntry, requestResult.Result);
return continuation()
.ContinueWith(t =>
{
Task<string> responseContent;
if (t.IsCompleted && t.Result.Content != null)
{
responseContent = t.Result.Content.ReadAsStringAsync().ContinueWith(responseResult => string.IsNullOrEmpty(responseResult.Result) ? "N/A" : responseResult.Result);
}
else
{
responseContent = TaskHelpers.FromResult("N/A");
}
return responseContent.ContinueWith(
responseResult =>
{
using (logContext)
{
this.log.DebugFormat("{0}, Status Code: {1}, Response = {2}", logEntry, t.Result.StatusCode, responseResult.Result);
}
return t.Result;
});
}).Unwrap();
}).Unwrap();
}
/// <summary>
/// Builds log data about the request.
/// </summary>
/// <param name="actionContext">Data associated with the call</param>
private string BuildLogEntry(HttpActionContext actionContext)
{
string route = actionContext.Request.GetRouteData().Route.RouteTemplate;
string method = actionContext.Request.Method.Method;
string url = actionContext.Request.RequestUri.AbsoluteUri;
string controllerName = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
string actionName = actionContext.ActionDescriptor.ActionName;
return string.Format("{0} {1}, route: {2}, controller:{3}, action:{4}", method, url, route, controllerName, actionName);
}
}
We use log4net, you can replace the ILogimplementation with whatever you see fit. ILog.DebugTimingis just an extension method that uses a Stopwatch to get elapsed time for each call.
我们使用 log4net,您可以用ILog您认为合适的任何内容替换实现。ILog.DebugTiming只是一个扩展方法,它使用秒表来获取每次调用的经过时间。
Edit: This post Get the IP address of the remote hosthas details on how to get the IP address of the remote caller.
编辑:这篇文章获取远程主机的 IP 地址详细介绍了如何获取远程调用者的 IP 地址。
Cheers, Dean
干杯,院长

