org.ocsoft.olivia.logger.LogStation.java Source code

Java tutorial

Introduction

Here is the source code for org.ocsoft.olivia.logger.LogStation.java

Source

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.ocsoft.olivia.logger;

import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

import javax.annotation.Nonnull;

import org.frows.genericfile.v0_3_2.GenericFile;
import org.ocsoft.olivia.DefaultValues;
import org.ocsoft.olivia.observers.OliviaObservatories;
import org.ocsoft.olivia.utils.JsonUtils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * OliviaLog???????.
 * @author tohhy
 */
public class LogStation {

    /**
     * ?.
     */
    @Nonnull
    private static final Level DEFAULT_CONSOLE_LEVEL = Level.INFO;

    /**
     * ?.
     */
    @Nonnull
    private static final Level DEFUALT_LOGFILE_LEVEL = Level.ALL;

    /**
     * ?.
     */
    @Nonnull
    private final Logger logger = Logger.getLogger("org.ocsoft.olivia");

    /**
     * ???.???.
     */
    @Nonnull
    private Level consoleLevel = DEFAULT_CONSOLE_LEVEL;

    /**
     * ???.???.
     */
    @Nonnull
    private Level logFileLevel = DEFUALT_LOGFILE_LEVEL;

    /**
     * ???.
     */
    @Nonnull
    private final ConsoleHandler ch;

    /**
     * ???.
     */
    @Nonnull
    private final FileHandler fh;

    /**
     * ???????????.
     */
    @Nonnull
    private final UncaughtExceptionHandler uch;

    /**
     * .
     */
    private static LogStation instance;

    /**
     * LogStation???.
     * @return 
     */
    public static LogStation getInstance() {
        if (instance == null)
            instance = new LogStation();
        return instance;
    }

    /**
     * ????.
     */
    private LogStation() {

        //??????????
        try {
            setUpLogFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //??
        for (Handler h : logger.getHandlers()) {
            if (h instanceof ConsoleHandler)
                logger.removeHandler(h);
        }
        //???????
        logger.setUseParentHandlers(false);
        //??
        this.ch = createConsoleLogHandler();
        logger.addHandler(ch);
        //?
        this.fh = createLogFileHandler();
        logger.addHandler(fh);
        //????????
        uch = new UncaughtExceptionHandler() {
            public void uncaughtException(Thread th, Throwable ex) {
                OliviaLogger.fatal("UNCAUGHT_EXCEPTION", "uncaught exception occured", new LogData() {
                    {
                        exception(ex);
                        put("thread", th.getName());
                    }
                });
            }
        };
        Thread.currentThread().setUncaughtExceptionHandler(uch);
        //?
        logger.setLevel(Level.ALL);
    }

    /**
     * ??OliviaLog????.
     * @param log ?
     */
    public void log(OliviaLog log) {
        logger.log(log.getLevel().toLoggerLevel(), log.getDataAsJsonString());
        OliviaObservatories.getLog().logExecuted(log);
    }

    /**
     * ??.
     * @throws IOException
     */
    private static void setUpLogFile() throws IOException {
        if (!DefaultValues.USER_LOG_FILE.exists()) {
            DefaultValues.USER_LOG_FILE.getParent().getHandler().createDirectories();
            DefaultValues.USER_LOG_FILE.getHandler().createEmptyFile();
        } else if (DefaultValues.USER_LOG_FILE.getFileSize() > 1024 * 1024) {
            //1MB????
            DefaultValues.USER_LOG_FILE.getHandler().moveTo(
                    new GenericFile(DefaultValues.USER_LOG_FILE.getParent(), new Date().toString() + ".log"));
            DefaultValues.USER_LOG_FILE.getHandler().createEmptyFile();
        }
    }

    /**
     * ????.
     * @return ?????
     */
    @Nonnull
    private ConsoleHandler createConsoleLogHandler() {
        ConsoleHandler ch = new ConsoleHandler();
        //logger??JSON??
        ch.setFormatter(new OliviaConsoleLogFormatter());
        return ch;
    }

    /**
     * ???????.
     * @return ????????
     */
    @Nonnull
    private FileHandler createLogFileHandler() {
        try {
            FileHandler fh = new FileHandler(DefaultValues.USER_LOG_FILE.getAbsolutePathString(), true);
            //logger??JSON??
            fh.setFormatter(new OliviaLogFileFormatter());
            return fh;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * ?????.<br>
     * ?????.
     * @return ???
     */
    public Level getConsoleLevel() {
        return consoleLevel;
    }

    /**
     * 
     * @param consoleLevel
     */
    public void setConsoleLevel(Level consoleLevel) {
        if (consoleLevel == null)
            throw new IllegalArgumentException("consoleLevel must not be null");
        this.consoleLevel = consoleLevel;
        ch.setLevel(consoleLevel);
    }

    /**
     * 
     * @param consoleLevel
     */
    public void setConsoleLevel(LogLevel consoleLevel) {
        setConsoleLevel(consoleLevel.toLoggerLevel());
    }

    /**
     * 
     */
    public void resetConsoleLevel() {
        setConsoleLevel(DEFAULT_CONSOLE_LEVEL);
    }

    /**
     * 
     * @return
     */
    public Level getLogFileLevel() {
        return logFileLevel;
    }

    /**
     * 
     * @param logFileLevel
     */
    public void setLogFileLevel(Level logFileLevel) {
        if (logFileLevel == null)
            throw new IllegalArgumentException("logFileLevel must not be null");
        this.logFileLevel = logFileLevel;
        fh.setLevel(logFileLevel);
    }

    /**
     * 
     * @param logFileLevel
     */
    public void setLogFileLevel(LogLevel logFileLevel) {
        setLogFileLevel(logFileLevel.toLoggerLevel());
    }

    /**
     * 
     */
    public void resetLogFileLevel() {
        setLogFileLevel(DEFUALT_LOGFILE_LEVEL);
    }

    /**
     * ??.
     * @author tohhy
     */
    private static class OliviaConsoleLogFormatter extends Formatter {

        /**
         * ??.
         */
        private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

        @Override
        public String format(LogRecord record) {
            try {
                Map<String, Object> log = new LinkedHashMap<>();
                log.put("date", DATE_FORMAT.format(new Date(record.getMillis())));
                log.put("level", record.getLevel().toString());
                log.put("data",
                        JsonUtils.readJsonString(record.getMessage(), new TypeReference<Map<String, String>>() {
                        }));
                return JsonUtils.toJsonString(log) + "\n";
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }

    }

    /**
     * ??.
     * @author tohhy
     */
    private static class OliviaLogFileFormatter extends Formatter {

        /**
         * ??.
         */
        private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

        /**
         * ?????????mapper??
         */
        private final ObjectMapper mapper = new ObjectMapper();

        @Override
        public String format(LogRecord record) {
            try {
                Map<String, Object> log = new LinkedHashMap<>();
                log.put("date", DATE_FORMAT.format(new Date(record.getMillis())));
                log.put("level", record.getLevel().toString());
                log.put("data",
                        JsonUtils.readJsonString(record.getMessage(), new TypeReference<Map<String, String>>() {
                        }));
                return mapper.writeValueAsString(log) + "\n";
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }

    }
}