目录
2.创建logback-spring.xml配置文件放在resource目录下,内容:
2. 调用方法之后可以直接在其他模块中引入logging直接使用
一 JavaSE logback
1.pom坐标
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
</dependencies>
2.logback.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="60 s">
<!-- 定义日志的根目录 通过启动-Dlog=./log 设置路径 -->
<!-- <property name="destination" value="${log}"/>-->
<!-- 定义日志的根目录 通过启动自定义类LogHomeProperty继承PropertyDefinerBase重写getPropertyValue方法返回设置路径,注意 class 配制LogHomeProperty的类路径 -->
<define name="destination" class="com.business.init.LogHomeProperty" /> <!--自定义的日志路径加载类-->
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<level>CONSOLE</level>
<Prudent>true</Prudent>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,[at %C.%M\(%F:%L\)]用于查看底层执行代码记录 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [at %C.%M\(%F:%L\)] --> %msg%n</pattern>
</encoder>
</appender>
<appender name="OFF" class="ch.qos.logback.core.rolling.RollingFileAppender">
<level>OFF</level>
<Prudent>true</Prudent>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤成功:onMatch,过滤失败:onMismatch || 保留:ACCEPT,丢弃:DENY,交给下一个过滤器:NEUTRAL -->
<level>OFF</level><onMatch>DENY</onMatch><onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<level>INFO</level>
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${destination}/info_%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory><!--保留时间30天-->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level \(%F:%L\) --> %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level><onMatch>DENY</onMatch><onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch>
</filter>
</appender>
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<level>ERROR</level>
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${destination}/error_%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>5</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level \(%F:%L\) --> %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level><onMatch>DENY</onMatch><onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level><onMatch>DENY</onMatch><onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level><onMatch>DENY</onMatch><onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>NEUTRAL</onMismatch>
</filter>
</appender>
<root level="INFO">
<appender-ref ref="OFF"/>
<appender-ref ref="ERROR"/>
<appender-ref ref="INFO"/>
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
重写类LogHomeProperty
package com.business.init;
import ch.qos.logback.core.PropertyDefinerBase;
public class LogHomeProperty extends PropertyDefinerBase {
@Override
public String getPropertyValue() {
return "/你自己指定的路径";
}
}
3.测试代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogTest {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(LogTest.class);
logger.error("error 错误信息,不会影响系统运行");
logger.warn("warn 警告信息,可能会发生问题");
logger.info("info 运行信息,数据连接、网络连接、I0操作等等");
logger.debug("debug 调试信息,一般在开发中使用,记录程序变量参数传递信息等等");
}
}
4.运行结果
5.日志文件
二.sprngboot logback
1.pom依赖
<dependency>
<!--springboot启动依赖-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.7.RELEASE</version>
</dependency>
<dependency>
<!--springboot 日志依赖-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>1.5.7.RELEASE</version>
</dependency>
2.创建logback-spring.xml配置文件放在resource目录下,内容:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="false" scanPeriod="60 seconds" debug="false">
<!-- 定义日志的根目录 通过启动-Dlog=./log 设置路径 -->
<property name="LOG_HOME" value="${log}"/>
<!-- 定义日志文件名称 -->
<property name="appName" value="${app}"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [at %C.%M\(%F:%L\)] - %msg %n</pattern>
</encoder>
<!--过滤器-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch><!--保留-->
<onMismatch>NEUTRAL</onMismatch><!--往下传递-->
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch><!--终止传递-->
</filter>
</appender>
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/${appName}/info_%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [at %C.%M\(%F:%L\)] - %msg %n</pattern>
</encoder>
<!--过滤器-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/${appName}/debug_%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>5</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [at %C.%M\(%F:%L\)] - %msg %n</pattern>
</encoder>
</appender>
<appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/${appName}/warn_%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>5</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [at %C.%M\(%F:%L\)] - %msg %n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/${appName}/error_%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>5</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [at %C.%M\(%F:%L\)] - %msg %n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="CONSOLE">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="INFO"/>
<appender-ref ref="WARN"/>
<appender-ref ref="DEBUG"/>
<appender-ref ref="ERROR"/>
</root>
</configuration>
3.测试
System.setProperty("log", projectLogPath);//设置配制文件的${log}路径
Logger logger = LoggerFactory.getLogger(this.getClass());
logger.error("error 错误信息,不会影响系统运行");
logger.warn("warn 警告信息,可能会发生问题");
logger.info("info 运行信息,数据连接、网络连接、I0操作等等");
logger.debug("debug 调试信息,一般在开发中使用,记录程序变量参数传递信息等等");
三. log4j
pom中不能用slf4j和logback 配制文件 log4j.properties
### #配置根Logger ###
log4j.rootLogger=debug,info,warn,error,stdout
### 输出到控制台 ### Threshol表示控制台输出日志级别 File标识存储路径
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.Threshold = debug
log4j.appender.stdout.layout.ConversionPattern=%d{yyy-MM-dd HH\:mm\:ss} %5p %c{1}\:%L - %m%n
### warn ###
log4j.appender.warn = org.apache.log4j.DailyRollingFileAppender
log4j.appender.warn.File=C:/Users/admin/IdeaProjects/metrics/log/warn
log4j.appender.warn.DatePattern = '.'yyyy-MM-dd
log4j.appender.warn.Append = true
log4j.appender.warn.Threshold = WARN
log4j.appender.warn.layout = org.apache.log4j.PatternLayout
log4j.appender.warn.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} [%thread] %p [at %c.%M\(%F:%L\)] --> %m%n
### info ###
log4j.appender.info = org.apache.log4j.DailyRollingFileAppender
log4j.appender.info.File=C:/Users/admin/IdeaProjects/metrics/log/info
log4j.appender.info.DatePattern = '.'yyyy-MM-dd
log4j.appender.info.Append = true
log4j.appender.info.Threshold = INFO
log4j.appender.info.layout = org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} [%thread] %p [at %c.%M\(%F:%L\)] --> %m%n
### error ###
log4j.appender.error = org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.File=C:/Users/admin/IdeaProjects/metrics/log/error
log4j.appender.error.DatePattern = '.'yyyy-MM-dd
log4j.appender.error.Append = true
log4j.appender.error.Threshold = ERROR
log4j.appender.error.layout = org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} [%thread] %p [at %c.%M\(%F:%L\)] --> %m%n
四.python自定义日志配制
1.配制代码
import logging
import time
import re
from logging.handlers import TimedRotatingFileHandler
def init(debug):
format = "%(levelname)s|%(asctime)-5s|%(thread)d| File \"%(pathname)s\", line %(lineno)d %(message)s"
"""
初始化日志
:param debug: 是否需要打印控制台日志
:return:
"""
# 第一步,创建一个logger
logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # Log等级总开关
# 第二步,创建一个handler,用于写入日志文件
rq = time.strftime('%Y-%m-%d', time.localtime(time.time()))
log_name = "./logs/" + rq + '.log'
formatter = logging.Formatter(format)
log_file_handler = TimedRotatingFileHandler(filename=log_name, when="D", encoding="utf-8", interval=1,
backupCount=31)
log_file_handler.suffix = "%Y-%m-%d_%H-%M.log"
log_file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}.log$")
log_file_handler.setFormatter(formatter)
log = logging.getLogger()
log.addHandler(log_file_handler)
if debug:
# 扩展,新增控制台日志
console = logging.StreamHandler()
formatter = logging.Formatter(format)
console.setFormatter(formatter)
logger.addHandler(console)
2. 调用方法之后可以直接在其他模块中引入logging直接使用
import logging
if __name__ == '__main__':
init(True)# 初始化日志
logging.info("这是新加的日志")
3. 查看运行效果
五.设置项目日志的路径自动获取
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
public class ParamDirUtil {
final static String encoding = "utf-8";
/**
* 获取资源文件或者目录
*
* @param fileName 文件名称
* @return
*/
public static String getProjectFilePath(String fileName) {
return getProjectFilePath(fileName, false);
}
/**
* @param fileName 文件名称
* @param source 是否在resource目录下如果不在 获取去项目根目录
* @return
*/
public static String getProjectFilePath(String fileName, boolean source) {
try {
Class<ParamDirUtil> thisClass = ParamDirUtil.class;
String runFileName = thisClass.getProtectionDomain().getCodeSource().getLocation().getPath();
boolean isJar = runFileName.endsWith(".jar");//是否是jar启动
boolean isWin = System.getProperty("os.name").contains("dows");//是否是win
String tmpFile = thisClass.getProtectionDomain().getCodeSource().getLocation().getPath();//必须要用到new
if (!isJar) {
String home = tmpFile.substring(1, tmpFile.length() - 15);
String filePath = home + "src/main/resources/" + fileName;
if (!source) {
filePath = home + fileName;
}
return URLDecoder.decode(filePath, encoding);
}
String filePathOther = isWin ? tmpFile.substring(1) : tmpFile;
String filePath = new File(filePathOther).getParent() + "/" + fileName;
return URLDecoder.decode(filePath, encoding);
} catch (UnsupportedEncodingException e) {
return "./" + fileName;
}
}
}