All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tango.logging.LoggingManager Maven / Gradle / Ivy

There is a newer version: 10.0.0
Show newest version
/**
 * Copyright (C) :     2012
 *
 * 	Synchrotron Soleil
 * 	L'Orme des merisiers
 * 	Saint Aubin
 * 	BP48
 * 	91192 GIF-SUR-YVETTE CEDEX
 *
 * This file is part of Tango.
 *
 * Tango is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tango is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Tango.  If not, see .
 */
package org.tango.logging;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tango.server.Constants;
import org.tango.server.ExceptionMessages;
import org.tango.utils.DevFailedUtils;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
import fr.esrf.Tango.DevFailed;

/**
 * Manage tango logging. Based on LogBack logging system
 *
 * @author ABEILLE
 *
 */
public final class LoggingManager {
    private final Logger logger = LoggerFactory.getLogger(LoggingManager.class);
    public static final String LOGGING_TARGET_SEPARATOR = "::";
    public static final String LOGGING_TARGET_DEVICE = "device";
    public static final String LOGGING_TARGET_FILE = "file";
    private final Map fileAppenders = new HashMap();
    private final Map deviceAppenders = new HashMap();
    private int rootLoggingLevel = 0;
    private final Map loggingLevels = new HashMap();
    private static LoggingManager instance = new LoggingManager();
    private ch.qos.logback.classic.Logger rootLoggerBack;

    private LoggingManager() {
        final Logger rootLogger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
        if (rootLogger instanceof ch.qos.logback.classic.Logger) {
            rootLoggerBack = (ch.qos.logback.classic.Logger) rootLogger;
            try {
                rootLoggingLevel = LoggingLevel.getLevel(rootLoggerBack.getLevel()).toInt();
            } catch (final RuntimeException e) {
            }
        }

    }

    public static LoggingManager getInstance() {
        return instance;
    }

    public int getRootLoggingLevel() {
        return rootLoggingLevel;
    }

    public int getLoggingLevel(final String deviceName) {
        int level = rootLoggingLevel;
        if (loggingLevels.containsKey(deviceName)) {
            level = loggingLevels.get(deviceName);
        }
        return level;
    }

    /**
     * Set the logging level of a device
     *
     * @param deviceName the device name
     * @param loggingLevel the level
     */
    public void setLoggingLevel(final String deviceName, final int loggingLevel) {
        System.out.println("set logging level " + deviceName + "-" + LoggingLevel.getLevelFromInt(loggingLevel));
        logger.debug("set logging level to {} on {}", LoggingLevel.getLevelFromInt(loggingLevel), deviceName);
        if (rootLoggingLevel < loggingLevel) {
            setRootLoggingLevel(loggingLevel);
        }
        // setLoggingLevel(loggingLevel);
        loggingLevels.put(deviceName, loggingLevel);
        for (final DeviceAppender appender : deviceAppenders.values()) {
            if (deviceName.equalsIgnoreCase(appender.getDeviceName())) {
                appender.setLevel(loggingLevel);
                break;
            }
        }
        for (final FileAppender appender : fileAppenders.values()) {
            if (deviceName.equalsIgnoreCase(appender.getDeviceName())) {
                appender.setLevel(loggingLevel);
                break;
            }
        }
    }

    /**
     * Set the level of the root logger
     *
     * @param loggingLevel
     */
    public void setRootLoggingLevel(final int loggingLevel) {
        rootLoggingLevel = loggingLevel;
        if (rootLoggerBack != null) {
            rootLoggerBack.setLevel(LoggingLevel.getLevelFromInt(loggingLevel));
        }
    }

    /**
     * Set the level of all loggers of JTangoServer
     *
     * @param loggingLevel
     */
    public void setLoggingLevel(final int loggingLevel, final Class... deviceClassNames) {

        if (rootLoggingLevel < loggingLevel) {
            setRootLoggingLevel(loggingLevel);
        }
        System.out.println("set logging to " + LoggingLevel.getLevelFromInt(loggingLevel));
        final Logger tangoLogger = LoggerFactory.getLogger("org.tango.server");
        if (tangoLogger instanceof ch.qos.logback.classic.Logger) {
            final ch.qos.logback.classic.Logger logbackLogger = (ch.qos.logback.classic.Logger) tangoLogger;
            logbackLogger.setLevel(LoggingLevel.getLevelFromInt(loggingLevel));
        }
        final Logger blackboxLogger = LoggerFactory.getLogger(Constants.CLIENT_REQUESTS_LOGGER);
        if (blackboxLogger instanceof ch.qos.logback.classic.Logger) {
            final ch.qos.logback.classic.Logger logbackLogger = (ch.qos.logback.classic.Logger) blackboxLogger;
            logbackLogger.setLevel(LoggingLevel.getLevelFromInt(loggingLevel));
        }
        for (int i = 0; i < deviceClassNames.length; i++) {
            final Logger deviceLogger = LoggerFactory.getLogger(deviceClassNames[i]);
            if (deviceLogger instanceof ch.qos.logback.classic.Logger) {
                final ch.qos.logback.classic.Logger logbackLogger = (ch.qos.logback.classic.Logger) deviceLogger;
                logbackLogger.setLevel(LoggingLevel.getLevelFromInt(loggingLevel));
            }
        }

    }

