Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #12442

Re: Additional logging questions

From Novice <novice@example..com>
Newsgroups comp.lang.java.programmer
Subject Re: Additional logging questions
Date 2012-02-27 19:14 +0000
Organization Your Company
Message-ID <XnsA0069221E7830jpnasty@94.75.214.39> (permalink)
References <XnsA005D74257FB0jpnasty@94.75.214.39> <4f4ae583$0$281$14726298@news.sunsite.dk> <XnsA005ED51BFCF7jpnasty@94.75.214.39> <jif6ua$3cm$1@news.albasani.net>

Show all headers | View raw


Lew <noone@lewscanon.com> wrote in news:jif6ua$3cm$1@news.albasani.net:

> 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?
> 
Right.

> 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. 
>
Another good rule of thumb. 
 
> If no one ever needs information from that class out of the log, it
> can get away with not logging.
>
That seems reasonable to me. I was pretty sure you were not going to 
advocate logging for the sake of logging and you didn't let me down ;-)
 
>>>> 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.
> 
Well, I'm thinking of enums like mine which are akin to edits. For 
instance, I use preferences for some of my programs so I created a 
PreferenceTrees enum. It has only two values, SYSTEM and USER. My 
PreferenceUtils class uses PreferenceTrees as a type in all of its 
methods so that someone invoking those methods can ONLY choose 
PreferenceTrees.SYSTEM or PreferenceTrees.USER, there's no possibility 
that someone is going to misspell "System", which could certainly happen 
if the method was expecting a String parameter. The PreferencesTree enum 
is trivial and seems unlikely to ever blow up.

But if an enum did more complicated logic, like looking up a day number 
and turning it into a day name in a foreign language, then sure, I can 
see that something might go awry and justify logging. The logic that 
looks up how to say "Monday" in Latvian or Turkish could throw an 
exception that should be logged. But my enums are mostly like the 
PreferenceTrees enum that I mentioned.


>>>> 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.
>
Some people call these data classes too, if I'm not mistaken. I find that 
a bit more descriptive but maybe that's just me.
 
>>>> 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.
> 
Absolutely. I'm just trying to think along the same lines as you've 
proposed in your posts. I hope I haven't made an unwarranted leap again.

>>>> 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?
>
See my remarks about enums above. The same would apply to a holder class. 
If it's a one line getter or setter, there's probably not much to go 
wrong and logging is probably inappropriate. But if it's doing something 
that could fail, sure, logging would make sense.  

>>>> 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.
>
Understood. I'm just extrapolating the general principle that you've been 
stating, which I would paraphrase (roughly) as "don't do anything 
slavishly or unnecessarily; do it because it makes sense to do it".
 
>>>> 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.
> 
I have had very little contact with operators in the PC era but I did 
have some in my mainframe days. Back then, they didn't have a lot to do 
with fixing the problems in the sense of repairing the code. Their job 
was basically to figure out which program had bombed and then look that 
up in their list so they knew which programmer to call. 

Would I be right in assuming that it's pretty much the same situation 
today in a massively PC-oriented world? Or have they assumed many new 
responsibilities?

It would help a lot to know what they hope to find in a log. 

If they still operate like they did in my mainframe days, I expect they 
pretty much just want to know which program failed so they can look up 
the on-call programmer's name. They won't care about most details, 
although they might like to be able to tell the programmer "Program Foo 
crashed on an IllegalArgumentException in the constructor for class 
FooMainPanel" as opposed to just "Program Foo crashed". They won't care 
about stacktraces or such things. But the programmer is going to care a 
lot about the stacktraces and other information!

But maybe modern operators do a lot more than that. You seem very 
familiar with what they do so this would be a great chance to get your 
insight on this.


>>> 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. 
> 
Interesting. I'm going to need to imitate that...

>>> 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. 
>
That's why I was displaying the name of the table so I'm going to take 
that as a "yes" ;-)
 
> 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).
> 
I don't touch hashCode(), equals() or compareTo() very often at all. Or 
toString() either for that matter. But overriding hashCode() and equals() 
solved a big problem for me recently. I was writing a holder class that 
contained three fields, a table name, a row number and a column number, 
as a key for a hash map and then storing the column width in the value 
portion of the map. But when I tried to look up a given combination of 
table name, row number and column number I was never finding values that 
I knew were there. I googled and found out that I needed to revise 
hashCode() and equals() and rougly what those changes needed to be and 
then my lookups went fine. But I didn't touch compareTo(). Hmm, maybe I 
need to revisit that and make sure it doesn't need some tweaking too....

-- 
Novice

Back to comp.lang.java.programmer | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

Additional logging questions Novice <novice@example..com> - 2012-02-27 02:02 +0000
  Re: Additional logging questions Arne Vajhøj <arne@vajhoej.dk> - 2012-02-26 21:08 -0500
    Re: Additional logging questions Novice <novice@example..com> - 2012-02-27 04:12 +0000
      Re: Additional logging questions Lew <noone@lewscanon.com> - 2012-02-26 22:13 -0800
        Re: Additional logging questions Novice <novice@example..com> - 2012-02-27 19:14 +0000
          Re: Additional logging questions Lew <noone@lewscanon.com> - 2012-02-27 12:32 -0800
          Re: Additional logging questions Lew <noone@lewscanon.com> - 2012-02-27 13:06 -0800
            Re: Additional logging questions Novice <novice@example..com> - 2012-02-28 01:48 +0000
              Re: Additional logging questions Arne Vajhøj <arne@vajhoej.dk> - 2012-02-27 20:57 -0500
                Re: Additional logging questions Lew <noone@lewscanon.com> - 2012-02-27 23:51 -0800
          Re: Additional logging questions Arne Vajhøj <arne@vajhoej.dk> - 2012-02-27 20:50 -0500
            Re: Additional logging questions Lew <noone@lewscanon.com> - 2012-02-27 23:57 -0800
        Re: Additional logging questions Arne Vajhøj <arne@vajhoej.dk> - 2012-02-27 20:45 -0500
          Re: Additional logging questions Leif Roar Moldskred <leifm@dimnakorr.com> - 2012-02-28 01:52 -0600
            Re: Additional logging questions Arne Vajhøj <arne@vajhoej.dk> - 2012-02-28 17:20 -0500
            Re: Additional logging questions Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-02-28 20:26 -0400
      Re: Additional logging questions Arne Vajhøj <arne@vajhoej.dk> - 2012-02-27 20:34 -0500
  Re: Additional logging questions Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2012-02-27 12:36 -0800
    Re: Additional logging questions Novice <novice@example..com> - 2012-02-28 01:43 +0000

csiph-web