| 知乎专栏 |
https://logging.paluch.biz/examples/log4j-2.x.html
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- Exclude the Tomcat dependency --> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> <!-- 禁用 logback --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- 添加Log4j2 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <dependency> <groupId>biz.paluch.logging</groupId> <artifactId>logstash-gelf</artifactId> <version>1.15.0</version> </dependency>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<properties>
<property name="log.pattern">[%d{yyyy-MM-dd HH:mm:ss}] [${hostName}] [%p] [%t] %l - %m%n</property>
<property name="log.dir">/tmp/logs</property>
<property name="log.level">info</property>
</properties>
<Appenders>
<!-- 控制台 -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${log.pattern}" />
</Console>
<!-- INFO级别日志 -->
<RollingFile name="RollingFileInfo" fileName="${log.dir}/info.log" filePattern="${log.dir}/info.%d{yyyy-MM-dd}.log">
<Filters>
<ThresholdFilter level="INFO" />
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL" />
</Filters>
<PatternLayout pattern="${log.pattern}" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="false" />
</Policies>
</RollingFile>
<!-- WARN级别日志 -->
<RollingFile name="RollingFileWarn" fileName="${log.dir}/warn.log" filePattern="${log.dir}/warn.%d{yyyy-MM-dd}.log">
<Filters>
<ThresholdFilter level="WARN" />
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL" />
</Filters>
<PatternLayout pattern="${log.pattern}" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="false" />
</Policies>
</RollingFile>
<!-- ERROR级别日志 -->
<RollingFile name="RollingFileError" fileName="${log.dir}/error.log" filePattern="${log.dir}/error.%d{yyyy-MM-dd}.log">
<Filters>
<ThresholdFilter level="ERROR" />
</Filters>
<PatternLayout pattern="${log.pattern}" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="false" />
</Policies>
</RollingFile>
<Gelf name="Gelf" host="udp:172.18.200.10" port="12201" version="1.1" extractStackTrace="true" filterStackTrace="true" mdcProfiling="true" includeFullMdc="true" maximumMessageSize="8192" originHost="%host{fqdn}">
<Field name="timestamp" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}" />
<Field name="logger" pattern="%logger" />
<Field name="level" pattern="%level" />
<Field name="class" pattern="%C{1}" />
<Field name="method" pattern="%M" />
<Field name="line" pattern="%L" />
<Field name="marker" pattern="%marker" />
<Filters>
<MarkerFilter marker="finance" onMatch="ACCEPT" onMismatch="NEUTRAL" />
<MarkerFilter marker="market" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>
</Gelf>
</Appenders>
<Loggers>
<Root level="${sys:log.level}">
<AppenderRef ref="Console" />
<AppenderRef ref="Gelf" />
<!-- <AppenderRef ref="RollingFileInfo" /> <AppenderRef ref="RollingFileWarn" /> <AppenderRef ref="RollingFileError" /> -->
</Root>
</Loggers>
</Configuration>
@GetMapping("/log")
public String log() {
Marker finance = MarkerFactory.getMarker(LogMarker.finance.toString());
Marker customer = MarkerFactory.getMarker(LogMarker.customer.toString());
Marker market = MarkerFactory.getMarker(LogMarker.market.toString());
logger.info("常规日志");
logger.info(finance, "test");
logger.info(finance, "finance");
logger.info(customer, "customer");
logger.info(market, "market");
return "OK!!!\r\n";
}
@GetMapping("/log/marker")
public String marker(@RequestParam("marker") String marker, @RequestParam("msg") String msg) {
logger.info(MarkerFactory.getMarker(marker), msg);
msg += "\r\n";
return msg;
}
[root@netkiller log]# cat /etc/logstash/conf.d/file.conf
input {
tcp {
port => 4567
codec => json_lines
}
gelf {
port => 12201
use_udp => true
#use_tcp => true
}
}
filter {
ruby {
code => "event.set('datetime', event.get('@timestamp').time.localtime.strftime('%Y-%m-%d %H:%M:%S'))"
}
}
output {
file {
path => "/opt/log/%{marker}.%{+yyyy}-%{+MM}-%{+dd}.log"
codec => line { format => "[%{datetime}] %{level} %{message}"}
}
file {
path => "/opt/log/origin.%{+yyyy}-%{+MM}-%{+dd}.log.gz"
codec => json_lines
gzip => true
}
}
[root@netkiller log]# ls
finance.2022-11-16.log market.2022-11-16.log origin.2022-11-16.log.gz
[root@netkiller log]# cat finance.2022-11-16.log
[2022-11-16 15:02:36] INFO test
[2022-11-16 15:02:36] INFO finance
[2022-11-16 15:21:34] INFO test
[2022-11-16 15:21:34] INFO finance
[root@netkiller log]# cat market.2022-11-16.log
[2022-11-16 15:02:36] INFO market
[2022-11-16 15:21:34] INFO market
[root@netkiller log]# zcat origin.2022-11-16.log.gz |jq
{
"datetime": "2022-11-16 15:21:34",
"timestamp": "2022-11-16 15:21:34.185",
"message": "market",
"host": "macbook-pro-neo.local",
"level": "INFO",
"line": 53,
"@version": "1",
"@timestamp": "2022-11-16T07:21:34.185Z",
"marker": "market",
"logger": "cn.netkiller.controller.HomeController",
"version": "1.1",
"method": "log",
"class": "HomeController",
"source_host": "172.18.5.142",
"facility": "logstash-gelf"
}
{
"datetime": "2022-11-16 15:21:34",
"timestamp": "2022-11-16 15:21:34.143",
"message": "test",
"host": "macbook-pro-neo.local",
"level": "INFO",
"line": 49,
"@version": "1",
"@timestamp": "2022-11-16T07:21:34.143Z",
"marker": "finance",
"logger": "cn.netkiller.controller.HomeController",
"version": "1.1",
"method": "log",
"class": "HomeController",
"source_host": "172.18.5.142",
"facility": "logstash-gelf"
}
{
"datetime": "2022-11-16 15:21:34",
"timestamp": "2022-11-16 15:21:34.184",
"message": "finance",
"host": "macbook-pro-neo.local",
"level": "INFO",
"line": 51,
"@version": "1",
"@timestamp": "2022-11-16T07:21:34.184Z",
"marker": "finance",
"logger": "cn.netkiller.controller.HomeController",
"version": "1.1",
"method": "log",
"class": "HomeController",
"source_host": "172.18.5.142",
"facility": "logstash-gelf"
}
方案一
logging:
config: classpath:log4j2-${spring.profiles.active}.xml
方案二
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private Environment env;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... param) {
if (Arrays.asList(env.getActiveProfiles()).contains("dev")) {
Configurator.initialize(null, "/path/to/log4j2-dev.xml");
} else {
Configurator.initialize(null, "/path/to/log4j2.xml");
}
}
}
#日志配置 无特殊需求无需更改
logging:
config: classpath:log4j2.xml
level:
root: INFO
javax.activation: info
org.apache.catalina: INFO
org.apache.commons.beanutils.converters: INFO
org.apache.coyote.http11.Http11Processor: INFO
org.apache.http: INFO
org.apache.tomcat: INFO
org.springframework: INFO
com.chinamobile.cmss.bdpaas.resource.monitor: DEBUG
<Loggers>
<Logger name="com.ensd.service.sharding.MonthShardingAlgorithm" level="ERROR" />
<Root level="${sys:log.level}">
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
<AppenderRef ref="Logstash"/>
</Root>
</Loggers>
引入依赖
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-spring-boot</artifactId> </dependency>
例子
<Configuration name="ConfigTest" status="ERROR" monitorInterval="5">
<properties>
<property name="applicationName">${spring:spring.application.name}</property>
</properties>
<Appenders>
<SpringProfile name="dev | staging">
<Console name="Out">
<PatternLayout pattern="%m%n"/>
</Console>
</SpringProfile>
<SpringProfile name="prod">
<List name="Out">
</List>
</SpringProfile>
</Appenders>
<Loggers>
<Logger name="org.apache.test" level="trace" additivity="false">
<AppenderRef ref="Out"/>
</Logger>
<Root level="error">
<AppenderRef ref="Out"/>
</Root>
</Loggers>
</Configuration>
读取方法 ${spring:spring.profiles.active}
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<properties>
<property name="log.pattern">[%d{yyyy-MM-dd HH:mm:ss}] [${hostName}] [%p] [%t] %l - %m%n</property>
<property name="log.home">/tmp/logs</property>
<property name="log.level">info</property>
</properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${log.pattern}" />
</Console>
<Gelf name="dev" host="udp:172.18.200.10" port="12201" version="1.1" extractStackTrace="true" filterStackTrace="true" mdcProfiling="true" includeFullMdc="true" maximumMessageSize="8192" originHost="%host{fqdn}">
<Field name="timestamp" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}" />
<Field name="logger" pattern="%logger" />
<Field name="level" pattern="%level" />
<Field name="class" pattern="%C{1}" />
<Field name="method" pattern="%M" />
<Field name="line" pattern="%L" />
<Field name="marker" pattern="%marker" />
<Filters>
<MarkerFilter marker="finance" onMatch="ACCEPT" onMismatch="NEUTRAL" />
<MarkerFilter marker="market" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>
</Gelf>
</Appenders>
<Loggers>
<Root level="${sys:log.level}">
<AppenderRef ref="Console" />
<AppenderRef ref="${spring:spring.profiles.active:-dev}" />
</Root>
</Loggers>
</Configuration>
Spring 2.1.4 无法获取配置,解决方法使用 sys,同时启动的时候增加系统配置项 java -Dspring.application.name=netkiller -Dspring.profiles.active=dev -jar netkiller.jar
<property name="service">${sys:spring.application.name}</property>
<property name="environment">${sys:spring.profiles.active}</property>