    /**
     * Logging of device sent to logviewer device
     *
     * @param deviceTargetName
     * @param deviceClassName
     * @param loggingDeviceName
     * @throws DevFailed
     */
    public void addDeviceAppender(final String deviceTargetName, final Class deviceClassName,
            final String loggingDeviceName) throws DevFailed {
        if (rootLoggerBack != null) {
            logger.debug("add device appender {} on {}", deviceTargetName, loggingDeviceName);
            final DeviceAppender appender = new DeviceAppender(deviceTargetName, loggingDeviceName);
            deviceAppenders.put(loggingDeviceName.toLowerCase(Locale.ENGLISH), appender);
            rootLoggerBack.addAppender(appender);
            // debug level by default
            setLoggingLevel(LoggingLevel.DEBUG.toInt(), deviceClassName);
            setLoggingLevel(loggingDeviceName, LoggingLevel.DEBUG.toInt());
            appender.start();
        }
    }

    /**
     * Add an file appender for a device
     *
     * @param fileName
     * @param deviceName
     * @throws DevFailed
     */
    public void addFileAppender(final String fileName, final String deviceName) throws DevFailed {
        if (rootLoggerBack != null) {
            logger.debug("add file appender of {} in {}", deviceName, fileName);
            final String deviceNameLower = deviceName.toLowerCase(Locale.ENGLISH);
            final File f = new File(fileName);
            if (!f.exists()) {
                try {
                    f.createNewFile();
                } catch (final IOException e) {
                    DevFailedUtils.throwDevFailed(ExceptionMessages.CANNOT_OPEN_FILE, "impossible to open file "
                            + fileName);
                }
            }
            if (!f.canWrite()) {
                DevFailedUtils
                .throwDevFailed(ExceptionMessages.CANNOT_OPEN_FILE, "impossible to open file " + fileName);
            }
            // debug level by default
            // setLoggingLevel(deviceName, LoggingLevel.DEBUG.toInt());
            System.out.println("create file  " + f);
            final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
            final FileAppender rfAppender = new FileAppender(deviceNameLower);
            fileAppenders.put(deviceNameLower, rfAppender);
            rfAppender.setName("FILE-" + deviceNameLower);
            rfAppender.setLevel(rootLoggingLevel);
            // rfAppender.setContext(appender.getContext());
            rfAppender.setFile(fileName);
            rfAppender.setAppend(true);
            rfAppender.setContext(loggerContext);
            final FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy();
            // rolling policies need to know their parent
            // it's one of the rare cases, where a sub-component knows about its parent
            rollingPolicy.setParent(rfAppender);
            rollingPolicy.setContext(loggerContext);
            rollingPolicy.setFileNamePattern(fileName + "%i");
            rollingPolicy.setMaxIndex(1);
            rollingPolicy.setMaxIndex(3);
            rollingPolicy.start();

            final SizeBasedTriggeringPolicy triggeringPolicy = new SizeBasedTriggeringPolicy();
            triggeringPolicy.setMaxFileSize("5MB");
            triggeringPolicy.setContext(loggerContext);
            triggeringPolicy.start();

            final PatternLayoutEncoder encoder = new PatternLayoutEncoder();
            encoder.setContext(loggerContext);
            encoder.setPattern("%-5level %d %X{deviceName} - %thread | %logger{25}.%M:%L - %msg%n");
            encoder.start();

            rfAppender.setEncoder(encoder);
            rfAppender.setRollingPolicy(rollingPolicy);
            rfAppender.setTriggeringPolicy(triggeringPolicy);
            rfAppender.start();

            rootLoggerBack.addAppender(rfAppender);
            rfAppender.start();

            // OPTIONAL: print logback internal status messages
            // StatusPrinter.print(loggerContext);

        }
    }

    public void removeAppender(final String loggingDeviceName, final String targetName) {
        final String loggingDeviceNameLower = loggingDeviceName.toLowerCase(Locale.ENGLISH);
        if (targetName.equalsIgnoreCase(LOGGING_TARGET_DEVICE) && deviceAppenders.containsKey(loggingDeviceNameLower)) {
            final DeviceAppender appender = deviceAppenders.get(loggingDeviceNameLower);
            appender.stop();
            deviceAppenders.remove(loggingDeviceNameLower);
        }
        if (targetName.equalsIgnoreCase(LOGGING_TARGET_FILE) && fileAppenders.containsKey(loggingDeviceNameLower)) {
            final FileAppender appender = fileAppenders.get(loggingDeviceNameLower);
            appender.stop();
            fileAppenders.remove(loggingDeviceNameLower);
        }

    }

    public String[] getLoggingTarget(final String loggingDeviceName) {
        final List targets = new ArrayList();
        final String loggingDeviceNameLower = loggingDeviceName.toLowerCase(Locale.ENGLISH);
        if (deviceAppenders.containsKey(loggingDeviceNameLower)) {
            final DeviceAppender appender = deviceAppenders.get(loggingDeviceNameLower);
            targets.add(LOGGING_TARGET_DEVICE + LOGGING_TARGET_SEPARATOR + appender.getLoggingDeviceName());
        }
        if (fileAppenders.containsKey(loggingDeviceNameLower)) {
            final FileAppender appender = fileAppenders.get(loggingDeviceNameLower);
            targets.add(LOGGING_TARGET_FILE + LOGGING_TARGET_SEPARATOR + appender.getFile());
        }
        return targets.toArray(new String[targets.size()]);
    }

    @SuppressWarnings("unchecked")
    public void startAll() {
        for (final ITangoAppender appender : deviceAppenders.values()) {
            if (rootLoggerBack != null) {
                rootLoggerBack.addAppender((Appender) appender);
                ((AppenderBase) appender).start();
            }
        }
    }

    public void stopAll() {
        for (final ITangoAppender appender : deviceAppenders.values()) {
            ((AppenderBase) appender).stop();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy