Log level philosophy

6

Eric posted today about log level confusion. As with everything, I have a long-winded and obsessive opinion about this so I thought I’d share it so the blogosphere can tell me how wrong I am. (Sorry, many days with no blogging has made me feisty!)

My opinion is that there are 4 log levels that matter for general program logging (specialized logs like audit and performance have their own rules). I don’t care what you call them so feel free to replace these with the names of your choice.

  • ERROR – an error has occurred in the program (usually an exception). All internal or unexpected failures should be logged at ERROR level. Programmers should care about anything logged as an error. User errors (like input validation) should generally NOT be logged at ERROR level. These are expected (if invalid) inputs and you should respond to the user appropriately (another post altogether), but this is not a program error. Exceptions may be made for things like repeated invalid password attempts that are likely security problems.
  • WARNING – an anomalous condition has been detected and the program will attempt to deal with it. No action needs to be taken externally but you might be interested if things go down in flames 5 minutes later. The conditions for warnings are relatively rare but an example would be reaching a warning threshold on a connection pool or a loss of connectivity that can be repaired by reconnecting to the same or different source.
  • INFO – an interesting piece of information that helps to give context to a log, often when things are starting or stopping. INFO messages should never be printed on a “per transaction” (whatever that means to you) path through the code. That is, INFO messages should be 1-time or very occasional messages.
  • DEBUG – whatever your OCD programmer mind desires.

The first three levels (ERROR, WARNING, and INFO) should always be on. If your logs grow rapidly with these levels on, something is wrong. You should be able to run in production with these levels for weeks without a problem (but you should really use a rolling log writer just in case). DEBUG should be used only during development for debugging.

On the subject of hierarchical loggers, I generally find them to be more annoying than useful. If you do use them, I really prefer to use them with the DEBUG level for turning on a targeted set of debug logging, not for changing what comes out of ERROR, WARNING, and INFO.

Comments

6 Responses to “Log level philosophy”
  1. Randall says:

    I agree that ERROR, WARNING and INFO should always be on and that the logs should generally not grow under normal operation.

    I also wonder whether there is a difference between open source and proprietary. With proprietary, only the developers should really ever use any finer-grained logging. With open source, users may want to turn on finder-grained logging so they can understand what the code is doing. Thoughts?

    Also, any thoughts on how internationalization fits into logging?

  2. Randall says:

    My internationalization question above wasn’t too clear. Let me try it again.

    Internationalizing logs is technically not difficult. My question surrounds whether its appropriate to internationalize finer-grained logging (DEBUG and TRACE)? Having extra messages expands the localization effort. And TRACE is really just extensions of the codebase, and you really have to have the code (which is generally in English and not internationalized) to use TRACE messages. DEBUG is arguably like TRACE, but could be used by users to help understand behavior (and unexpected behavior).

  3. Alex says:

    Regarding, open source v proprietary I don’t think there’s much of a difference but it’s an interesting question. I think in both cases, there should be instructions on how to turn on debug logging. It’s one of my pet peeves that this is such a PITA on so many open source libs. Even in the proprietary world, it’s quite common for other teams, field, or customers to need to turn on debug logging so it should be straightforward for them as well.

    Regarding internationalization, your question was very clear to me. In fact, I’ve wrestled with this exact question here before. Lots of good comments on that entry.

    Generally, my default answer would be that it’s not worth it to do that as (like it or not) English tends to be the lingua franca between programmers. It’s both way more costly (in money and/or time) and way more complicated. So, unless there were some really strong other reason, I would avoid it.

  4. Bill Shirley says:

    I totally agree. One clarification I would add (which you may or mayn’t agree with) is that normal situations can throw exceptions, but they must be caught (your password case). Exceptions are a programmatic mechanism for stealing the execution away from the current location, are perfectly valid for doing so, but in such cases must be caught. (And reported as an appropriate level log if applicable.)

  5. Brian Hartin says:

    I would add TEST, because it’s nice to be able to log messages that only appear in the logs created during unit/other automated testing, and are readily identifiable as such (i.e. grep/searching for ‘level: TEST’, etc.).

Trackbacks

Check out what others are saying about this post...
  1. [...] log level philosophy [...]



Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!