如何实现服务器启动自动创建日志

有时候我们的服务是以SDK的方式提供给外围使用。如果SDK需要打印业务日志进行排查的话,需要业务使用方配置log4j,这样使用起来相当不友好。而且很容易忽略这一块的配置,导致上线之后务日志可进行排查。

比如我们使用的中间件zdal, 会自动在服务器打印一下日志,无需我们感知。

我们可以通过log4j 的API方式实现服务启动自动创建监控日志:

/**
 * Alipay.com Inc.
 * Copyright (c) 2004-2015 All Rights Reserved.
 */
package com.alipay.ap.prodintl.common.log;

import java.io.File;
import java.io.IOException;

import org.apache.log4j.Appender;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggerRepository;
import org.springframework.beans.factory.InitializingBean;

/**
 * SDK客户端日志配置
 * 
 * @author baoxing.gbx
 * @version $Id: ClientLogger.java, v 0.1 2015年7月30日 下午9:05:57 baoxing.gbx Exp $
 */
public class ClientLogger implements InitializingBean {

    /** 系统SAL层(调用外部系统服务)摘要日志 */
    public static final Logger  APPRODINTL_SAL_DIGEST     = Logger
                                                              .getLogger(LoggerNames.APPRODINTL_SAL_DIGEST);

    /** 系统SERVICE层(外围系统调用本系统服务)摘要日志 */
    public static final Logger  APPRODINTL_SERVICE_DIGEST = Logger
                                                              .getLogger(LoggerNames.APPRODINTL_SERVICE_DIGEST);

    /** 系统业务日志 */
    public static final Logger  APPRODINTL_BUSINESS       = Logger
                                                              .getLogger(LoggerNames.APPRODINTL_BUSINESS);

    /** 错误APPENDER */
    private static final String ERROR_APPENDER            = "ERROR-APPENDER";

    /** 控制台的appender */
    private static final String CONSOLE_APPENDER          = "CONSOLE";

    private static final String LogPath                   = "logs";

    /** 应用名称 */
    private String              appName;

    /** 日志级别  */
    private String              logLevel;

    /** 分隔符 */
    public final static String  SEPARATOR                 = ",";

    /** 日志参数 */
    public final static String  DAY_DATE_PATTERN          = "'.'yyyy-MM-dd";
    public final static String  DAY_DATE_DIAGEST_PATTERN  = "'.'yyyy-MM-dd_HH";
    public final static String  LAYOUT_PATTERN            = "%d [%t] - %m%n";
    public final static String  DAILY_APPENDER_NAME       = "_DAILY_APPENDER_NAME";
    public final static String  CONVERSION_PATTERN        = "%d %-5p %m%n";

    /** 
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    @Override
    public void afterPropertiesSet() throws Exception {

        initLog(LoggerNames.APPRODINTL_SERVICE_DIGEST_NAME, APPRODINTL_SERVICE_DIGEST);

        initLog(LoggerNames.APPRODINTL_SAL_DIGEST_NAME, APPRODINTL_SAL_DIGEST);

        initLog(LoggerNames.APPRODINTL_BUSINESS_NAME, APPRODINTL_BUSINESS);
    }

    /**
     * 初始化Appender并关联到对应Logger
     * 
     * @param logFileName
     *          日志文件名称
     * @param logger
     *          Logger
     */
    private void initLog(String logFileName, Logger logger) {

        LoggerRepository repository = LogManager.getLoggerRepository();
        //初始化错误日志appender
        DailyRollingFileAppender errorAppender = getErrorAppender(repository);
        //初始化监控日志appender
        DailyRollingFileAppender monitorAppender = getMonitorAppender(repository, logFileName);
        //初始化控制台日志appender
        Appender consoleAppender = getConsoleAppender(repository);
        // 获取日志级别
        logger.setLevel(Level.toLevel(this.logLevel));
        if (monitorAppender != null) {
            logger.addAppender(monitorAppender);
            logger.addAppender(errorAppender);
        }

        //如果控制台的appender配置,添加
        if (consoleAppender != null) {
            logger.addAppender(consoleAppender);
        }
        logger.setAdditivity(false);

    }

    /**
     * 获取错误日志appender
     * 
     * @param repository
     * @return
     */
    private Appender getConsoleAppender(LoggerRepository repository) {
        return repository.getRootLogger().getAppender(CONSOLE_APPENDER);
    }

    /**
     * 获取监控日志appender
     * 
     * @param repository
     * @param logFileName
     * @return
     */
    private DailyRollingFileAppender getMonitorAppender(LoggerRepository repository,
                                                        String logFileName) {
        PatternLayout layout = new PatternLayout(LAYOUT_PATTERN);
        layout.setConversionPattern(CONVERSION_PATTERN);
        DailyRollingFileAppender monitorAppender = null;
        //日志文件目录
        String path = getLogFilePath();
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        //完整日志文件路径
        String fullLogFileName = path + logFileName;
        try {
            // 文件
            String rollingDatePattern = DAY_DATE_PATTERN;
            monitorAppender = new DailyRollingFileAppender(layout, fullLogFileName,
                rollingDatePattern);
            monitorAppender.setAppend(true);
            monitorAppender.setEncoding("UTF-8");
            monitorAppender.setName(DAILY_APPENDER_NAME);

        } catch (IOException e) {

            throw new RuntimeException(e);
        }
        return monitorAppender;
    }

    /**
     * 获取控制台日志appender
     * 
     * @param repository
     * @return
     */
    private DailyRollingFileAppender getErrorAppender(LoggerRepository repository) {
        return (DailyRollingFileAppender) repository.getRootLogger().getAppender(ERROR_APPENDER);
    }

    /**
     * 构造日志文件目录
     * 
     * @return 日志文件目录
     */
    private String getLogFilePath() {

        String userHome = System.getProperty("user.home");
        if (!userHome.endsWith(File.separator)) {
            userHome += File.separator;
        }
        return userHome + LogPath + File.separator + this.appName + File.separator;
    }

    /**
     * Setter method for property <tt>appName</tt>.
     * 
     * @param appName value to be assigned to property appName
     */
    public void setAppName(String appName) {
        this.appName = appName;
    }

    /**
     * Setter method for property <tt>logLevel</tt>.
     * 
     * @param logLevel value to be assigned to property logLevel
     */
    public void setLogLevel(String logLevel) {
        this.logLevel = logLevel;
    }

}

  

posted @ 2015-07-31 14:30  E_star  阅读(623)  评论(0编辑  收藏  举报