有时候我们的服务是以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; } }