日志套餐篇 - log4j2 logback全量套餐
日志套餐篇 - log4j2 logback全量套餐
前情提要:
Log4j Log4j2 logback是当下主流的日志框架
slf4j则是新一代的日志框架接口,logback直接实现了slf4j接口,另外logback是SpringBoot最新的默认日志框架
综合来看性能上依然推荐:log4j2(拥有logback全部特性)
**注:**鉴于log4j已经跟不上时代的要求,因此不做特别的介绍,其实log4j的配置,完全可以在log4j2上使用
普通工程 - 建议集成log4j2
普通工程即:普通的java项目, 如个人的代码Demo或者准备打成jar使用的,推荐使用log4j2
必要依赖如下:
<!-- log4j2 必要依赖 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.10.0</version>
</dependency>
<!-- log4j2 必要依赖 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.10.0</version>
</dependency>
<!-- slf4j核心包 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!--用于与slf4j保持桥接-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.10.0</version>
</dependency>
配置如下:
Maven项目只需要在resource里面加入log4j2.xml配置文件即可
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<Configuration status="WARN" monitorInterval="30">
<!--全局属性-->
<Properties>
<Property name="APP_NAME">kerwinTools</Property>
<Property name="LOG_FILE_PATH">/log/${APP_NAME}</Property>
<Property name="PATTERN_FORMAT">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%t] %class{36} (%L) %M - %msg%xEx%n</Property>
</Properties>
<Appenders>
<!--输出到控制台-->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN_FORMAT}"/>
</Console>
<!-- INFO_LOG -->
<RollingFile name="INFO_LOG" fileName="${LOG_FILE_PATH}/info.log" filePattern="${LOG_HOME}/info.log_%d{yyyy-MM-dd}.log">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<Filters>
<ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<pattern>${PATTERN_FORMAT}</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_FILE_PATH}" maxDepth="1">
<IfFileName glob="info.log_*" />
<IfLastModified age="5d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<!-- DEBUG_LOG -->
<RollingFile name="DEBUG_LOG" fileName="${LOG_FILE_PATH}/debug.log" filePattern="${LOG_HOME}/debug.log_%d{yyyy-MM-dd}.log">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<Filters>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<pattern>${PATTERN_FORMAT}</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_FILE_PATH}" maxDepth="1">
<IfFileName glob="debug.log_*" />
<IfLastModified age="5d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<!-- ERROR_LOG -->
<RollingFile name="ERROR_LOG" fileName="${LOG_FILE_PATH}/error.log" filePattern="${LOG_HOME}/error.log_%d{yyyy-MM-dd}.log">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<pattern>${PATTERN_FORMAT}</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_FILE_PATH}" maxDepth="1">
<IfFileName glob="error.log_*" />
<IfLastModified age="5d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<!-- LOG everything at DEBUG level 默认级别为DEBUG -->
<Root level="DEBUG">
<AppenderRef ref="Console"/>
<AppenderRef ref="INFO_LOG"/>
<AppenderRef ref="DEBUG_LOG"/>
<AppenderRef ref="ERROR_LOG"/>
</Root>
</Loggers>
</Configuration>
**注:**日志打印的位置我并没用做特别的约束,所以它会在项目所存储的盘符自动建立${APP_NAME} 文件夹
效果如图所示:
SpringBoot项目 - 个人练习建议集成logback
// 由于springboot默认支持logbak 因此无需任何依赖即可使用,当然需要一些默认的必备依赖 如 web等...
application配置如下:
# 约束mybis-dao级别为dao层
logging.level.com.cat.dao=DEBUG
logging.config=classpath:logback-spring.xml
# 文件输出位置即文件夹名称
logging.file=/log/volcat-server
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logback</contextName>
<!-- 命名为logback-spring 可以读取spring中的配置信息, 以下即为读取spring的日志输出地址 -->
<springProperty scope="context" name="log.path" source="logging.file"/>
<!-- 在当前文件中约束配置地址 -->
<!--<property name="log.path" value="/log/demo_test_nginx" />-->
<!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、
以及指定<appender>。<logger>仅有一个name属性,
一个可选的level和一个可选的addtivity属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
如果未设置此属性,那么当前logger将会继承上级的级别。
addtivity:是否向上级logger传递打印信息。默认是true
-->
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39} %line){cyan} %clr(:) %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,配置为DEBUG级别, 控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/debug.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档 -->
<fileNamePattern>${log.path}/debug/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/warn/warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
不能设置为INHERITED或者同义词NULL。默认是DEBUG
可以包含零个或多个元素,标识这个appender将会添加到这个logger。
-->
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</configuration>
SpringBoot项目 - 集成log4j2
必备依赖 - 既然是SpringBoot项目,那用官方的starter是最好的,版本什么的都不用管
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 去除logback日志依赖 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 导入log4j2-starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- log4j2 异步打印必要依赖 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.4</version>
</dependency>
applications配置
# mybatis-dao相关的操作为DEBUG级别, 数据库日志会打印到debug文件中
logging.level.com.cat.dao=DEBUG
logging.config=classpath:log4j2.xml
配置文件 - 沿用上面的配置文件即可,必要情况可以修改打印的日志级别,如
.....
<Loggers>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<Logger name="org.springframework" level="INFO"/>
<Logger name="org.mybatis" level="INFO"/>
<!-- LOG everything at INFO level -->
<Root level="INFO">
<AppenderRef ref="Console"/>
<AppenderRef ref="INFO_LOG"/>
<AppenderRef ref="DEBUG_LOG"/>
<AppenderRef ref="ERROR_LOG"/>
</Root>
</Loggers>
SpringBoot - log4j2 企业级方案
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<properties>
<property name="LOG_HOME">/log/volcat-server</property>
</properties>
<Appenders>
<!-- 輸出到監視器 -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout charset="UTF-8" pattern="%date{yyyy-MM-dd HH:mm:ss,SSS} [%thread][%level] - %msg%n" />
</Console>
<RollingFile name="error.log" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/error.log_%d{yyyy-MM-dd}.log">
<PatternLayout charset="UTF-8" pattern="%date{yyyy-MM-dd HH:mm:ss,SSS} [%thread][%level] - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="1">
<IfFileName glob="error.log_*" />
<IfLastModified age="5d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="debug.log" fileName="${LOG_HOME}/debug.log" filePattern="${LOG_HOME}/debug.log_%d{yyyy-MM-dd}.log">
<PatternLayout charset="UTF-8" pattern="%date{yyyy-MM-dd HH:mm:ss,SSS} [%thread][%level] - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="1">
<IfFileName glob="debug.log_*" />
<IfLastModified age="5d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="message.log" fileName="${LOG_HOME}/message.log" filePattern="${LOG_HOME}/message.log_%d{yyyy-MM-dd}.log">
<PatternLayout charset="UTF-8" pattern="%date{yyyy-MM-dd HH:mm:ss,SSS} [%thread][%level] - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="1">
<IfFileName glob="message.log_*" />
<IfLastModified age="5d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="access.log" fileName="${LOG_HOME}/access.log" filePattern="${LOG_HOME}/access.log_%d{yyyy-MM-dd}.log">
<PatternLayout charset="UTF-8" pattern="%date{yyyy-MM-dd HH:mm:ss,SSS} [%thread][%level] - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="1">
<IfFileName glob="access.log_*" />
<IfLastModified age="5d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="sys.error" level="ERROR">
<AppenderRef ref="error.log" />
</Logger>
<Logger name="sys.debug" level="DEBUG">
<AppenderRef ref="debug.log" />
</Logger>
<Logger name="sys.message" level="INFO">
<AppenderRef ref="message.log" />
</Logger>
<Logger name="sys.access" level="INFO">
<AppenderRef ref="access.log" />
</Logger>
</Loggers>
</Configuration>
Logit工具类
package com.mine.log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Logit {
private static final Logger DEBUG_LOG = LoggerFactory.getLogger("sys.debug");
private static final Logger WARN_LOG = LoggerFactory.getLogger("sys.warn");
private static final Logger MESSAGE_LOG = LoggerFactory.getLogger("sys.message");
private static final Logger ACCESS_LOG = LoggerFactory.getLogger("sys.access");
private static final Logger ERROR_LOG = LoggerFactory.getLogger("sys.error");
private static final Logger DB_LOG = LoggerFactory.getLogger("db.sql");
public Logit() {}
public static void accessLog(String log) {
ACCESS_LOG.info(log);
}
public static void messageLog(String log) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
MESSAGE_LOG.info(sb.toString());
}
public static void messageLog(String log, String loglevel) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
if ("debug".equalsIgnoreCase(loglevel)) {
MESSAGE_LOG.debug(log);
} else if ("info".equalsIgnoreCase(loglevel)) {
MESSAGE_LOG.info(log);
} else if ("warn".equalsIgnoreCase(loglevel)) {
MESSAGE_LOG.warn(log);
} else if ("error".equalsIgnoreCase(loglevel)) {
MESSAGE_LOG.error(log);
} else {
MESSAGE_LOG.info(log);
}
}
public static void debugLog(String log) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
debugPlog(sb.toString(), "debug");
}
public static void debugLog(String log, String loglevel) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
debugPlog(sb.toString(), loglevel);
}
private static void debugPlog(String log, String loglevel) {
if ("debug".equalsIgnoreCase(loglevel)) {
DEBUG_LOG.debug(log);
} else if ("info".equalsIgnoreCase(loglevel)) {
DEBUG_LOG.info(log);
} else if ("warn".equalsIgnoreCase(loglevel)) {
DEBUG_LOG.warn(log);
} else if ("error".equalsIgnoreCase(loglevel)) {
DEBUG_LOG.error(log);
} else {
DEBUG_LOG.debug(log);
}
}
public static void warnLog(String log) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
WARN_LOG.error(sb.toString());
}
public static void errorLog(String log) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
errorPLog(sb.toString(), (Throwable)null);
}
public static void errorLog(String log, Throwable throwable) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
errorPLog(sb.toString(), throwable);
}
public static void dbLog(String log, Object... objects) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
if (objects != null && objects.length > 0) {
sb.append("; parameter[");
Object[] var4 = objects;
int var5 = objects.length;
for(int var6 = 0; var6 < var5; ++var6) {
Object obj = var4[var6];
sb.append(obj);
sb.append(",");
}
sb.delete(sb.length() - 1, sb.length());
sb.append("]");
}
DB_LOG.debug(sb.toString());
}
private static void errorPLog(String log, Throwable throwable) {
if (throwable == null) {
ERROR_LOG.error(log);
} else {
ERROR_LOG.error(log, throwable);
}
}
public static void log(String name, String log) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
logByName(name, sb.toString(), "debug", (Throwable)null);
}
public static void log(String name, String log, String loglevel) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
logByName(name, sb.toString(), loglevel, (Throwable)null);
}
public static void log(String name, String log, String loglevel, Throwable throwable) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
logByName(name, sb.toString(), loglevel, throwable);
}
private static void logByName(String name, String log, String loglevel, Throwable throwable) {
if (name != null) {
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
StringBuffer sb = new StringBuffer(stacks[1].getClassName());
sb.append(".");
sb.append(stacks[1].getMethodName());
sb.append("---");
sb.append(log);
Logger logger = LoggerFactory.getLogger(name);
try {
if (throwable == null) {
if ("debug".equalsIgnoreCase(loglevel)) {
logger.debug(log);
} else if ("info".equalsIgnoreCase(loglevel)) {
logger.info(log);
} else if ("warn".equalsIgnoreCase(loglevel)) {
logger.warn(log);
} else if ("error".equalsIgnoreCase(loglevel)) {
logger.error(log);
} else {
logger.debug(log);
}
} else if ("debug".equalsIgnoreCase(loglevel)) {
logger.debug(log, throwable);
} else if ("info".equalsIgnoreCase(loglevel)) {
logger.info(log, throwable);
} else if ("warn".equalsIgnoreCase(loglevel)) {
logger.warn(log, throwable);
} else if ("error".equalsIgnoreCase(loglevel)) {
logger.error(log, throwable);
} else {
logger.debug(log, throwable);
}
} catch (Exception var8) {
;
}
}
}
}
使用说明 :
// 由于该方案配置的Logger 为 sys.error...等开头,因此 直接使用loger的方式会在控制台输出,但不会被记录到日志文件之中,有且仅有通过Logit打印的日志才会被记录到文件中,此方案减少了每个类都创建loger的尴尬,非常方便
Logit.errorLog("在线用户插入失败" + " parms: " + userOnline, new Throwable(e));
GITHUB链接:https://github.com/kkzhilu/volcat-server (不同分支即对应不同日志框架)
项目暂时为私有, 如果需要参考请联系我
日志套餐篇 - log4j2 logback全量套餐的更多相关文章
- Log4j,Log4j2,logback,slf4j日志学习
日志学习笔记 Log4j Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.数据库等:我们也可以控制每一条日志的输出格式:通过定义每一条 ...
- Log4j,Log4j2,logback,slf4j日志学习(转)
日志学习笔记Log4jLog4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.数据库等:我们也可以控制每一条日志的输出格式:通过定义每一条日志 ...
- 免费申请使用IBM Cloud Lite(轻量套餐) 续
之前尝试申请了IBM的轻量套餐,过程很简单,操作起来也比较方便,就是能够用到的地方不多,虽说几乎是无限流量且永久免费,我能做的也只是做个小网站 免费用户默认的是轻量应用服务,如果需要功能更多更全的应用 ...
- 54. spring boot日志升级篇—logback【从零开始学Spring Boot】
在<44. Spring Boot日志记录SLF4J>章节中有关相关的介绍,这里我们在深入的了解下logback框架. 为什么要使用logback ? --在开发中不建议使用System. ...
- SpringBoot系列之集成logback实现日志打印(篇二)
SpringBoot系列之集成logback实现日志打印(篇二) 基于上篇博客SpringBoot系列之集成logback实现日志打印(篇一)之后,再写一篇博客进行补充 logback是一款开源的日志 ...
- 免费申请使用IBM Cloud Lite(轻量套餐) 详细教程指南
注册轻量帐户可在 IBM CLOUD控制台中使用所选的显示有轻量标记的免费轻量套餐来构建应用程序和探索服务.轻量帐户不会到期,也无需信用卡. 本文详细的介绍了一下,免费云服务的申请以及使用!这次使用I ...
- 全量日志 requestId
常量参数和系统参数 API 的请求者不可见,由网关在请求后端服务时添加上. 常量参数.比如您的后端需要接收一个常量,但是这个常量您不希望被您的客户看见,那么就设置一个常量参数,可以在 Header 或 ...
- iOS开发中全量日志的获取
我们在app中对崩溃.卡顿.内存问题进行监控.一旦监控到问题,我们就需要记录下来,但是,很多问题的定位仅靠问题发生的那一刹那记录的信息是不够的,我们需要记录app的全量日志来获取更多的信息. 一,使用 ...
- Mysql备份系列(2)--mysqldump备份(全量+增量)方案操作记录
在日常运维工作中,对mysql数据库的备份是万分重要的,以防在数据库表丢失或损坏情况出现,可以及时恢复数据. 线上数据库备份场景:每周日执行一次全量备份,然后每天下午1点执行MySQLdump增量备份 ...
随机推荐
- 兄弟打印机MFC代码示范
m_strModel.LoadString(IDS_MODEL_STRING); //IDS_MODEL_STRING,字符串控件的ID,资源视图-String Table里面设置 m_strSour ...
- Jmeter 测试接口
创建线程组 添加HTTP请求 查看结果树
- 4.WebPack-Loader
一.什么是Loader WebPack默认只"认识"以*.js结尾的文件,如果想处理其他类型的文件,就必须添加Loader,有各种各样的Loader,每个Loader可处理不同类型 ...
- JavaScript DOM 注册事件
一个HTML是一个DOM树,每一个节点都是DOM对象,整个HTML其实也是一个DOM对象,根节点是<html>; 在HTML页面初始化的时候,JavaScript会自动帮DOM对象注册消息 ...
- Elasticsearch的query phase和fetch phase
对于一次query查询到数据返回到客户端,经历了两个过程 query phase和fetch phase的过程 query phase 查询阶段 fetch phase 获取阶段. 1 qu ...
- Markdown语法说明及测试一览表
标题: Markdown语法说明及测试一览表 作者: 梦幻之心星 347369787@QQ.com 标签: [Markdown, Typora, Markdown_Nice, CSS] 目录: [Ma ...
- mysql8.0 解决时区问题
jdbc:mysql://localhost:3306/databaseName?useUnicode=true&characterEncoding=UTF-8&useOldAlias ...
- Spring IoC BeanDefinition 的加载和注册
前言 本系列全部基于 Spring 5.2.2.BUILD-SNAPSHOT 版本.因为 Spring 整个体系太过于庞大,所以只会进行关键部分的源码解析. 本篇文章主要介绍 Spring IoC 容 ...
- openstack Rocky 社区版部署1.2 安装ntp service
一.controller节点安装ntp 1 安装ntp服务 yum install chrony 2 Edit the chrony.conf file and add, change, or rem ...
- xeus-clickhouse: Jupyter 的 ClickHouse 内核
在科学计算领域,Jupyter 是一个使用非常广泛的集成开发环境,它支持多种主流的编程语言比如 Python, C++, R 或者 Julia.同时,数据科学最重要的还是数据,而 SQL 是操作数据最 ...