我們使用下面的過濾器,我們添加到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);
}
}
我們使用log4net的,可以更換ILog
執行,不管你認爲合適的。 ILog.DebugTiming
只是一個擴展方法,它使用秒錶來獲取每個呼叫的經過時間。
編輯: 此帖子Get the IP address of the remote host詳細介紹瞭如何獲取遠程調用者的IP地址。
乾杯, 院長
你發送的作品的鏈接: 私人字符串GetClientIp(HttpRequestMessage要求) \t \t { \t \t \t如果(request.Properties.ContainsKey( 「MS_HttpContext」)) \t \t \t {(HttpContextWrapper)request.Properties [「MS_HttpContext」])。Request.UserHostAddress; \t \t \t} \t \t \t如果(request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name)) \t \t \t { \t \t \t \t RemoteEndpointMessageProperty丙; \t \t \t \t prop =(RemoteEndpointMessageProperty)request.Properties [RemoteEndpointMessageProperty.Name]; \t \t \t \t return prop.Address; \t \t \t} \t \t \t return null; \t \t} – maxfridbe 2012-07-10 21:52:19
看起來好像Mike的回答是更好的選擇 - 如果需要的話可以注入實際的日誌記錄實現甚至內置的web api日誌框架(從而防止加倍努力)。 – Lex 2012-08-28 08:32:27
我們調查了'ITraceWriter'位,但它似乎很難將開始和結束時間關聯起來,並且在社區中似乎明顯缺乏生產力實施來指導您編寫自己的。我們決定上述方法更簡單。 – 2012-08-28 12:33:07