1

私はPieter de Rycke によるこのブログのようなロギング動作を書いていますが、NLog 用です。私はこのコードを思いつきました:

public class NLogLogger : IParameterInspector
{
    private void Log(Type instanceType, string operationName, string msg)
    {
        NLog.Logger logger = LogManager.GetLogger(
            instanceType.FullName, instanceType);
        logger.Info(msg, instanceType);
    }

    public object BeforeCall(string operationName, object[] inputs)
    {
        // Retrieve the service instance type for the logger then log the call.
        OperationContext operationContext = OperationContext.Current;
        Type instanceType = operationContext.InstanceContext
            .GetServiceInstance().GetType();
        Log(instanceType, operationName, "BeforeCall");

        return instanceType;
    }

    public void AfterCall(
        string operationName, object[] outputs,
        object returnValue, object correlationState
    )
    {
        if (correlationState is Type)
            Log(correlationState as Type, operationName, "AfterCall");
    }
}

ロギング動作は正常に機能します。Example.MyServiceピーターが説明したように、属性を使用してサービスに挿入しました。NLog ターゲットにこのレイアウトがあります。

${longdate} ${callsite} ${level:uppercase=true} ${message}

ただし、操作のコールサイトGetContactsが間違っています:

2013-07-11 13:32:53.1379 Common.NLogLogger.Log INFO BeforeCall
2013-07-11 13:32:53.7121 Common.NLogLogger.Log INFO AfterCall

正しいのは次のとおりです。

2013-07-11 13:32:53.1379 Example.MyService.GetContacts INFO BeforeCall
2013-07-11 13:32:53.7121 Example.MyService.GetContacts INFO AfterCall

私は何を試しましたか?

NLog は、このStackOverflow の回答で説明されているように、ラッパーまたはファサードをログに記録するための呼び出しサイトの特別な処理を提供します: 呼び出しサイトのクラスをログ メソッドに渡します。

実際、私はlogger.Info(msg, instanceType)上記のLog()方法でこれを行いました。BeforeCall()ただし、動作のメソッドが実行されているときにコールサイトがまだスタック トレースにないため、これは機能しません。WCF はまだ操作の実行を開始していません。NLog はスタック トレースで呼び出しサイトを見つけられず、スタック トレースをアンラップできません。

コールサイトを偽装するにはどうすればよいですか? または、ロギング動作の「正しい」コールサイトを表示するにはどうすればよいですか?

4

1 に答える 1