Home of: [Atelier "FUJIGURUMA"] >> [PTLog hosted by SourceForge.net]

SEE "For Readers of English Version",
or Japanese version of this page

Format values

This section explains how to format specified values.

Please see also classes belonging to basic.format package of demonstration implementation.

Overview

Class names

In this tutorial, abbreviated class names are used. Complete names are shown below.

Classes of PTLog

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

Specify formatter per request

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"
    }

Specify formatter per request

Please see "Default*" classes in jp.ne.dti.lares.foozy.ptlog.format package for detail about pre-defined formatting instance.

Specify formatter per data type

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);
    }
}

Specify formatter per data type

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);
    }
}

Customize 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);
            }
        });
    }
}

Hook listener into 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.

Specify default formatter

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);
    }
}

Define custom UniversalFormatter

Please see "Specify formatter per data type" about how to specify custom formatter as initial one for your LogTaps.

Specify formatter per Log/LogBuffer

You 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);
        ....
    }

Specify formatter per Log/LogBuffer

Please 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.


To next section "Customize log type"