derFunk
derFunk

Reputation: 1630

ServiceStack: Exception in RestService is not logged in catch-clause

I'm using Log4Net with ServiceStack. It's initialized within the 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();
}

I have a static Log object within my MyAppHost-class:

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

..and I have a Rest Service like this:

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";
    }

}

So when a exception in Operator.DoSomething occurs, I neither see "Posting to MyService" nor "Exception: xxx" in my logfile. When no exception occurs those log entries appear in the logfile.

I can overcome this problem by moving the try/catch from Operator.DoSomething to the OnPost method of MyService, surrounding the DoSomething Call. Everything works fine then when I do that (I'ss see both log outputs).

I want to understand why the logging does not work the way I wanted to realize it in the first place. Is there something I've missed?

Upvotes: 3

Views: 332

Answers (1)

mythz
mythz

Reputation: 143339

Although your Application_Start() code looks like you want to use ServiceStack.Logging with:

LogManager.LogFactory = new Log4NetFactory(true);

You're not using ServiceStack.Logging interfaces anywhere else in the code, e.g.

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

Instead of ServiceStack's ILog interface:

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

Another anomaly is that you don't have a separate logger for each class, you're instead sharing the static AppHost logger.

As ServiceStack just delegates the logging to the underlying provider, the issue is with Log4Net not ServiceStack, but the issue could be related to Log4Net's use of ThreadStatic since the thread that's logging in the WebWorker is different to the Thread that created the MyAppHost.Log.

Upvotes: 1

Related Questions