Purpose - to provide an api for debug log and trace messages.
The purpose of debug log and trace messages is: To provide a mechanism that allows the developer to enable output of minor events focused on a specific problem area and to follow what is going on inside ArgoUML.
The Logging is located in org.argouml.???
The Logging is a Layer 0 subsystem.
Logging is currently implemented using log4j.
ArgoUML uses the standard log4j logging facility. The following sections deal with the current implementation in ArgoUML. By default, logging is turned off and only the version information of all used libraries are shown on the console.
Logging entries in log4j belong to exactly one level.
The FATAL level designates very severe error events that will presumably lead the application to abort. Everything known about the reasons for the abortion of the application shall be logged.
The ERROR level designates error events that might still allow the application to continue running. Everything known about the reasons for this error condition shall be logged.
The WARN level designates potentially harmful situations. This is if CG can't find all the information required and has to make something up.
The INFO level designates informational messages that highlight the progress of the application at coarse-grained level. This typically involves creating modules, subsystems, and singletons, loading and saving of files, imported files, opening and closing files.
The DEBUG Level designates fine-grained informational events that are most useful to debug an application. This could be everything happening within the application.
This list is ordered according to the priority of these logging entries i.e. if logging on level WARN is enabled for a particular class/package, all logging entries that belong to the above levels ERROR and FATAL are logged as well.
For performance reasons, it is advised to do a check before frequently passed DEBUG and INFO log4j messages (see Example 5.2, “Improving on speed/performance”). The purpose of this test is to avoid the creation of the argument.
You should not use
System.out.println
in
ArgoUML
Java Code.
The only exception of this rule is for output in non-GUI mode
like to print the usage message in Main.java
.
To make log entries from within your own classes, you just need to follow the three steps below:
Import the org.apache.log4j.Logger class
Get a Logger
Start Logging...
Example 5.1. For log4j version 1.2.x
import org.apache.log4j.Logger; ... public classtheClass
{ ... private static final Logger LOG = Logger.getLogger(theClass
.class); ... public void anExample() { LOG.debug("This is a debug message."); LOG.info("This is a info message."); LOG.warn("This is a warning."); LOG.error("This is an error."); LOG.fatal("This is fatal. The program stops now working..."); }
Notice that we in the ArgoUML project have decided to have all loggers private static final with a static initializer. The reason for making them private is that this reduces the coupling between classes i.e. there is no risk that one class uses some other class' Logger to do logging. The reason for making them static is that our classes are more or less all either lightweight, like a representation of an object in the model, or a singleton. For the lightweight classes, having a reference to a logger object per object is a burden and for the singleton objects it doesn't care if the logger is static or not. The reason for making this final is that it shall never be modified by the class. The reason for having a static initializer is that then all classes can do this in the same way and we don't ever risk to forgot to create the Logger.
For performance reasons, a check before the actual logging statement saves the overhead of all the concatenations, data conversions and temporary objects that would be created otherwise. Even if logging is turned off for DEBUG and/or INFO level.
Example 5.2. Improving on speed/performance
if (LOG.isDebugEnabled()) { LOG.debug("Entry number: " + i + " is " + entry[i]); } if (LOG.isInfoEnabled()) { LOG.info("Entry number: " + i + " is " + entry[i]); }
![]() | Warning |
---|---|
Since this has a big impact also on the readability, only use it where it is really needed (like places passed several times per second or hundreds of times for every key the user presses). |
For more information go to the log4j homepage at http://jakarta.apache.org/log4j.
Most of the log statements passed in ArgoUML are passed with logging turned off. This means that the only thing log4j should do is to determine that logging is off and return. Log4j has a really quick algorithm to determine if logging is on for a certain level so that is not a problem.
The problem is instead explained by noticing the following log statement:
int i; ... LOG.debug("Entry number: " + i + " is " + entry[i]);
It is quite innocent looking isn't it? Well that is because the java compiler is very helpful when it comes to handling strings and will convert it to the equivalent of:
StringBuffer sb = new StringBuffer(); sb.append("Entry number: "); sb.append(i); sb.append(" is "); sb.append(entry[i].toString()); LOG.debug(sb.toString());
If the entry[i] is some object with a lot of calculations
when toString() is called and the logging statement is passed
often some action needs to be taken.
If the toString() methods are simple you are still
stuck with the overhead of creating a StringBuffer
(and a String
from the sb.toString()-statement.
log4j uses the command line parameter
-Dlog4j.configuration = URL
to configure itself where URL points to the location of
your log4j configuration file.
Example 5.3. Various URLs
org/argouml/resource/filename.lcfhttp://localhost/shared/argouml/filename.lcf
file://home/username/filename.lcf
![]()
There are currently two possibilities of running ArgoUML from the command line:
Run ArgoUML using
argouml.jar
Run ArgoUML using the ant script
In the first case, the configuration file is specified
directly on the command line, whereas in the latter
case this parameter is specified in the
build.xml
(which in that case
needs to be modified).
ArgoUML is then started as
usual with ./build run.
Example 5.4. Command Line for argouml.jar
[localhost:~] billy% java -Dlog4j.configuration=URL -jar argouml.jar
Example 5.5. Modification of build.xml
<!-- =================================================================== -->
<!-- Run ArgoUML from compiled sources -->
<!-- =================================================================== -->
<target name="run" depends="compile">
<echo message="--- Executing ${Name} ---"/>
<!-- Uncomment the sysproperty and change the value if you want -->
<java classname="org.argouml.application.Main"
fork="yes"
classpath="${build.dest};${classpath}">
< sysproperty key="log4j.configuration"
value="org/argouml/resource/filename.lcf"></sysproperty>
</java>
</target>
To view the console output, the WebStart user has to
set Enable Java Console
in the
Java WebStart preferences. In the same dialog, there
is also an option to save the Console Output to a
file.
As you cannot provide any userspecific parameters to a WebStart Application from within WebStart, it is currently not possible to choose log4j configuration when running ArgoUML from Java Web Start.
At the time of writing this paragraph, it is not possible to set the logging configuration file on a per project basis in NetBeans. Instead, the Global Options of [Debbuging and Execution/Execution Types/External Execution/External Process] need to be changed.
There are some sample configuration files provided in
org.argouml.resource
. Modify these according
to your needs.
Or alternatively, you can try
configLog4j to assist yourself in creating a log4j configuration file.
The log4j project homepage at http://jakarta.apache.org/log4j
The configlog4j homepage at http://www.japhy.de/configLog4j