de.decidr.model.logging.DefaultLogger.java Source code

Java tutorial

Introduction

Here is the source code for de.decidr.model.logging.DefaultLogger.java

Source

/*
 * The DecidR Development Team licenses this file to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package de.decidr.model.logging;

import org.apache.log4j.Appender;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

/**
 * Provides a common logging configuration for the DecidR components and
 * subsystems.
 * <p>
 * XXX use JDBC appender instead of or in addition to console appender, add
 * support for remotely triggered log level changes. See
 * http://www.dankomannhaupt.de/projects/index.html for an improved JDBC
 * appender.
 * 
 * @author Daniel Huss
 * @author Daniel Willig
 * @version 0.1
 * 
 */
public class DefaultLogger {

    private static final String DEFAULT_LOGGER = "de.decidr";
    private static final String HIBERNATE_LOGGER = "org.hibernate";
    private static final String JAXB_LOGGER = "com.sun.xml.bind";
    private static final String BEANUTILS_LOGGER = "org.apache.commons.beanutils";

    private static boolean initialized = false;

    private static Appender defaultAppender = new ConsoleAppender(
            new PatternLayout("[%-5p: %d{dd.MM. HH:mm:ss}] %m%n"), ConsoleAppender.SYSTEM_OUT);

    static {
        // run configurator - every new logger will inherit the defaultAppender
        BasicConfigurator.resetConfiguration();
        BasicConfigurator.configure(defaultAppender);

        /*
         * The default log level _before_ the system settings are retrieved is
         * "WARN". If the system settings cannot be retrieved, the default log
         * level is "DEBUG". The log level for JAXB and Hibernate is hardcoded
         * to "WARN" to make the debug logs smaller.
         */
        Logger.getLogger(HIBERNATE_LOGGER).setLevel(Level.WARN);
        Logger.getLogger(JAXB_LOGGER).setLevel(Level.WARN);
        Logger.getLogger(BEANUTILS_LOGGER).setLevel(Level.WARN);

        // configure the default logger
        Logger defaultLogger = Logger.getLogger(DEFAULT_LOGGER);
        defaultLogger.addAppender(defaultAppender);
        // don't pass messages to higher-level loggers
        defaultLogger.setAdditivity(false);
        Level globalLogLevel = Level.DEBUG;
        try {
            globalLogLevel = getGlobalLogLevel();
        } catch (Exception e) {
            globalLogLevel = Level.DEBUG;
            defaultLogger.warn("Cannot retrieve global log level from database.", e);
        }

        defaultLogger.setLevel(globalLogLevel);

        initialized = true;
    }

    /**
     * Private constructor to prevent instantiation.
     */
    private DefaultLogger() {
        // Nothing needs to be done here.
    }

    /**
     * Fetches the global log level from the database.
     * 
     * (we cannot instantiate any transaction coordinator because it might use
     * the default logger, creating a cyclic dependency)
     * 
     * @return log level
     */
    private static Level getGlobalLogLevel() {
        Level result = Level.DEBUG;
        Session session = null;
        SessionFactory sessionFactory = null;
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
            session = sessionFactory.openSession();

            Transaction tx = session.beginTransaction();
            try {
                result = Level.toLevel((String) session.createQuery("select s.logLevel from SystemSettings s")
                        .setMaxResults(1).uniqueResult());
                tx.commit();
            } catch (Throwable t) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                try {
                    session.close();
                } catch (Throwable t) {
                    // ignore
                }
            }
            if (sessionFactory != null) {
                try {
                    sessionFactory.close();
                } catch (Throwable t) {
                    // ignore
                }
            }
        }

        return result;
    }

    /**
     * Retrieve a logger named according to the full class name of the clazz
     * parameter. If the named logger already exists, then the existing instance
     * will be returned. Otherwise, a new instance is created.
     * 
     * @param clazz
     *            class whose full name should be used as the name of the
     *            returned logger
     * @return a logger that uses the name of the given class
     */
    public static Logger getLogger(Class<?> clazz) {
        return getLogger(clazz.getName());
    }

    /**
     * Retrieve a logger named according to the value of the name parameter. If
     * the named logger already exists, then the existing instance will be
     * returned. Otherwise, a new instance is created.
     * 
     * @param name
     *            The name of the logger to retrieve.
     * @return the named logger
     */
    public static Logger getLogger(String name) {
        return Logger.getLogger(name);
    }

    /**
     * @return whether the default logger has been initialized.
     */
    public static boolean isInitialized() {
        return initialized;
    }
}