This project has retired. For details please refer to its Attic page.
Logging
Zest™
Introduction
Tutorials
Javadoc
Samples
Core
Libraries
Extensions
Tools
Glossary 

Logging

code

docs

tests

First of all, Zest™ is taking a fresh look at all things that we take for granted. Logging is one such thing.

It should (but is not) obvious that Logging are used for three very distinct purposes, and in our opinion the concepts are not related and should not be abstracted in the same fashion, as has been the norm in Log4j, JDK logging, Commons Logging and most other similar packages and APIs.

Although similar in nature, the audience are very different in Logging vs Debugging/Tracing and their requirements are not only different, but if not handled properly the debug log is mixed up with the audit logs, which in turn can lead to turning off whole or parts of the domain logging by mistake. We want to avoid this, and instead crystalize the needs for each scenario and audience.

Another drastic difference from previous frameworks is that we don’t have an Appender notion. All messages are entities which are stored in a configured entity store. This means that especially the domain log can be more easily be given a user interface suitable for the domain, without complex parsing of message strings

Table 37. Artifact

Group IDArtifact IDVersion

org.qi4j.library

org.qi4j.library.logging

2.1


Logging

Logging is still not finalized and will need a lot more thought before considered done.

Debugging

To produce debugging output in your code you just need to add the field

@Optional @This Debug debug;

and then check for null at each usage

if( debug != null )
{
    debug.debug( Debug.NORMAL, "Debugging is made easier." );
}

The Debug mixin can be either added to the composite declaration, or it can be added as a contextual fragment during bootstrap.

You will also need to declare a DebugService to be visible to the composite where the debug output is coming from. And the DebugService in turn will use the default UnitOfWork and associated entity store, which must also be configured and visible.

Tracing

Tracing is the process of tracking all the methods that has been called. There are two levels of tracing available in Zest. Either Trace All or trace where a annotation has been given.

If the TraceAllConcern is added to a composite, and there is a TraceService visible, then all method calls into that composite is traced.

If a subset of the methods want to be traced, you can annotate those methods with @Trace in either the Composite Type interface or the mixin implementation. You will also need to add the TraceConcern to the composite.

public interface ImportantRepository
{
    @Trace
    void addImportantStuff( ImportantStuff stuff );

    @Trace
    void removeImportantStuff( ImportantStuff stuff );

    ImportantStuff findImportantStuff( String searchKey );
}

In the above sample code, the findImportantStuff() method is not traced, whereas the other two will be traced if there is a TraceConcern declared on the composite, and a TraceService visible from that composite.

The fact that each TraceConcern (and TraceAllConcern) will use the TraceService that is visible, allows you to enable or disable tracing per module, simply by adding or removing a TraceService with Visibility.module in each module you want it, or expose Visibility.layer and turn on/off tracing by layers. The TraceConcern has the TraceService as optional.

The recommended way to enable tracing is to use contexual fragments, a feature that allows you to add concerns, sideeffects and mixins to composites during the bootstrap phase instead of hard-coded into the composite declaration.

public void assemble( ModuleAssembly module )
        throws AssemblyException
{
    module.addServices(ImportantRepository.class)
            .withConcerns( TraceAllConcern.class )
            .withMixins( Debug.class );
}