5

I have log4net successfully setup for my C# application. Everything works fine, except when I do this:

catch (Exception ex)
{
    if (log.IsErrorEnabled)
       log.Error("test", ex);
}

All I get is the message "test", I do not get the exception at all. Then, when I do this:

catch (Exception ex)
{
    if (log.IsErrorEnabled)
       log.Error(ex);
}

I get the exception as desired, stack trace and everything. This works, but ideally I'd like to have both the message and the exception.

Why does the exact same code (no configuration changes) not work in the first example but it does in the second example? Am I reading the docs wrong for the Error() method?

landoncz
  • 1,997
  • 14
  • 15

3 Answers3

3

The first overload you are using is the one that you want: Error(string, Exception). If the exception is actually written depends on your appender and / or the layout you choose. Here is explained how to disable printing of the stacktrace: https://stackoverflow.com/a/3660529/106567

I need to see your configuration in order to tell why the exception is not printed.

The code that "works" is not really what you should do: log.Error(ex) seems to do what you want since log4net treats the exception as the message object and simply calls toString() on it. Any appender / layout that specifically deals with exceptions would be unable to process the exception properly. The same happens if you use one of the ErrorFormat overloads (actually I never quite understood, why you cannot use a formatted string and an exception at the same time).

Community
  • 1
  • 1
Stefan Egli
  • 17,398
  • 3
  • 54
  • 75
  • How would log4net be able to distinguish between the format string arguments and the exception..? – stuartd Feb 10 '15 at 13:30
  • by making the Exception the first argument. something like: Error(Exception ex, String message, params Object[] args) vs. Error(String message, params Object[] args) – Stefan Egli Feb 10 '15 at 13:38
  • That's true, but having the message and exception swap around in the parameter list would be unintuitive - `Error(string message)` and `Error(string message, Exception exception)` and `ErrorFormat(string message, params object[] args)` but then `ErrorFormat(Exception ex, string message, params object[] args)` - can always implement it as an extension method. – stuartd Feb 10 '15 at 14:19
  • fair enough, but it would not need to be this way. If you have an exception it is the first parameter, if not the message is the first parameter. ErrorFormat would not be necessary: Error(string), Error(string, object[]), Error(Exception, string), Error(Exception, string, object[]). Maybe this does not appeal to everyone, but it is good enough for me :-) – Stefan Egli Feb 10 '15 at 14:40
  • 1
    I've actually done what Stefan suggested in my log4net wrapper library. Works fine. – Chris Mar 10 '15 at 22:44
1

The solution was not relevant in the code I posted, but I was not fixing the flags correctly. The eventual solution was already found in this stack overflow post

Community
  • 1
  • 1
landoncz
  • 1,997
  • 14
  • 15
0

Try

log.ErrorFormat("test: {0}", ex);
display name
  • 4,165
  • 2
  • 27
  • 52
  • That works! I get the exception and stack trace and everything. Any idea why the Error(string, exception) method doesn't work? – landoncz Feb 09 '15 at 23:46
  • It may have something to do with your appender config. Not sure but glad it worked for you! :) – display name Feb 10 '15 at 00:18
  • @landoncz based on this solution working for you, it looks like the overload you were trying to use expected to dump the "ex" into the `string.format` template provided in the first parameter, and since there wasn't a `{0}` included, it was simply ignored. – Doctor Blue Feb 10 '15 at 00:21