9

Web API へのログ呼び出しを監査する必要があります。理想的には、次のような属性を使用したいと思います。

    [HttpPost, Auditing]
    public dynamic MyAPICall()

属性は、パラメーターをログに記録し、API 呼び出しの実行にかかった時間も記録するために、実行の前後に API 呼び出しをインターセプトできる必要があります。

MVC を使用すると、ActionFilterAttribute の派生物を作成し、OnActionExecuted と OnActionExecuting をオーバーライドできます。

Web API の世界で同等のことが可能ですか?

4

4 に答える 4

16

属性ではなくメッセージ ハンドラーを使用します。

public class LoggingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> 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<string>().AsEnumerable();
        if (request.Headers.TryGetValues("my-custom-header-for-current-user", out values) == false) return "<anonymous>";

        return values.First(); 
    }
}
于 2012-09-06T12:50:42.620 に答える
5

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<TraceRecord> 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
            }
        }
    }
}
于 2012-10-19T22:46:21.460 に答える