3

私はServiceStackでLog4Netを使用しています。Global.asax.cs内で初期化されます。

    protected void Application_Start(object sender, EventArgs e)
{
    LogManager.LogFactory = new Log4NetFactory(true); //Also runs log4net.Config.XmlConfigurator.Configure()
    new MyAppHost().Init();
}

MyAppHostクラス内に静的Logオブジェクトがあります。

public class MyAppHost : AppHostBase
{
    public static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(TvDAppHost).Name);
    // ...

..そして私はこのようなRESTサービスを持っています:

public class MyService : RestServiceBase<MyResponse>
{
    public override object OnPost(ProfileSync request)
    {
        MyAppHost.Log.Info("Posting to MyService");

        MyResponse response;
        var myOperator = new Operator();
        response = myOperator.DoSomething();

        return new MyDto();
    }
}

public class Operator {

    public MyResponse DoSomething()
    {
        MyResponse r = new MyResponse();
        try{
            r.Stuff = DoStuff();
        }
        catch(Exception e)
        {
            // this will not be logged!!
            MyAppHost.Log.Error("Exception: " + e);
            r.Error = true;
        }
        return r;
    }

    private string DoStuff()
    {
        // Do something which can throw exceptions.
        // Actually I'm doing Database work here.
        return "stuff";
    }

}

そのため、Operator.DoSomethingで例外が発生すると、ログファイルに「PostingtoMyService」も「Exception:xxx」も表示されません。例外が発生しない場合、それらのログエントリはログファイルに表示されます。

この問題は、try / catchをOperator.DoSomethingからMyServiceのOnPostメソッドに移動し、DoSomething呼び出しを囲むことで解決できます。それを行うと、すべてが正常に機能します(両方のログ出力が表示されます)。

そもそもロギングが思ったように機能しない理由を理解したいと思います。私が見逃したものはありますか?

4

1 に答える 1

1

あなたのApplication_Start()コードはServiceStack.Loggingを使用したいように見えますが:

LogManager.LogFactory = new Log4NetFactory(true);

コード内の他の場所でServiceStack.Loggingインターフェイスを使用していません。

public static readonly log4net.ILog Log = 
    log4net.LogManager.GetLogger(typeof(TvDAppHost).Name);

ServiceStackのILogインターフェースの代わりに:

public static readonly ILog Log = LogManager.GetLogger(typeof(TvDAppHost));

もう1つの異常は、クラスごとに個別のロガーがなく、代わりに静的AppHostロガーを共有していることです。

ServiceStackはログを基になるプロバイダーに委任するだけなので、問題はServiceStackではなくLog4Netにありますが、WebWorkerにログインしているスレッドはMyAppHost.Logを作成したスレッドとは異なるため、問題はLog4NetによるThreadStaticの使用に関連している可能性があります。

于 2012-11-26T16:53:54.557 に答える