2015-09-06 18 views
5

Web Api 2とOwinを使用してアプリケーションにログを追加しようとしていますので、Microsoft Owin Loggingを使用しました。これは​​とILoggerFactoryが実装されており、STARTUPメソッドまたはOwin Middlewareコンポーネントのいずれかを使用します。例えばMicrosoft Owinロギング - Web Api 2 - ロガーの作成方法を教えてください。

、私はStartup方法にいるとき、私は使用してロガーを作成することができます。

public void Configuration(IAppBuilder app) 
    { 
     // Creates configuration 
     var configuration = new HttpConfiguration(); 

     // Configure WebApi Settings 
     WebApiConfig.Register(configuration); 

     app.SetLoggerFactory(new OwinLog4NetLoggerFactory("Default")); 

     var logger = app.CreateLogger<Startup>(); 
     logger.WriteInformation("test log"); 

     // Enabled WebApi in OWIN 
     app.UseWebApi(configuration); 
    } 

「OwinLog4NetLoggerFactoryは」私のカスタムILoggerFactory実装です

これまでのところ、...実際のウェブAPIのアクションメソッドを使用しているときに、どのようにロガーを作成できますか... Request.GetOwinEnvironment()にアクセスしようとしましたが、ロガーファクトリは辞書にありません。例えば

public class AccountController : ApiController 
{ 
    public int Get(int id) 
    { 
     // Create logger here 

     return id + 1; 
    } 
} 

私はAPIコントローラにロガーを追加するロガーファクトリーへの参照、あるいは注射で静的クラスを作成することができます知っているが、それはそのはず何かのためには複雑すぎるようですすでにそこにいてください。

すべてのアイデアをいただければ幸いです。

+0

誰もが実際に答えることができます元のポスターの質問?以下の1つの答えは、彼が求めたものではありません。 –

答えて

-1

すべてのメソッドでログコードを追加するのではなく、Global.asax.csに一度登録できるMessageLoggingHandlerを作成し、すべての要求と応答を記録します。 、あなたのGlobal.asax.csで次に

public abstract class MessageHandler : DelegatingHandler 
{ 
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     var corrId = Guid.NewGuid(); 
     var requestMethod = request.Method.Method.ToString(); 
     var requestUri = request.RequestUri.ToString(); 
     var ipAddress = request.GetOwinContext().Request.RemoteIpAddress; 

     var requestMessage = await request.Content.ReadAsByteArrayAsync(); 
     await LogMessageAsync(corrId, requestUri, ipAddress, "Request", requestMethod, request.Headers.ToString(), requestMessage, string.Empty); 

     var response = await base.SendAsync(request, cancellationToken); 

     var responseMessage = await response.Content.ReadAsByteArrayAsync(); 
     await LogMessageAsync(corrId, requestUri, ipAddress, "Response", requestMethod, response.Headers.ToString(), responseMessage, ((int)response.StatusCode).ToString() + "-" + response.ReasonPhrase); 

     return response; 
    } 

    protected abstract Task LogMessageAsync(Guid CorrelationId, string APIUrl, string ClientIPAddress, string RequestResponse, string HttpMethod, string HttpHeaders, byte[] HttpMessage, string HttpStatusCode); 

} 

public class MessageLoggingHandler : MessageHandler 
{ 
    protected override async Task LogMessageAsync(Guid CorrelationId, string APIUrl, string ClientIPAddress, string RequestResponse, string HttpMethod, string HttpHeaders, byte[] HttpMessage, string HttpStatusCode) 
    { 
     // Create logger here 

     //Do your logging here 
    } 
} 

まずDelegationHandlerから継承MessageHandlerのクラスを作成します。

ここでは、あなたの要件に応じて変更することができ、私が使用するコードですあなたは、上記で作成したMessageLoggingHandlerを登録する必要があります。

GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageLoggingHandler()); 

