如何在C#中获取.NET WebAPI
电话的已用时间?
我的日志文件需要这样的信息
我可以在api调用之前和之后轻松地执行DateTime.Now()
,但是,如果已经有了某些东西......让我们使用它!
答案 0 :(得分:8)
您可以使用过滤器
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Mvc;
namespace Cludo.App.Utility
{
/// <summary>
/// Used to log requests to server
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class LogActionRequestsAttribute : ActionFilterAttribute
{
public LogActionRequestsAttribute()
{
//You can inject to constructors ILog or what ever
}
public static Stopwatch GetTimer(HttpRequestMessage request)
{
const string key = "__timer__";
if (request.Properties.ContainsKey(key))
{
return (Stopwatch)request.Properties[key];
}
var result = new Stopwatch();
request.Properties[key] = result;
return result;
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
var timer = GetTimer(actionContext.Request);
timer.Start();
base.OnActionExecuting(actionContext);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
var timer = GetTimer(actionExecutedContext.Request);
timer.Stop();
var totalTime = timer.ElapsedMilliseconds;
}
}
}
然后在webapi配置
config.Filters.Add(
(LogActionRequestsAttribute)
GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof (LogActionRequestsAttribute)));
AttributeUsage阻止调用属性两次。 但我认为其他选项可能是你写http模块使用开始,结束请求事件,这可能是最好和精确的测量,在我的应用程序中它足以使用属性,因为几毫秒不会对我有什么大不了的
答案 1 :(得分:0)
如果它对某人有帮助,我在下面添加了适用于 .NET Core 的 Vova 答案的更新版本。
/// <summary>
/// Used to log requests to server
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class LogActionRequestsAttribute : ActionFilterAttribute
{
private const string ACTION = "Action";
private const string RESULT = "Result";
private static Stopwatch GetTimer(HttpContext context, string type)
{
var key = $"__timer__{type}";
if (context.Items.ContainsKey(key)) return (Stopwatch) context.Items[key];
var stopWatch = new Stopwatch();
context.Items[key] = stopWatch;
return stopWatch;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
var timer = GetTimer(context.HttpContext, ACTION);
timer.Start();
base.OnActionExecuting(context);
}
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
var timer = GetTimer(context.HttpContext, ACTION);
timer.Stop();
var logger = context.HttpContext.RequestServices.GetService<ILogger<LogActionRequestsAttribute>>();
logger.LogInformation($"{ACTION} call to {context.HttpContext.Request.Path} took {timer.ElapsedMilliseconds} ms");
}
public override void OnResultExecuting(ResultExecutingContext context)
{
var timer = GetTimer(context.HttpContext, RESULT);
timer.Start();
base.OnResultExecuting(context);
}
public override void OnResultExecuted(ResultExecutedContext context)
{
base.OnResultExecuted(context);
var timer = GetTimer(context.HttpContext, RESULT);
timer.Stop();
var logger = context.HttpContext.RequestServices.GetService<ILogger<LogActionRequestsAttribute>>();
logger.LogInformation($"{RESULT} call to {context.HttpContext.Request.Path} took {timer.ElapsedMilliseconds} ms");
}
}
该属性可以直接应用于 ApiController,无需额外注册。