diff --git a/axzo-loger-spring-boot-starter/README.md b/axzo-loger-spring-boot-starter/README.md new file mode 100644 index 0000000..0d19753 --- /dev/null +++ b/axzo-loger-spring-boot-starter/README.md @@ -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 + + + cn.axzo.framework + axzo-logger-spring-boot-starter + 2.0.0-SNAPSHOT + +``` + +### 2、日志配置(logback-spring.xml) + +``` xml + + + + + + + + + + +``` + diff --git a/axzo-loger-spring-boot-starter/pom.xml b/axzo-loger-spring-boot-starter/pom.xml new file mode 100644 index 0000000..d4d569c --- /dev/null +++ b/axzo-loger-spring-boot-starter/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + + cn.axzo.framework + axzo-framework + ${revision} + ../pom.xml + + + axzo-logger-spring-boot-starter + 2.0.0-SNAPSHOT + + axzo-logger-spring-boot-starter + 安心筑日志支持库 + + + + org.springframework.boot + spring-boot + true + + + org.springframework.boot + spring-boot-starter-logging + + + org.apache.skywalking + apm-toolkit-logback-1.x + + + net.logstash.logback + logstash-logback-encoder + + + diff --git a/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/DynamicLoggerManager.java b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/DynamicLoggerManager.java new file mode 100644 index 0000000..9e795b1 --- /dev/null +++ b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/DynamicLoggerManager.java @@ -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 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 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 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; + } + +} diff --git a/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/HostNamePropertyDefiner.java b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/HostNamePropertyDefiner.java new file mode 100644 index 0000000..2387171 --- /dev/null +++ b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/HostNamePropertyDefiner.java @@ -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; + } + +} diff --git a/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/LogPrefixhPropertyDefiner.java b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/LogPrefixhPropertyDefiner.java new file mode 100644 index 0000000..a194fca --- /dev/null +++ b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/LogPrefixhPropertyDefiner.java @@ -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; + } +} diff --git a/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/PodNamespacePropertyDefiner.java b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/PodNamespacePropertyDefiner.java new file mode 100644 index 0000000..b62b5ff --- /dev/null +++ b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/PodNamespacePropertyDefiner.java @@ -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); + } +} diff --git a/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/SystemPropertyResolver.java b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/SystemPropertyResolver.java new file mode 100644 index 0000000..226c1e4 --- /dev/null +++ b/axzo-loger-spring-boot-starter/src/main/java/cn/axzo/framework/logger/SystemPropertyResolver.java @@ -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 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(); + } + } + +} diff --git a/axzo-loger-spring-boot-starter/src/main/resources/logback/logback-axzo.xml b/axzo-loger-spring-boot-starter/src/main/resources/logback/logback-axzo.xml new file mode 100644 index 0000000..d4ef8e3 --- /dev/null +++ b/axzo-loger-spring-boot-starter/src/main/resources/logback/logback-axzo.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + ${appName} + + + + + ${PATTERN_CONSOLE} + UTF-8 + + + + + + + + ${PATTERN_FILE} + + + + ${LOG_PATH}/${LOG_FILE} + + + ${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz} + + ${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false} + + ${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB} + + ${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-1GB} + + ${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30} + + + + + + 0 + + 256 + + + + + + + + ${PATTERN_SKWALKING} + + + + + + + + + + @timestamp + yyyy-MM-dd'T'HH:mm:ss.SSSx + GMT+8 + + + + { + "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}" + } + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0865485..a65e897 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,6 @@ 2.0.0-SNAPSHOT - 2.0.0-SNAPSHOT @@ -32,18 +31,17 @@ canal-alarm axzo-auth-spring-boot-starter axzo-test-spring-boot-starter + axzo-logger-spring-boot-starter - + - - - cn.axzo.infra - axzo-bom - ${axzo-bom.version} - pom - import - - + + + cn.axzo.framework + axzo-common + ${project.version} + + \ No newline at end of file