MAP | PTLog Documents > Tutorial > PTLog Basic > Write client code | << | >> |
This section explains how to write client code of logging request.
Please see also classes belonging to basic.client package of demonstration implementation.
In this tutorial, abbreviated class names are used. Complete names are shown below.
Notation | Full name |
---|---|
Log | jp.ne.dti.lares.foozy.ptlog.Log |
LogBuffer | jp.ne.dti.lares.foozy.ptlog.LogBuffer |
LogTap | jp.ne.dti.lares.foozy.ptlog.LogTap |
WriterProvider | jp.ne.dti.lares.foozy.ptlog.writer.WriterProvider |
LogTap
At first,
you should create LogTap
for convenience.
public class Client { .... final static public LogTap TAP = new LogTap(Client.class, WriterProvider.STDOUT); }
LogTap
is almost equivalent to
Logger
of JDK logging API(or Apache Log4j).
The former parameter of constructor is the "subject" of logging request. This is used to identify logging request issuer.
The later parameter specifies underlying logging framework.
In this case,
"WriterProvider.STDOUT
" means that
logging request is written out to standard out initially.
Please see "Plug into logging framework" for detail about the later parameter.
Log
Now you can issue logging request
via Log
gotten from LogTap
.
For example:
public void doSomething(){ Log log = TAP.getLog("doSomething"); log.info("log with INFO type"); log.dump("log with DUMP type"); try{ .... .... } catch(Exception e){ log.error("log with ERROR type", e); } }
Parameter of LogTap#getLog()
means
name of method in which logging request is issued.
Log
has some "type"s to accept logging request:
type | corresponded level/method | ||
---|---|---|---|
JDK logging API | Apache Log4j | JCL(*1) | |
fatal | SEVERE(1000) | FATAL(50000) | fatal |
error | SEVERE(1000) | ERROR(40000) | error |
warn | WARNING(900) | WARN(30000) | warn |
info | INFO(800) | INFO(20000) | info |
config | CONFIG(700) | INFO(20000) | info |
dump | FINE(500) | DEBUG(10000) | debug |
trace | FINER(400) | TRACE(5000)(*2) | trace(*3) |
---(*4) | FINEST(300) | --- | --- |
(*1) is used as abbreviation of "Jakarta Common Loggings" in this tutorial.
(*2) is supported since Log4j 1.2.12.
(*3) uses "DEBUG"(in Log4j environment) or "FINEST"(in JDK Logging API environment), according to JCL 1.0.x.
(*4) can be enabled by type conversion.
Each "type"s have three signature variations in Log
class.
public void <type>(String message, Throwable throwable); public void <type>(Object data); public boolean enables<Type>();
First of them is generic form like other logging frameworks
(such as JDK logging API, Log4j and JCL).
You can specify "null" as message
and/or throwable
.
Second of them is used to log any data including Throwable
.
This is usefull if you want to write out
only one of String
or Throwable
.
Third of them is used to examine whether logging request of such "type" is enabled or not. For example:
public void doSomething(){
Log log = TAP.getLog("doSomething");
if(log.enablesDump()){
log.dump("log with DUMP type");
}
}
Block under "log.enablesDump()
" condition is executed
only when "dump" is enabled.
Such condition may be changed dynamically in runtime.
This examination is usefull when information gatherring is too expensive to do it always.
In addition to them, three more variations are defined for "trace" type.
public void doSomething(){ Log log = TAP.getLog("doSomething"); log.enter(); // means method entry .... log.pass("initialize phase - 1"); .... log.pass("initialize phase - 2"); .... log.pass("initialize phase - 3"); .... .... log.exit(); // means method exit }
Each methods shown in above example are
replacable by "Log#trace
" method,
but these methods provide uniform ways
to request(and format) "trace" logging.
And, shortness of method invocation code is important, is not it?
LogBuffer
In my experience, parameter output is one of major purposes of logging, and there are two styles to request logging.
One of them is "concatenation" style.
public void doSomething(int p1, int p2, int p3, ....){ Log log = TAP.getLog("doSomething"); log.dump("p1=" + p1 + "/p2=" + p2 + "/p3=" + p3 + .....); }
The other of them is "separation" style.
public void doSomething(int p1, int p2, int p3, ....){ Log log = TAP.getLog("doSomething"); log.dump("p1=" + p1); log.dump("p2=" + p2); log.dump("p3=" + p3); .... }
In "concatenation" style, you can get parameter output in one log record, but client code of logging request is not elegant.
In "separation" style, you should gather information from logging output, because parameter output is splitted into some log records.
PTLog solves this by LogBuffer
.
public void doSomething(int p1, int p2, int p3, ....){ Log log = TAP.getLog("doSomething"); LogBuffer dump = log.forDump(); dump.add("p1", p1); dump.add("p2", p2); dump.add("p3", p3); .... dump.flush(); // requests logging }
In above example,
logging request is issued in "dump" type
at LogBuffer#flush()
invocation.
LogBuffer
concatenates
names and values of parameters.
When corresponded "type" is disabled to log,
Log#for<Type>()
methods return
LogBuffer
implementation
which does nothing at any method invocations.
So you do not have to examine by Log#enables<Type>()
unless any of parameters have expensive Object#toString
or
number of parameters is very big.
MAP | PTLog Documents > Tutorial > PTLog Basic > Write client code | << | >> |