| MAP | PTLog Documents > Tutorial > PTLog Basic > Format values | << | >> |
This section explains how to format specified values.
Please see also classes belonging to basic.format package of demonstration implementation.
In this tutorial, abbreviated class names are used. Complete names are shown below.
| Notation | Full name |
|---|---|
| DefaultIntFormatter | jp.ne.dti.lares.foozy.ptlog.format.DefaultIntFormatter |
| DefaultUniversalFormatter | jp.ne.dti.lares.foozy.ptlog.format.DefaultUniversalFormatter |
| IntFormatter | jp.ne.dti.lares.foozy.ptlog.format.IntFormatter |
| Log | jp.ne.dti.lares.foozy.ptlog.Log |
| LogBuffer | jp.ne.dti.lares.foozy.ptlog.LogBuffer |
| LogDirector | jp.ne.dti.lares.foozy.ptlog.LogDirector |
| LogServer | jp.ne.dti.lares.foozy.ptlog.LogServer |
| LogTap | jp.ne.dti.lares.foozy.ptlog.LogTap |
| UniversalFormatter | jp.ne.dti.lares.foozy.ptlog.format.UniversalFormatter |
In the former section, code to log some values in one log record is shown.
In such cases,
you may want specified values to be formated in custom manner:
for example, int value formatted not in decimal but in hexdecimal.
You can specify format per request as shown below.
public void doSomething(int p1, int p2, int p3, ....){
Log log = TAP.getLog("doSomething");
LogBuffer dump = log.forDump();
dump.add("p1", p1);
// formats value in "signed decimal"
dump.add("p2", p2, DefaultIntFormatter.S_OCT);
// formats value in "Signed OCTal"
dump.add("p3", p3, DefaultIntFormatter.U_HEX);
// formats value in "Unsigned HEXdecimal"
}
Please see "Default*" classes in
jp.ne.dti.lares.foozy.ptlog.format package
for detail about pre-defined formatting instance.
You may also want specify format per data type as shown below.
public class Client
{
....
final static
public LogTap TAP =
new LogTap(Client.class, LogConfig.DIRECTOR);
static{
IntFormatter intFormatter = DefaultIntFormatter.U_HEX;
TAP.DEFAULT_FORMATTER.setIntFormatter(intFormatter);
}
}
DEFAULT_FORMATTER instance field is used as
default formatter of LogTap,
so you can configure LogTap
via DEFAULT_FORMATTER.
In above example,
you can configure only one LogClient#TAP at the same time.
There are two ways to configure plural LogTaps
at the same time.
One of them is to create your custom LogTap and use it.
For example:
public class CustomTap
extends LogTap
{
public CustomTap(Object subject, LogServer initialServer){
super(subject, initialServer);
IntFormatter intFormatter = DefaultIntFormatter.U_HEX;
DEFAULT_FORMATTER.setIntFormatter(intFormatter);
}
}
LogTap
The other of them is to hook listener into LogTap creation.
For example:
public class LogConfig
{
....
final static
public LogDirector DIRECTOR = new LogDirector();
static{
// this block is executed
// when LogConfig class is loaded.
// so "addListener" is done
// before creation of "LogTap"s
// which refer LogConfig#DIRECTOR.
LogTap.addListener(new LogTap.Listener(){
public void initialized(LogTap tap,
String subjectName,
Class level)
{
// ignore other taps than ones in your packages,
// if you want so.
if(!subjectName.startsWith("your.package.")){
return;
}
IntFormatter intFormatter = DefaultIntFormatter.U_HEX;
tap.DEFAULT_FORMATTER.setIntFormatter(intFormatter);
}
});
}
}
LogTap creation
Listeners hooked into LogTap are callback-ed
at each LogTap construction.
The former way is very simple and clear,
but forces you to invoke constructor of CustomTap.
Today, thanks to refacotring tools like Eclipse,
replacing constructor invocation of LogTap with
one of CustomTap in your application code
is not so difficult.
But such replacing in code of ohters is still difficult.
The later way is more complicated,
but this allows you to configure almost all LogTaps
even if they are "private" or in the application code of another.
NOTE:
Configurable LogTaps are not "all" but "almost all",
because you should register listener to configure LogTap.
There is no way to configure "private" LogTaps
created before your listener registration.
Value formatting in LogBuffer is
done by UniversalFormatter implementation class,
and you can set default implementation for your LogTap
by "#setFormatter(UniversalFormatter)" invocation
with your custom one.
As the first step of UniversalFormatter customization,
this tutorial shows example of the class derived from
DefaultUniversalFormatter
which is implementation class of UniversalFormatter.
public class CustomFormatter
extends DefaultUniversalFormatter
{
public CustomFormatter(){
super();
setIntFormatter(DefaultIntFormatter.U_HEX);
}
}
UniversalFormatter
Please see "Specify formatter per data type"
about how to specify custom formatter
as initial one for your LogTaps.
Log/LogBufferYou can also specify your custom formatter
per Log/LogBuffer as shown below.
public void doSomething(int p1, int p2, int p3, ....){
Log log =
TAP.getLog("doSomething", new CustomFormatter());
LogBuffer dump = log.forDump(new CustomFormatter());
dump.add("p1", p1);
....
}
Log/LogBufferPlease choose invocation metheds according to scope of format customization.
NOTE:
Above example code gives higer priority to code simpleness,
so invoke CustomFormatter constructor per invocation.
You should define "static"(and may be "final")
member field having own instance in CustomFormatter
for resource efficiency, if it is multi thread safe.
| MAP | PTLog Documents > Tutorial > PTLog Basic > Format values | << | >> |