添加 axzo-logger-spring-boot-starter
This commit is contained in:
parent
2110f70532
commit
f6cf98297f
33
axzo-loger-spring-boot-starter/README.md
Normal file
33
axzo-loger-spring-boot-starter/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
# axzo-logger-spring-boot-starter
|
||||
|
||||
日志支持库.
|
||||
更多细节用法请参考:
|
||||
- [Spring Boot Logging](https://docs.spring.io/spring-boot/docs/2.4.13/reference/html/spring-boot-features.html#boot-features-logging)
|
||||
|
||||
## Quickstart
|
||||
### 1、引入依赖:
|
||||
|
||||
``` xml
|
||||
<!-- Logger依赖 -->
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-logger-spring-boot-starter</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 2、日志配置(logback-spring.xml)
|
||||
|
||||
``` xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<configuration>
|
||||
<!-- 导入安心筑全局日志配置 -->
|
||||
<include resource="logback/logback-axzo.xml" />
|
||||
<!-- 覆盖开发环境日志配置 -->
|
||||
<springProfile name="local,dev">
|
||||
<logger name="cn.axzo" level="DEBUG" />
|
||||
</springProfile>
|
||||
</configuration>
|
||||
```
|
||||
|
||||
39
axzo-loger-spring-boot-starter/pom.xml
Normal file
39
axzo-loger-spring-boot-starter/pom.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-framework</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>axzo-logger-spring-boot-starter</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
|
||||
<name>axzo-logger-spring-boot-starter</name>
|
||||
<description>安心筑日志支持库</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>apm-toolkit-logback-1.x</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.logstash.logback</groupId>
|
||||
<artifactId>logstash-logback-encoder</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,77 @@
|
||||
package cn.axzo.framework.logger;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.context.logging.LoggingApplicationListener;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.boot.logging.LoggerConfiguration;
|
||||
import org.springframework.boot.logging.LoggerGroup;
|
||||
import org.springframework.boot.logging.LoggerGroups;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
/**
|
||||
* 动态日志Level调整管理器
|
||||
*
|
||||
* @see org.springframework.boot.actuate.autoconfigure.logging.LoggersEndpointAutoConfiguration
|
||||
* @see org.springframework.boot.actuate.logging.LoggersEndpoint
|
||||
*/
|
||||
public class DynamicLoggerManager implements ApplicationContextAware {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
private static final Map<String, LogLevel> LEVELS = new HashMap<>();
|
||||
|
||||
static {
|
||||
LEVELS.put("trace", LogLevel.TRACE);
|
||||
LEVELS.put("debug", LogLevel.DEBUG);
|
||||
LEVELS.put("info", LogLevel.INFO);
|
||||
LEVELS.put("warn", LogLevel.WARN);
|
||||
LEVELS.put("error", LogLevel.ERROR);
|
||||
LEVELS.put("off", LogLevel.OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态设置日志级别,支持按group设置,也支持按名称设置
|
||||
* @param name group名称或者包名称,Spring内置group有web、sql
|
||||
* @param level 只支持:trace、debug、info、warn、error、off
|
||||
* @return 返回变更后的日志配置文本列表
|
||||
*/
|
||||
public List<String> setLevel(String name, String level) {
|
||||
LogLevel logLevel = LEVELS.getOrDefault(level, LogLevel.INFO);
|
||||
|
||||
LoggingSystem loggingSystem = context.getBean(LoggingApplicationListener.LOGGING_SYSTEM_BEAN_NAME, LoggingSystem.class);
|
||||
|
||||
// 按分组设置日志级别
|
||||
LoggerGroups loggerGroups = context.getBean(LoggingApplicationListener.LOGGER_GROUPS_BEAN_NAME, LoggerGroups.class);
|
||||
LoggerGroup group = loggerGroups.get(name);
|
||||
if (group != null && group.hasMembers()) {
|
||||
group.configureLogLevel(logLevel, loggingSystem::setLogLevel);
|
||||
|
||||
List<String> loggerConfigs = group.getMembers().stream().map(loggingSystem::getLoggerConfiguration)
|
||||
.sorted(Comparator.comparing(LoggerConfiguration::getName)).map(LoggerConfiguration::toString).collect(Collectors.toList());
|
||||
return loggerConfigs;
|
||||
}
|
||||
// 单个loggerName设置日志级别
|
||||
LoggerConfiguration loggerConfiguration = loggingSystem.getLoggerConfiguration(name);
|
||||
if (loggerConfiguration == null) {
|
||||
return Collections.singletonList("Logger not exist : " + name);
|
||||
}
|
||||
loggingSystem.setLogLevel(name, logLevel);
|
||||
|
||||
return Collections.singletonList(loggingSystem.getLoggerConfiguration(name).toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package cn.axzo.framework.logger;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import ch.qos.logback.core.PropertyDefinerBase;
|
||||
|
||||
|
||||
/**
|
||||
* 获取主机IP地址
|
||||
* //TODO 业务代码中的CanonicalHostNamePropertyDefiner类需要删除
|
||||
*/
|
||||
public class HostNamePropertyDefiner extends PropertyDefinerBase {
|
||||
|
||||
@Override
|
||||
public String getPropertyValue() {
|
||||
InetAddress ia;
|
||||
try {
|
||||
ia = InetAddress.getLocalHost();
|
||||
String host = ia.getHostName();
|
||||
return host;
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package cn.axzo.framework.logger;
|
||||
|
||||
import ch.qos.logback.core.PropertyDefinerBase;
|
||||
|
||||
/**
|
||||
* 日志路径定义:
|
||||
* 非容器环境下日志目录为target/logs/,容器环境下日志目录为/mnt/app-logdata/ + podNamespace
|
||||
* //TODO connom包中的冗余代码可删除
|
||||
*/
|
||||
public class LogPrefixhPropertyDefiner extends PropertyDefinerBase {
|
||||
|
||||
private static final String POD_NAMESPACE_KEY = "MY_POD_NAMESPACE";
|
||||
|
||||
@Override
|
||||
public String getPropertyValue() {
|
||||
String podNamespace = SystemPropertyResolver.getPropertyValue(POD_NAMESPACE_KEY);
|
||||
return podNamespace == null ? "target/logs/" : "/mnt/app-logdata/" + podNamespace;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package cn.axzo.framework.logger;
|
||||
|
||||
import ch.qos.logback.core.PropertyDefinerBase;
|
||||
|
||||
/**
|
||||
* 获取 Pod Namespaces变量值
|
||||
*/
|
||||
public class PodNamespacePropertyDefiner extends PropertyDefinerBase {
|
||||
|
||||
private static final String POD_NAMESPACE_KEY = "MY_POD_NAMESPACE";
|
||||
|
||||
@Override
|
||||
public String getPropertyValue() {
|
||||
return SystemPropertyResolver.getPropertyValue(POD_NAMESPACE_KEY);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package cn.axzo.framework.logger;
|
||||
|
||||
import java.security.AccessControlException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 从系统变量中解析属性
|
||||
*/
|
||||
public class SystemPropertyResolver {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(SystemPropertyResolver.class);
|
||||
|
||||
public static String getPropertyValue(String key) {
|
||||
String envValue = getSystemEnvironment().get(key);
|
||||
return envValue == null ? getSystemProperties().getProperty(key) : envValue;
|
||||
}
|
||||
|
||||
private static Map<String, String> getSystemEnvironment() {
|
||||
try {
|
||||
return System.getenv();
|
||||
} catch (AccessControlException ex) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Caught AccessControlException when accessing system environment, its value will be returned [null]. Reason: "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
private static Properties getSystemProperties() {
|
||||
try {
|
||||
return System.getProperties();
|
||||
} catch (AccessControlException ex) {
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Caught AccessControlException when accessing system property, its value will be returned [null]. Reason: "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
return new Properties();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<included>
|
||||
<!-- 引用 Spring Boot 的 logback 基础配置 -->
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
||||
<!-- spring变量 -->
|
||||
<springProperty scope="context" name="appName" source="spring.application.name"/>
|
||||
|
||||
<define name="hostname" class="cn.axzo.framework.logger.HostNamePropertyDefiner"/>
|
||||
<define name="LOG_PREFIX" class="cn.axzo.framework.logger.LogPrefixhPropertyDefiner"/>
|
||||
|
||||
<property name="LOG_FILE" value="${appName}.log"/>
|
||||
<!--日志路径-->
|
||||
<property name="LOG_PATH" value="${LOG_PREFIX}/${appName}/"/>
|
||||
<!-- 日志最大的历史 7天 -->
|
||||
<property name="MAX_HISTORY" value="7"/>
|
||||
|
||||
<!--默认日志输出模式-->
|
||||
<property name="PATTERN_CONSOLE" value="%date{HH:mm:ss} %highlight(%-5level) [%15thread] %cyan([%class{36}#%M:%L]) %msg%n"/>
|
||||
<property name="PATTERN_FILE" value="%date{yyyy-MM-dd HH:mm:ss} %-5level --- [%15thread] [%X{ctxLogId}] %logger: %msg%n"/>
|
||||
<property name="PATTERN_SKWALKING" value="%d{yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%thread] [%tid] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
|
||||
|
||||
<contextName>${appName}</contextName>
|
||||
|
||||
<!-- 控制台 Appender -->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${PATTERN_CONSOLE}</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 文件 Appender -->
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
|
||||
<pattern>${PATTERN_FILE}</pattern>
|
||||
</layout>
|
||||
</encoder>
|
||||
<!-- 日志文件名 -->
|
||||
<file>${LOG_PATH}/${LOG_FILE}</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!-- 滚动后的日志文件名 -->
|
||||
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
|
||||
<!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
|
||||
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
|
||||
<!-- 日志文件,到达多少容量,进行滚动 -->
|
||||
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
|
||||
<!-- 日志文件的总大小,0 表示不限制 -->
|
||||
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-1GB}</totalSizeCap>
|
||||
<!-- 日志文件的保留天数 -->
|
||||
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
<!-- 异步写入日志,提升性能 -->
|
||||
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
|
||||
<discardingThreshold>0</discardingThreshold>
|
||||
<!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
|
||||
<queueSize>256</queueSize>
|
||||
<appender-ref ref="FILE"/>
|
||||
</appender>
|
||||
|
||||
<!-- 接入了skywalking才配置该项 -->
|
||||
<appender name="SKYWALKING" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
|
||||
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
|
||||
<Pattern>${PATTERN_SKWALKING}</Pattern>
|
||||
</layout>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 控制台输出LOGSTASH JSON日志 -->
|
||||
<appender name="LOGSTASH" class="ch.qos.logback.core.ConsoleAppender" addtivity="false">
|
||||
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
|
||||
<providers>
|
||||
<timestamp>
|
||||
<fieldName>@timestamp</fieldName>
|
||||
<pattern>yyyy-MM-dd'T'HH:mm:ss.SSSx</pattern>
|
||||
<timeZone>GMT+8</timeZone>
|
||||
</timestamp>
|
||||
<pattern>
|
||||
<pattern>
|
||||
{
|
||||
"app":"${appName}",
|
||||
"level":"%level",
|
||||
"traceId":"%X{ctxLogId}",
|
||||
"thread":"%thread",
|
||||
"class":"%logger{40}",
|
||||
"message":"%message",
|
||||
"m":"#asJson{%message}",
|
||||
"error_level":"%X{errorLevel}",
|
||||
"error_type":"%X{errorType}",
|
||||
"stack_trace":"%exception{20}"
|
||||
}
|
||||
</pattern>
|
||||
</pattern>
|
||||
</providers>
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- 本地环境 -->
|
||||
<springProfile name="local,dev">
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</root>
|
||||
</springProfile>
|
||||
<!-- 其它环境 -->
|
||||
<springProfile name="test,test1,uat,pre,master,default,pre-new">
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="ASYNC"/>
|
||||
<appender-ref ref="LOGSTASH"/>
|
||||
<appender-ref ref="SKYWALKING"/>
|
||||
</root>
|
||||
</springProfile>
|
||||
|
||||
</included>
|
||||
18
pom.xml
18
pom.xml
@ -19,7 +19,6 @@
|
||||
|
||||
<properties>
|
||||
<revision>2.0.0-SNAPSHOT</revision>
|
||||
<axzo-bom.version>2.0.0-SNAPSHOT</axzo-bom.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
@ -32,18 +31,17 @@
|
||||
<module>canal-alarm</module>
|
||||
<module>axzo-auth-spring-boot-starter</module>
|
||||
<module>axzo-test-spring-boot-starter</module>
|
||||
<module>axzo-logger-spring-boot-starter</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.infra</groupId>
|
||||
<artifactId>axzo-bom</artifactId>
|
||||
<version>${axzo-bom.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
Loading…
Reference in New Issue
Block a user