ただ、これはすべてのリクエストとレスポンス、意志の完全なメッセージ本文を記録します、注意してください。これは非常に迅速に(あなたのAPIの使用状況に応じて)多くのスペースを取ることができます。したがって、これを調整する必要があるかもしれません(例えば、1ヶ月程度の記録を残したり、200OK応答を無視するなど)。

+2

残念ながら、残念ながら私は各リクエスト/レスポンスをログに記録する必要はありません(FYI、Owinの世界では、通常はミドルウェアを通じて行います)。私はいくつかのアクションで "いくつかのデバッグまたは警告メッセージ"を記録する必要があるので、ロガーを作成する必要があります。ご返信ありがとうございます。 – Daniel

1

ミドルウェアを作成してコントローラ外のログを処理することをお勧めします。次に、スタートアップクラスの

public class LoggingMiddleware : OwinMiddleware 
{ 
    public LoggingMiddleware(OwinMiddleware next) 
     : base(next) 
    { 
    } 

    public override async Task Invoke(IOwinContext context) 
    { 
      //handle request logging 

      await Next.Invoke(context); 

      //handle response logging 
    } 

} 

:、、LoggingMiddlewareで要求ロギングコードを打つコントローラのコードをヒットしてから応答が上LoggingMiddlewareに記録されます

public class Startup 
{ 
    // ReSharper disable once UnusedMember.Global 
    public void Configuration(IAppBuilder appBuilder) 
    { 
     HttpConfiguration config = new HttpConfiguration(); 

     config.MapHttpAttributeRoutes(); 
     appBuilder.Use<LoggingMiddleware>(); 
     appBuilder.UseWebApi(config); 
    } 
} 

要求は、その後で来る

帰り道。

ただし、ミドルウェアからコントローラにオブジェクトを送信する場合は、ミドルウェアでcontext.Set("loggingObject", loggingObject);、次にコントローラーに var loggingObject = Request.GetOwinContext().Get<LoggerClass>("loggingObject");を使用できます。

編集:固定A}

+0

Samさん、ありがとうございます。しかし、それはコントローラの呼び出しの前と後にログインすることができます。私は各コントローラ/クラス内でLog4Netを使用して終了しました.... Trevorの推奨するように、私はLog4Netへの直接の依存関係を作成する必要はありませんので、ログ抽象化を使用することができましたが、 Microsoft Owinロギング。ありがとう。 – Daniel

0

私はNuGetで利用可能なアプリケーションでCommon.Loggingライブラリを、使用することをお勧めします。 Common.Loggingは、あなたの好みのロギングソリューションを使用するための共通のインターフェイスを提供します。それはあなたのような多くの問題を解決します。ここでNLogでCommon.Loggingを使用した例である:あなたのコントローラで

が、あなたはそうのようにアクセスします:

public class MyController : ApiController 
    { 
    private static readonly ILog Log = LogManager.GetLogger<MyController>(); 

    public async Task<IHttpActionResult> Get([FromUri] int id) 
    { 
     Log.Debug("Called Get with id " + id.ToString()); 
     return Ok(); 
    } 
    } 

これを書いている時点では(NuGetの最新Common.Logging.NLogパッケージをピックアップCommon.Logging.NLog41である必要があります)。次に、あなたのweb.configファイルで、あなたのNLog構成を使用するCommon.Logging構成します。

ここ
<common> 
    <logging> 
    <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog41"> 
     <arg key="configType" value="FILE" /> 
     <arg key="configFile" value="~/NLog.config" /> 
    </factoryAdapter> 
    </logging> 
</common> 

は、いくつかの追加のリンクです:

https://github.com/net-commons/common-logging

https://cmatskas.com/an-introduction-to-common-logging-api-2/

+0

ありがとうございました...私はLog4Netを各コントローラクラスで直接使用しましたが、アイデアはビルドインログ抽象化(別のパッケージではない)を使用することでした。ありがとう! – Daniel

関連する問題