Logging Module

Version 21.1 by Thomas Mortagne on 2014/06/17 18:18

cogAllows to easily manipulate logging
TypeJAR
Category
Developed by

XWiki Development Team

Rating
0 Votes
LicenseGNU Lesser General Public License 2.1
Bundled With

XWiki Enterprise, XWiki Enterprise Manager

Description

This module allows any component to manipulate logs in the following way:

  • receive logs as events
  • isolate log in for a specific task without it to appear in the standard log

The user interface documentation can be found on Logging Application.

This module is not about logging from Components. For that see the Component Module.

Features

Logs as events

To receive log a component can listen to org.xwiki.logging.event.LogEvent events. See Observation Module for more details on how to listen to events.

import org.xwiki.logging.LogLevel;
import org.xwiki.logging.event.AbstractLogEventListener;
import org.xwiki.observation.event.Event;

@Component
@Named("MyLogListener")
@Singleton
public class MyLogListener extends AbstractLogEventListener
{
   @Override
   public String getName()
   {
       return "MyLogListener";
   }

   @Override
   public void onEvent(Event event, Object source, Object data)
   {
        LogEvent logEvent = (LogEvent) event;

       if (logEvent.getLevel() == LogLevel.ERROR) {
            System.err.println(logEvent.getFormattedMessage());
       } else if (logEvent.getLevel() == LogLevel.WARN) {
            System.err.println(logEvent.getFormattedMessage());
       } else if (logEvent.getLevel() == LogLevel.INFO) {
            System.out.println(logEvent.getFormattedMessage());
       } else if (logEvent.getLevel() == LogLevel.DEBUG) {
            System.out.println(logEvent.getFormattedMessage());
       } else if (logEvent.getLevel() == LogLevel.TRACE) {
            System.out.println(logEvent.getFormattedMessage());
       }
   }
}

Log isolation

Sometime for a specific task you want to report detailed log to the user of the UI but don't want to pollute the system log. For this you can use org.xwiki.logging.LoggerManager default component.

It provide way to push and pop overwriting log receiver as event listener.

Here is an example:

LogQueue queue = new LogQueue();

loggerManager.pushLogListener(new LogQueueListener("loglistenerid", queue));
logger.error("Some application error happen");
loggerManager.popLogListener();

Manipulate loggers log level

It's possible to get or modify all registered loggers.

Get all registered loggers

  Collection<Logger> loggers = loggerManager.getLoggers();

Set log level

The following example set the level DEBUG to org.xwiki package and all sub-packages (unless one of the sub-packages override it).

  loggerManager.setLoggerLevel("org.xwiki", LogLevel.DEBUG)

Get log level

The following example return the log level of the package org.xwiki.

  loggerManager.getLoggerLevel("org.xwiki")

Translate log

since 5.0M2

It's possible to provide a translation key when logging, using SLF4J's Marker support. That allows logging listeners (classes extending org.xwiki.logging.event.AbstractLogEventListener for example) receiving logging events (org.xwiki.logging.event.LogEvent) to be able to get that information and use a localization framework to convert the translation key to the translated version.

Log producer example:

  logger.error(new TranslationMarker("someapplication.error"), "Some application error happen");

since 5.4

Log displayer example:

  #set($translatedLogEvent = $services.logging.translate($logEvent))
  $translatedLogEvent.formattedMessage

Log tree

since 5.4

It's possible to organize a set of logs as a tree using org.xwiki.logging.event.LogEvent#MARKER_BEGIN and org.xwiki.logging.event.LogEvent#MARKER_END markers.

  logger.info(LogEvent.MARKER_BEGIN, "Start some task");
  logger.error("Failed to do part of the task");
  logger.info(LogEvent.MARKER_END, "Task is done but failed");

  logger.info(LogEvent.MARKER_BEGIN, "Start a different task");
  logger.info(LogEvent.MARKER_END, "Task has ended well");

You can use org.xwiki.logging.LogTree to properly interpret such a log and get helpers to navigate into the tree.

The logging ScriptService also provide a helper to convert a log list into a tree:

#set($logtree = $services.logging.toLogTree($logs))

Supported implementations

To provide theses feature this module actually need to have specific support for each logging system because there is no way at the SLF4J level to catch logs and setup actual loggers. Right now only Logback is supported but should not be too hard to add support for other systems like Log4j for example.

Scripting

A org.xwiki.script.service.ScriptService is provided with the name logging.

Get a Logger from script

You can ask for a proper Logger using Logger getLogger(String name)

$services.logging.getLogger('My script').info('Hello {}', 'world')
Tags:
Created by Thomas Mortagne on 2018/11/19 15:33
    

Get Connected