org.eclipse.gyrex.logback.config.model.LogbackConfig.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.gyrex.logback.config.model.LogbackConfig.java

Source

/**
 * Copyright (c) 2012 Gunnar Wagenknecht and others.
 * All rights reserved.
 *
 * This program and the accompanying materials are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Gunnar Wagenknecht - initial API and implementation
 */
package org.eclipse.gyrex.logback.config.model;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.eclipse.gyrex.boot.internal.logback.LogbackConfigurator;

import org.apache.commons.lang.StringUtils;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.jul.LevelChangePropagator;

/**
 * Model object representing an entire Logback configuration which can be used
 * to generate the Logback XML.
 * <p>
 * Note, for simplicity the generation of the XML is tightly coupled to the
 * model. This might be an anti-pattern. Contributions to separate this are
 * welcome!
 * </p>
 */
public final class LogbackConfig extends LobackConfigElement {

    static void writeProperty(final XMLStreamWriter writer, final String name, final String value)
            throws XMLStreamException {
        writer.writeEmptyElement("property");
        writer.writeAttribute("name", name);
        writer.writeAttribute("value", value);
    }

    private Map<String, Appender> appenders;
    private Map<String, Logger> loggers;
    private boolean shortenStackTraces;
    private Level defaultLevel;
    private List<String> defaultAppenders;

    public void addAppender(final Appender appender) {
        if (StringUtils.isBlank(appender.getName()))
            throw new IllegalArgumentException("appender name must not be blank");
        getAppenders().put(appender.getName(), appender);
    }

    private String addExceptionPattern(final String pattern) {
        if (isShortenStackTraces())
            return pattern + "%rootException{6}";
        else
            return pattern + "%rootException";
    }

    public void addLogger(final org.eclipse.gyrex.logback.config.model.Logger logger) {
        if (StringUtils.isBlank(logger.getName()))
            throw new IllegalArgumentException("logger name must not be blank");
        getLoggers().put(logger.getName(), logger);
    }

    public Map<String, Appender> getAppenders() {
        if (null == appenders) {
            appenders = new LinkedHashMap<String, Appender>();
        }
        return appenders;
    }

    public List<String> getDefaultAppenders() {
        if (null == defaultAppenders) {
            defaultAppenders = new ArrayList<String>();
        }
        return defaultAppenders;
    }

    /**
     * Returns the defaultLevel.
     * 
     * @return the defaultLevel
     */
    public Level getDefaultLevel() {
        if (null == defaultLevel)
            return Level.INFO;
        return defaultLevel;
    }

    public Map<String, Logger> getLoggers() {
        if (null == loggers) {
            loggers = new LinkedHashMap<String, Logger>();
        }
        return loggers;
    }

    private String getLongPattern() {
        return addExceptionPattern(
                "%date{ISO8601} [%thread.%property{HOSTNAME}] %-5level %logger{36} %mdc{gyrex.contextPath, '[CTX:', '] '}%mdc{gyrex.applicationId, '[APP:', '] '}%mdc{gyrex.jobId, '[JOB:', '] '}- %msg%n");
    }

    private String getShortPattern() {
        return addExceptionPattern(LogbackConfigurator.DEFAULT_PATTERN);
    }

    public boolean isShortenStackTraces() {
        return shortenStackTraces;
    }

    public void setDefaultAppenders(final List<String> defaultAppenders) {
        this.defaultAppenders = defaultAppenders;
    }

    /**
     * Sets the defaultLevel.
     * 
     * @param defaultLevel
     *            the defaultLevel to set
     */
    public void setDefaultLevel(final Level defaultLevel) {
        this.defaultLevel = defaultLevel;
    }

    public void setShortenStackTraces(final boolean shortenStackTraces) {
        this.shortenStackTraces = shortenStackTraces;
    }

    /**
     * Serializes the Logback configuration to the specified XML writer.
     * <p>
     * The XML is expected to be readable by Logback. As such, it depends
     * heavily on Logback and may be bound to different evolution/compatibility
     * rules.
     * </p>
     * 
     * @param writer
     *            the stream writer
     * @throws XMLStreamException
     */
    @Override
    public void toXml(final XMLStreamWriter writer) throws XMLStreamException {
        writer.writeStartDocument();

        writer.writeStartElement("configuration");
        writer.writeAttribute("scan", "true");
        writer.writeAttribute("scanPeriod", "2 minutes");

        writeCommonProperties(writer);
        writeJulLevelChangePropagator(writer);

        for (final Appender appender : getAppenders().values()) {
            appender.toXml(writer);
        }
        for (final Logger logger : getLoggers().values()) {
            logger.toXml(writer);
        }

        writeRootLogger(writer);

        writer.writeEndElement();

        writer.writeEndDocument();
    }

    private void writeCommonProperties(final XMLStreamWriter writer) throws XMLStreamException {
        writer.writeComment("common properties");
        writeProperty(writer, "BASE_PATH", "${gyrex.instance.area.logs:-logs}");
        writeProperty(writer, "PATTERN_SHORT", getShortPattern());
        writeProperty(writer, "PATTERN_LONG", getLongPattern());
    }

    private void writeJulLevelChangePropagator(final XMLStreamWriter writer) throws XMLStreamException {
        writer.writeComment("propagate log level changes to JUL");
        writer.writeStartElement("contextListener");
        writer.writeAttribute("class", LevelChangePropagator.class.getName());
        {
            writer.writeStartElement("resetJUL");
            writer.writeCData("true");
            writer.writeEndElement();
        }
        writer.writeEndElement();
    }

    private void writeRootLogger(final XMLStreamWriter writer) throws XMLStreamException {
        writer.writeStartElement("root");
        writer.writeAttribute("level", getDefaultLevel().toString());
        for (final String appenderRef : getDefaultAppenders()) {
            writer.writeEmptyElement("appender-ref");
            writer.writeAttribute("ref", appenderRef);
        }
        writer.writeEndElement();
    }

}