Re: Aspect questions?
Novice wrote:
Lew wrote:
Novice wrote:
Lew wrote:
Novice wrote:
Lew wrote:
Logging is a great use case for aspects. However, there are
alternatives to lessening logging's overhead, too. You have to
weigh costs and benefits.
What are other good ways to do logging?
log4j is my favorite.
Right now, the two main programs in my current project each create
their own logger and then pass it to the classes they call in their
parameters.
I don't think that's a good pattern. Which logging library are you
using?
I'm using Java Logging. Does that answer your question or are you
asking something else?
I have each class create its own logger (log4j style shown:
package eegee;
import org.apache.log4j.Logger;
import static org.apache.log4j.Logger.getLogger;
public class Foo
{
final Logger logger = getLogger(getClass());
public void foo()
{
logger.debug("");
// do the fooey stuff
try
{
// do the trying stuff
}
catch (FooException exc)
{
String msg = "trying stuff failed. "+
exc.getLocalizedMessage(); logger.error(msg, exc);
throw new IllegalStateException(msg, exc);
}
}
}
This boilerplate is what aspects aim to remove from the code and I
espouse retaining.
My code is not terribly different than that.
Actually, what you do is different and some of that difference is
terrible.
Why aren't you logging the exceptions?
Because this is the code that creates the logger. If it fails to create
the logger, where would you like me to log the exception?
Yeah, I figured that out after the fact. You were doing a weird thing by
creating a factory method to call the factory method to create the logger.
And what you are doing here is radically different from what I
proposed, hardly at all similar in any respect. I don't understand why
you think it's similar.
Okay, maybe it's completely different then. I thought it was the same
spirit.
No. The difference is that I put the logger code in each class, and don't have
a centralized factory factory. That's because the logging framework already
provides a factory and a way to configure it, so I don't try to reinvent that
entire mechanism.
Here's the actual code minus the Javadoc comment:
================================================================
public static Logger configureLogger(String className, String
logFilePath, String logFileName, Locale locale, Formatter formatter,
Level loggingLevel) {
My goodness, don't use TABs! Especially not in Usenet posts!
Sorry.
This use of a separate logger factory that takes over what the logging
framework already does is, well, curious.
String METHOD_NAME = "configureLogger()"; //$NON-NLS-1$
You don't need this, and if you did it should be 'final' and named
according to the Java coding conventions.
I thought final was irrelevant in a method and only made a difference for
instance variables?
It's not irrelevant, depending on what you think is relevant. It prevents
reassignment of the reference, and as a comment lets maintainers know the
intent is to have an immutable reference.
But you are correct that is actually wasn't so necessary here.
You're right about the case of the name. That should be methodName for a
method variable....
/* Ensure that the mandatory parameters have all been specified.
*/ if (className == null) {
throw new IllegalArgumentException("The name of the class
must
be provided."); //$NON-NLS-1$
You didn't log this!
Where would you like me to log this?
'logger.severe()' right at the point, just before the throw.
And those "$NON-NLS-1$" comments are highly distracting.
Sorry, I should have stripped them and the tabs out of the code first.
Actually, you should indent with spaces not TABs routinely. And strip out the
superfluous comments in your own code, too - that is, if they're actually
superfluous.
}
if (logFilePath == null) {
throw new IllegalArgumentException("The log file path must
be
provided."); //$NON-NLS-1$
}
if (logFileName == null) {
throw new IllegalArgumentException("The log file name must
be
provided."); //$NON-NLS-1$
}
if (locale == null) {
throw new IllegalArgumentException("The locale must be
provided."); //$NON-NLS-1$
}
/* Create the logger. */
Logger logger = Logger.getLogger(className);
/* Create path identified by logFilePath if it does not exist.
*/ File path = new File(logFilePath);
Really?
I can't go on. It's too painful.
Why? Telling me it's awful without saying why doesn't teach me anything.
I didn't stop there. I did say why.
I put that in a utility class in my Common project. Then any program
that wants a logger just executes this one method passing the
appropriate parameters.
You don't need that. You just call 'Logger.getLogger()'. The utility class is
a whole lot of weird complication that you don't need.
But, splutter, but, ... that's what the existing 'Logger.getLogger()'
method does!
You're doing everything by hand that the framework does for you!
So I just execute Logger.getLogger() and a logger will be magically
created that is exactly where I want it to be with exactly the file name
I want to ensure that it is in the right format, XML in my case and with
exactly the right logging level and handlers? I thought I had to do SOME
of the work to ensure I got what I wanted.
Yes, that is correct.
I realize that I could have each class create its own logger and log
but
Huh?
No!
would seem to guarantee a proliferation of logs that would be a pain
to find. It seems reasonable to me that if I have a bunch of
programs,
No, no, no, no.
You don't create multiple log files, one per class. Where did you get
that notion?
Huh? You seem to be contradicting yourself. Are you saying I should
create one logging file per class or not? And why have a separate logging
No. I never said nor implied that you should have one logging file per class.
That one's on you, brother.
file for each class? Isn't it more logical to have all the messages that
come from one program, say Foo, appear in the same log? Isn't the poor
Yes, but why are you arguing a point not in dispute?
Sysop going to be excessively busy if he has to check a separate log for
each and every one of the - hundreds? thousands? - of classes in the
system? Wouldn't it be more logical to group logs on the basis of which
application is invoking the class? Therefore, if method
getCurrentWeekdayName had problems while executing program Foo, the Foo
log would contain the information? Wouldn't the person running Foo be the
one that's notifying the SysOp that something screwy just happened while
running Foo? Then the name of the application would be a huge head start
in finding the problem: just look in the Foo log and all will be
revealed. Or at least enough to get started.
How you do go on.
No one is suggesting anything like that scenario. so cool your jets, Cadet!
Wow.
You set up the logging in the configuration file. Done. Simple.
What configuration file? I'm not sure what you mean. First, I'm not sure
what you mean by a configuration file. Second, are you saying that all
applications will normally have a configuration file? I don't remember
coming across those in the Java Tutorial, for example, or even seeing
them mentioned in this newsgroup.
A configuration file is a file that contains configuration information.
As far as what you don't remember, if you follow the link from the API docs
for java.util.logging:
<http://docs.oracle.com/javase/7/docs/api/java/util/logging/package-summary.html>
You come across a recommendation to read the introduction to Java logging,
which I sure hope you followed:
"Related Documentation
For an overview of control flow, please refer to the Java Logging Overview."
which links you to
<http://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html>
wherein you would have read, had you read it,
<http://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html#a1.15>
"The APIs are structured so that an initial set of configuration information
is read as properties from a configuration file."
As for the tutorials, you have
<http://lmgtfy.com/?q=Java+logging+tutorial>
which among other links will find you
<http://forward.com.au/javaProgramming/javaGuiTips/javaLogging.html>
that covers a little about the "logging.properties" file.
If this is some routine thing that professional developers do, great. I
obviously need to know about it. Can you point me to a tutorial or
whatever that will explain what they are and how to create them?
GIYF, dude.
You are re-inventing the logging wheel. You said,
Goodness no! I am using the Java Logging classes to do my logging.
Sorry if that wasn't clear.
but you aren't using it correctly. What you are doing is defeating the
built-in features and reinventing everything. Don't do that.
That was not my intention. I'm off to look at the logging classes again
and see how I can avoid reinventing the wheel. I'm really not seeing why
you say that yet. I'm using the standard Java Logging classes. I've
Abusing
tweaked the properties file that governs logging a little bit to get the
Huh. That's the configuration file, dude.
effect that I wanted and I created my own variant on the XMLFormatter
that is only very slightly different. Aside from that, I'm using the
vanilla logging classes. I'm not sure how that constitutes reinventing
the framework. But, as I said, I'm going to review the logging classes
now and see if I'm overcomplicating the creation of the logger as you
say. Perhaps I am....
The properties file specifies the log file, the log level (by type if you so
choose), the output format, whether you report the class and method being
logged - all the things you did manually in your utility class.
And when I said you should know both ju.logging and log4j, somehow you
inferred that to mean that you should use both in the same program.
Such leaps you make! Settle back and stick with inferences that
actually follow from what I say.
Well, here's the exact quote:
"Use log4j or java.util.logging (OR BOTH)". [emphasis added]
Not in the same code! Yeesh.
....
As I've said, I'm a one man Java shop in a town that doesn't seem to do
much Java. I don't work in a professional Java shop so I have no
professional Java code to look at or peers to learn from. So I'm
floundering. That's why this newsgroup is important to me. I _AM_ trying
to get better at this....
Of course, hence the detailed feedback.
--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg