Re: Additional logging questions
Novice wrote:
Arne Vajh??j wrote:
Novice wrote:
Basically, I'm looking for advice on what should always be logged by
every class. I understand now that every class is going to have its
own logger but what should be logged?
You log what reveals to someone reading the log what they want to know.
Or to put it another way, are there cases where a class won't log at
all?
That depends on the logging level set at runtime, doesn't it?
If a class is unable to log anything, and that omission deprives someone of
necessary information when they're relying on the log, it's a mistake.
If no one ever needs information from that class out of the log, it can get
away with not logging.
I'm thinking of things like Enums. If I have an enum that lists the
Enums are classes. The same considerations apply as for any other class.
days of the week, there's not much to go wrong there and I'm not
Is there? I trust you - there's not.
likely to throw exceptions or even have a try/catch block. So should
it just be left so that it isn't logging at all? Or should there be
some standard bare-minimum sort of logging, like an entering() and
existing(), even if nothing else of interest goes on?
Good questions. Answer wisely, Grasshopper.
What about holder classes? I'm not sure if I'm using the terminology
You are.
correctly but I'm thinking of a class where you simply store related
bits of data, like a Name class whose constructor insists on a first
name and a last name and then supplies getters and setters so that
another class can ask for just the first name or just the last name?
(Let's pretend that everyone has exactly one given name and one
surname, no exceptions, just to keep this simple). This could be an
awfully barebones class if it only had a two line constructor and one
line getters and setters. Should it log anyway?
Logging is generally for state changes.
My feeling is that Lew would say NOT to log unless there was a good
reason to log and then cite several good reasons to log. I'm not sure
Don't take advice from your fantasy of me unless it's good advice. Don't take
advice from the real me unless it's good advice, either.
if something like an enum or a holder class (if I've used the term
correctly) would EVER justify logging though.
Sure.
Depends on what's in it, doesn't it?
I may have completely misread Lew and, if so, I'm sorry. Maybe this
is another premature leap....
Since I never before said what to log or not log that you've seen, there's
been nothing to misread, has there?
Nothing to read, nothing to misread. It's a simple equation.
Some of the rest of you may differ dramatically on what should be
logged and when it is okay not to bother. I hope some of you can
share those thoughts with me.
Basically, I'm just about ready to start getting loggers for each and
every class in the project I'm working on now (with plans to do the
same in every project as I create it or return to it). But I don't
want to do too much logging either.....
You should log the information you expect potentially could be
useful when troubleshooting a problem.
This requires that you think like a useful person, not a computer programmer.
When you're troubleshooting a log, you don't have code in front of you. You
have what the log tells you. It had better God-damned tell you what you need,
because you wouldn't be looking if someone weren't breathing down your neck.
No fancy "***********************=============" strings. Logs are dense,
multi-mega- or gigabyte beasts of tightly printed strings.
Ops personnel read logs. Ops personnel think programmers are children. I had
an ops mentor who told me, "We love getting the programmers from [the
development location] here for six months. They go back to coding _changed_!"
Other times they're cursing the programmers who wrote such lame logging
statements.
And as a general rule, then if any doubt then log, because it
is usually better to have too much logging than too little
logging.
I do not see any need for logging in an enum or in a pure
data class (holder class).
Some enums.
Like any other class, it depends on what it does. But generally you log state
changes, i.e., behavioral methods (not usually attributes). You log anything
that is weird. You log errors and warnings.
You pick appropriate logging levels. Here's my log4j idiom:
public void loadResource()
{
logger.debug("");
final BufferedReader reader;
try
{
reader = new BufferedReader(new InputStreamReader(getClass()
.getResourceAsStream("/config/configuration.txt")));
}
catch(IOException exc)
{
String msg = "Cannot open configuration. "+ exc.getLocalizedMessage();
logger.error(msg, exc);
throw new IllegalStateException(msg, exc);
}
assert reader != null;
try
{
// read the Reader, etc.
}
catch(IOException exc)
{
String msg = "Cannot read configuration. "+ exc.getLocalizedMessage();
logger.error(msg, exc);
throw new IllegalStateException(msg, exc);
}
finally
{
try
{
reader.close();
}
catch(IOException exc)
{
String msg = "Cannot close configuration. "
+ exc.getLocalizedMessage();
logger.warn(msg, exc);
}
}
}
Note the multiple uses of 'logger' (an instance member) in that method.
But please add a toString method in your data class, so
when the class with real login in that uses the data class
can log it and you get something useful in the log about the
data.
Sorry, I'm not following you.
Are you saying that the toString() method needs to be there to turn
things like references into meaningful information? I know that a
reference to something like a JFrame is not going to be very meaningful
and would rather display the name given the JFrame via setName(). Or are
you saying something quite different?
'toString()' should always give a useful way to identify the specific instance.
It should depend on (and usually only on) the same fields used to drive
'hashCode()' and 'equals()' and if supported, 'compareTo()' (which should
always be consistent with each other).
--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg