How should I provide access to my logger?

F

Fencer

Hello, I've been tasked with implementing a logging feature to a program
consisting of maybe 100 classes. I've implemented the GUI side of this
feature (a window where this information will be displayed, it can go to
a file as well).
Now I'm wondering what the best way is to make my logger available to
the classes that needs to use it. I could add a parameter to the
constructors, I suppose, but that doesn't feel right to me. The whole
idea is to replace many System.out/err.println() calls that are
scattered throughout the code with this logging class.
The users of the logging class don't know or care if the logger just
writes to a file, and/or displays it in a special window or if it's even
turned of.
Maybe I could use a singleton as my logger? So when a class A wants to
log something it obtains a logger object and uses it. I want the user to
be able to change the behavior of the logging during runtime, and I
think I can do that with this approach. But since I'm not a seasoned
Java programmer I ask here for advice.
Also, this program is single-threaded, at least, I'm not creating any
new threads myself explicitly. I'm using Java 1.6.0_13.

- Fencer
 
M

Mike Schilling

Fencer said:
Hello, I've been tasked with implementing a logging feature to a
program consisting of maybe 100 classes. I've implemented the GUI
side of this feature (a window where this information will be
displayed, it can go to a file as well).
Now I'm wondering what the best way is to make my logger available
to
the classes that needs to use it. I could add a parameter to the
constructors, I suppose, but that doesn't feel right to me. The
whole
idea is to replace many System.out/err.println() calls that are
scattered throughout the code with this logging class.
The users of the logging class don't know or care if the logger just
writes to a file, and/or displays it in a special window or if it's
even turned of.
Maybe I could use a singleton as my logger? So when a class A wants
to
log something it obtains a logger object and uses it. I want the
user
to be able to change the behavior of the logging during runtime, and
I
think I can do that with this approach. But since I'm not a seasoned
Java programmer I ask here for advice.
Also, this program is single-threaded, at least, I'm not creating
any
new threads myself explicitly. I'm using Java 1.6.0_13.


Look into java.util.logging. You can use its Loggers to divide the
logged messages in two dimensions:

1. Type of message, which you accomplish by logging messages to
different instances of Logger.
2. Priority of message, which you accomplish by logging them at
different Levels.

The GUI you've written will be part of a Handler, that is, a class
that accepts a logged message and processes it in some fashion. As
you say, the client code just logs messages, and has no idea how (or
whether) they're displayed, saved to disk, etc. And that can be
changed that by editing a configuration file that determines which
Handlers are created.
 
G

Giovanni Azua

hi Fencer,

Fencer said:
[snip]
Now I'm wondering what the best way is to make my logger available to the
classes that needs to use it. I could add a parameter to the constructors,
I suppose, but that doesn't feel right to me. The whole idea is to replace
many System.out/err.println() calls that are scattered throughout the code
with this logging class.
[snip]
In most scenarios each class that need to log anything should have a static
final attribute that gets initialialized from some sort of logging
framework-specific Factory e.g. using slf4j:
private static Logger logger = LoggerFactory.getLogger(Foo.class);

But as you mentioned "scatter", if you replace the System.out.print by
whatever logging framework, logging is still scattered, you have better
control with logging frameworks but you will have tangled and scattered code
nevertheless. Logging is a non-functional concern that does not belong in
any class and in most cases will degrade quality metrics like LCOM (Lack of
Cohesion) and CBO (Coupling between Classes). I personally use logging
frameworks directly in my Java code but I am aware of these issues.

Now logging is the classic use-case for APO (Aspect Oriented Programming)
where you don't touch the java source code to add non functional concerns
but use Aspects. Google for "AspectJ and Logging" and you will find many
articles and examples related to this.

HTH,
Best regards,
Giovanni
 
L

Lew

Giovanni said:
Now logging is the classic use-case for APO [sic] (Aspect Oriented Programming)

I'm less enamored of the idea of AOP than some.
where you don't touch the java [sic] source code to add non functional concerns
but use Aspects. Google for "AspectJ and Logging" and you will find many
articles and examples related to this.

The trouble with AspectJ (and presumably other such) is that it rewrites the
class file for you. I know of one major production system that ran into
troubles with bugs in how AspectJ did bytecode rewriting.

I'm also somewhat dubious of how an aspect can capture all the right
information to log. With inline logging code, you have a context from which
you can cherry-pick what needs to be logged.

OTOH, I have yet to be in a project where they architected the logging aspect
as carefully (?) as they did the core code. Perhaps AspectJ is a good idea
compared to how people actually use logging, as opposed to how they should.
 
A

Arved Sandstrom

Fencer said:
Hello, I've been tasked with implementing a logging feature to a program
consisting of maybe 100 classes. I've implemented the GUI side of this
feature (a window where this information will be displayed, it can go to
a file as well).
Now I'm wondering what the best way is to make my logger available to
the classes that needs to use it. I could add a parameter to the
constructors, I suppose, but that doesn't feel right to me. The whole
idea is to replace many System.out/err.println() calls that are
scattered throughout the code with this logging class.
The users of the logging class don't know or care if the logger just
writes to a file, and/or displays it in a special window or if it's even
turned of.
Maybe I could use a singleton as my logger? So when a class A wants to
log something it obtains a logger object and uses it. I want the user to
be able to change the behavior of the logging during runtime, and I
think I can do that with this approach. But since I'm not a seasoned
Java programmer I ask here for advice.
Also, this program is single-threaded, at least, I'm not creating any
new threads myself explicitly. I'm using Java 1.6.0_13.

- Fencer

As others have indicated, examine existing logging frameworks carefully
to see if they do what you want - java.util.logging, then log4j, etc.

Having said that, I recently needed logging for a small app at work
where the log file rotation requirements were such that I could not,
noways, nohow, get either java.util.logging or log4j to make that part
happen. To this end I did write a single logging class which was a
singleton.

In my case the formatting requirements of log entries were very simple,
so the specialized logic to handle the twisted rotation requirements
accounted for about half the class. And as you may have gathered, execpt
for some special parameters like size of individual log files, and log
file location, the configuration of the logger never really changes in
my case.

In your case I would think you can probably use java.util.logging.

AHS
 
A

Arne Vajhøj

Lew said:
Giovanni said:
Now logging is the classic use-case for APO [sic] (Aspect Oriented
Programming)

I'm less enamored of the idea of AOP than some.
where you don't touch the java [sic] source code to add non functional
concerns but use Aspects. Google for "AspectJ and Logging" and you
will find many articles and examples related to this.

The trouble with AspectJ (and presumably other such) is that it rewrites
the class file for you. I know of one major production system that ran
into troubles with bugs in how AspectJ did bytecode rewriting.

AOP is a smart way of organizing source code - it is a not some magic
that allows you to make changes to an application without test.
I'm also somewhat dubious of how an aspect can capture all the right
information to log. With inline logging code, you have a context from
which you can cherry-pick what needs to be logged.

AOP has its limitations - the logging must match some relative
simple patterns.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top