From 584983337db3e423f1dd674f58f24e9bfe0c46a8 Mon Sep 17 00:00:00 2001 From: leojames Date: Thu, 28 Dec 2023 15:03:08 +0800 Subject: [PATCH] using ark plugin for all adapter --- .../src/main/resources/application.properties | 2 +- sofa-serverless-runtime/pom.xml | 2 +- .../sofa-serverless-adapter-apollo/pom.xml | 7 +- .../sofa-serverless-adapter-dubbo2.6/pom.xml | 43 +- .../adapter/Dubbo26AdapterActivator.java | 35 ++ .../sofa-serverless-adapter-log4j2/pom.xml | 140 +++---- .../adapter/Log4j2AdapterActivator.java | 35 ++ ...ServerlessLog4j2SpringContextListener.java | 111 ------ .../logging/log4j2/Log4J2LoggingSystem.java} | 367 ++++++++++-------- .../main/resources/META-INF/spring.factories | 2 - .../sofa-serverless-base-starter/pom.xml | 38 +- 11 files changed, 426 insertions(+), 356 deletions(-) create mode 100644 sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-dubbo2.6/src/main/java/com/alipay/sofa/serverless/adapter/Dubbo26AdapterActivator.java create mode 100644 sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/adapter/Log4j2AdapterActivator.java delete mode 100644 sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2SpringContextListener.java rename sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/{com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2LoggingSystem.java => org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java} (55%) delete mode 100644 sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/resources/META-INF/spring.factories diff --git a/samples/springboot-samples/web/tomcat/biz2/src/main/resources/application.properties b/samples/springboot-samples/web/tomcat/biz2/src/main/resources/application.properties index 9f1938c7a..9973a1700 100644 --- a/samples/springboot-samples/web/tomcat/biz2/src/main/resources/application.properties +++ b/samples/springboot-samples/web/tomcat/biz2/src/main/resources/application.properties @@ -1,4 +1,4 @@ spring.application.name=biz2 logging.file.path=./web/tomcat/logs -logging.path=./web/tomcat/logs \ No newline at end of file +logging.path=./web/tomcat/logs diff --git a/sofa-serverless-runtime/pom.xml b/sofa-serverless-runtime/pom.xml index d66f1a533..a80f7aad3 100644 --- a/sofa-serverless-runtime/pom.xml +++ b/sofa-serverless-runtime/pom.xml @@ -9,7 +9,7 @@ pom - 0.5.5 + 0.5.6-SNAPSHOT 2.2.5 2.7.15 1.2.9 diff --git a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-apollo/pom.xml b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-apollo/pom.xml index 00ae7f387..aa7c60912 100644 --- a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-apollo/pom.xml +++ b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-apollo/pom.xml @@ -36,11 +36,6 @@ sofa-ark-spi provided - - com.alipay.sofa - sofa-ark-api - provided - @@ -76,4 +71,4 @@ - \ No newline at end of file + diff --git a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-dubbo2.6/pom.xml b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-dubbo2.6/pom.xml index aa9a6a8de..cc135826c 100644 --- a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-dubbo2.6/pom.xml +++ b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-dubbo2.6/pom.xml @@ -19,6 +19,47 @@ 2.6.12 provided + + com.alipay.sofa + sofa-ark-spi + provided + - \ No newline at end of file + + + + com.alipay.sofa + sofa-ark-plugin-maven-plugin + ${sofa.ark.version} + + + default-cli + + ark-plugin + + + + + com.alipay.sofa.serverless.adapter.Dubbo26AdapterActivator + + + override + + com.alibaba.dubbo.common + com.alibaba.dubbo.config.spring.extension + com.alibaba.dubbo.rpc.protocol.dubbo + + + + *:*:* + com.alipay.sofa.serverless:sofa-serverless-adapter-dubbo2.6 + + + + + + + + + diff --git a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-dubbo2.6/src/main/java/com/alipay/sofa/serverless/adapter/Dubbo26AdapterActivator.java b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-dubbo2.6/src/main/java/com/alipay/sofa/serverless/adapter/Dubbo26AdapterActivator.java new file mode 100644 index 000000000..ad378bc87 --- /dev/null +++ b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-dubbo2.6/src/main/java/com/alipay/sofa/serverless/adapter/Dubbo26AdapterActivator.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.serverless.adapter; + +import com.alipay.sofa.ark.spi.model.PluginContext; +import com.alipay.sofa.ark.spi.service.PluginActivator; + +/** + * @author lvjing2 + * @since 0.5.5 + */ +public class Dubbo26AdapterActivator implements PluginActivator { + @Override + public void start(PluginContext context) { + } + + @Override + public void stop(PluginContext context) { + // no op + } +} diff --git a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/pom.xml b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/pom.xml index 979e33df9..0b1b6e515 100644 --- a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/pom.xml +++ b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/pom.xml @@ -1,73 +1,75 @@ - 4.0.0 - - com.alipay.sofa.serverless - sofa-serverless-adapter-ext - ${revision} - ../pom.xml - - sofa-serverless-adapter-log4j2 - ${revision} + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + com.alipay.sofa.serverless + sofa-serverless-adapter-ext + ${revision} + ../pom.xml + + sofa-serverless-adapter-log4j2 + ${revision} - - - org.springframework.boot - spring-boot-starter - ${spring.boot.version} - provided - - - org.springframework.boot - spring-boot-starter-logging - - - - - org.springframework.boot - spring-boot-starter-log4j2 - ${spring.boot.version} - provided - - - org.springframework.boot - spring-boot-starter-test - test - - - android-json - com.vaadin.external.google - - - - - junit - junit - test - - - commons-io - commons-io - 2.11.0 - test - - - com.github.stefanbirkner - system-rules - 1.16.0 - test - - - juint - junit-dep - - - - - org.springframework.boot - spring-boot-actuator - test - - + + + org.springframework.boot + spring-boot-starter + ${spring.boot.version} + provided + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + ${spring.boot.version} + provided + + + com.alipay.sofa + sofa-ark-spi + provided + + + + + + + com.alipay.sofa + sofa-ark-plugin-maven-plugin + ${sofa.ark.version} + + + default-cli + + ark-plugin + + + + + com.alipay.sofa.serverless.adapter.Log4j2AdapterActivator + + + override + + + org.springframework.boot.logging.log4j2.Log4J2LoggingSystem + + + + + *:*:* + com.alipay.sofa.serverless:sofa-serverless-adapter-log4j2 + + + + + + + diff --git a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/adapter/Log4j2AdapterActivator.java b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/adapter/Log4j2AdapterActivator.java new file mode 100644 index 000000000..6f7c44c75 --- /dev/null +++ b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/adapter/Log4j2AdapterActivator.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.serverless.adapter; + +import com.alipay.sofa.ark.spi.model.PluginContext; +import com.alipay.sofa.ark.spi.service.PluginActivator; + +/** + * @author lvjing2 + * @since 0.5.5 + */ +public class Log4j2AdapterActivator implements PluginActivator { + @Override + public void start(PluginContext context) { + } + + @Override + public void stop(PluginContext context) { + // no op + } +} diff --git a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2SpringContextListener.java b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2SpringContextListener.java deleted file mode 100644 index 231b32cf7..000000000 --- a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2SpringContextListener.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alipay.sofa.serverless.log4j2; - -import org.apache.logging.log4j.ThreadContext; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; -import org.springframework.boot.context.event.ApplicationStartingEvent; -import org.springframework.boot.logging.LoggingSystem; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.event.GenericApplicationListener; -import org.springframework.core.Ordered; -import org.springframework.core.ResolvableType; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.EnumerablePropertySource; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 支持将配置转换为 log4j2 context. - * 1. 设置LoggingSystem=SOFAServerlessLog4j2LoggingSystem - * 2. 添加属性到log4j2 ThreadContext - * - * @author ruoshan - * @version $Id: AlipayLog4j2SpringContextListener.java, v 0.1 2018年08月23日 10:32 PM ruoshan Exp $ - */ -public class SOFAServerlessLog4j2SpringContextListener implements GenericApplicationListener, - Ordered { - - private static Class[] EVENT_TYPES = { ApplicationStartingEvent.class, - ApplicationEnvironmentPreparedEvent.class }; - - private static Class[] SOURCE_TYPES = { SpringApplication.class, ApplicationContext.class }; - - @Override - public boolean supportsEventType(ResolvableType eventType) { - return isAssignableFrom(eventType.getRawClass(), EVENT_TYPES); - } - - @Override - public boolean supportsSourceType(Class sourceType) { - return isAssignableFrom(sourceType, SOURCE_TYPES); - } - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof ApplicationStartingEvent) { - onApplicationStartingEvent(); - } else if (event instanceof ApplicationEnvironmentPreparedEvent) { - onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event); - } - } - - private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) { - ConfigurableEnvironment environment = event.getEnvironment(); - Map configMap = new ConcurrentHashMap<>(); - Set configKeys = new HashSet<>(); - environment.getPropertySources().stream().filter(propertySource -> propertySource instanceof EnumerablePropertySource) - .forEach(propertySource -> configKeys.addAll(Arrays.asList(((EnumerablePropertySource)propertySource).getPropertyNames()))); - - configKeys.forEach(key -> { - try { - configMap.put(key, environment.getProperty(key)); - } catch (Throwable t) { - // ignore, 异常在 AlipayPrintEnvironmentListener 中打印 - } - }); - - configMap.forEach(ThreadContext::put); - } - - private void onApplicationStartingEvent() { - System.setProperty(LoggingSystem.class.getName(), - SOFAServerlessLog4j2LoggingSystem.class.getName()); - } - - @Override - public int getOrder() { - return HIGHEST_PRECEDENCE + 19; - } - - private boolean isAssignableFrom(Class type, Class... supportedTypes) { - if (type != null) { - for (Class supportedType : supportedTypes) { - if (supportedType.isAssignableFrom(type)) { - return true; - } - } - } - return false; - } -} diff --git a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2LoggingSystem.java b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java similarity index 55% rename from sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2LoggingSystem.java rename to sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java index 7c0a6f7ff..d61788d18 100644 --- a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2/SOFAServerlessLog4j2LoggingSystem.java +++ b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java @@ -1,12 +1,11 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Copyright 2012-2023 the original author or authors. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.serverless.log4j2; + +package org.springframework.boot.logging.log4j2; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; @@ -28,51 +39,44 @@ import org.apache.logging.log4j.core.config.ConfigurationFactory; import org.apache.logging.log4j.core.config.ConfigurationSource; import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.logging.log4j.core.config.composite.CompositeConfiguration; import org.apache.logging.log4j.core.filter.AbstractFilter; import org.apache.logging.log4j.core.util.NameUtil; import org.apache.logging.log4j.message.Message; + import org.springframework.boot.context.properties.bind.BindResult; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.logging.LogFile; import org.springframework.boot.logging.LogLevel; import org.springframework.boot.logging.LoggerConfiguration; +import org.springframework.boot.logging.LoggerConfiguration.LevelConfiguration; import org.springframework.boot.logging.LoggingInitializationContext; import org.springframework.boot.logging.LoggingSystem; import org.springframework.boot.logging.LoggingSystemFactory; -import org.springframework.boot.logging.log4j2.Log4J2LoggingSystem; +import org.springframework.boot.logging.Slf4JLoggingSystem; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.ResourceUtils; import org.springframework.util.StringUtils; -import org.springframework.util.SystemPropertyUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.ConsoleHandler; -import java.util.logging.Handler; /** - * SpringBoot 默认使用 log4j2.6.2 的 API,与 log4j2.8.2 不兼容 + * {@link LoggingSystem} for Log4j 2. * - * @author ruoshan - * @version $Id: AlipayLog4J2LoggingSystem.java, v 0.1 2018年08月24日 12:09 PM ruoshan Exp $ + * @author Daniel Fullarton + * @author Andy Wilkinson + * @author Alexander Heusingfeld + * @author Ben Hale + * @since 1.2.0 */ -public class SOFAServerlessLog4j2LoggingSystem extends Log4J2LoggingSystem { - - private static final String FILE_PROTOCOL = "file"; +public class Log4J2LoggingSystem extends Slf4JLoggingSystem { - private static final String DEFAULT_LOG4j_CONFIG_PATH = "classpath:org/springframework/boot/logging/log4j2/"; + private static final String FILE_PROTOCOL = "file"; - private static final LogLevels LEVELS = new LogLevels<>(); + private static final LogLevels LEVELS = new LogLevels<>(); static { LEVELS.map(LogLevel.TRACE, Level.TRACE); @@ -84,139 +88,154 @@ public class SOFAServerlessLog4j2LoggingSystem extends Log4J2LoggingSystem { LEVELS.map(LogLevel.OFF, Level.OFF); } - private static final Filter FILTER = new AbstractFilter() { - - @Override - public Result filter(LogEvent event) { - return Result.DENY; - } - - @Override - public Result filter(Logger logger, - Level level, - Marker marker, - Message msg, - Throwable t) { - return Result.DENY; - } - - @Override - public Result filter(Logger logger, - Level level, - Marker marker, - Object msg, - Throwable t) { - return Result.DENY; - } - - @Override - public Result filter(Logger logger, - Level level, - Marker marker, - String msg, - Object... params) { - return Result.DENY; - } - - }; - - public SOFAServerlessLog4j2LoggingSystem(ClassLoader classLoader) { + private static final Filter FILTER = new AbstractFilter() { + + @Override + public Result filter(LogEvent event) { + return Result.DENY; + } + + @Override + public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) { + return Result.DENY; + } + + @Override + public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) { + return Result.DENY; + } + + @Override + public Result filter(Logger logger, Level level, Marker marker, String msg, Object... params) { + return Result.DENY; + } + + }; + + public Log4J2LoggingSystem(ClassLoader classLoader) { super(classLoader); } @Override - public void beforeInitialize() { - LoggerContext loggerContext = getLoggerContext(); - if (isAlreadyInitialized(loggerContext)) { - return; + protected String[] getStandardConfigLocations() { + return getCurrentlySupportedConfigLocations(); + } + + private String[] getCurrentlySupportedConfigLocations() { + List supportedConfigLocations = new ArrayList<>(); + addTestFiles(supportedConfigLocations); + supportedConfigLocations.add("log4j2.properties"); + if (isClassAvailable("com.fasterxml.jackson.dataformat.yaml.YAMLParser")) { + Collections.addAll(supportedConfigLocations, "log4j2.yaml", "log4j2.yml"); } - configureJdkLoggingBridgeHandler(); - loggerContext.getConfiguration().addFilter(FILTER); + if (isClassAvailable("com.fasterxml.jackson.databind.ObjectMapper")) { + Collections.addAll(supportedConfigLocations, "log4j2.json", "log4j2.jsn"); + } + supportedConfigLocations.add("log4j2.xml"); + return StringUtils.toStringArray(supportedConfigLocations); } - private void configureJdkLoggingBridgeHandler() { - try { - this.removeJdkLoggingBridgeHandler(); - } catch (Throwable var2) { + private void addTestFiles(List supportedConfigLocations) { + supportedConfigLocations.add("log4j2-test.properties"); + if (isClassAvailable("com.fasterxml.jackson.dataformat.yaml.YAMLParser")) { + Collections.addAll(supportedConfigLocations, "log4j2-test.yaml", "log4j2-test.yml"); } + if (isClassAvailable("com.fasterxml.jackson.databind.ObjectMapper")) { + Collections.addAll(supportedConfigLocations, "log4j2-test.json", "log4j2-test.jsn"); + } + supportedConfigLocations.add("log4j2-test.xml"); + } + protected boolean isClassAvailable(String className) { + return ClassUtils.isPresent(className, getClassLoader()); } @Override - public void initialize(LoggingInitializationContext initializationContext, - String configLocation, LogFile logFile) { + public void beforeInitialize() { LoggerContext loggerContext = getLoggerContext(); if (isAlreadyInitialized(loggerContext)) { return; } - loggerContext.getConfiguration().removeFilter(FILTER); - - if (StringUtils.hasLength(configLocation)) { - initializeWithSpecificConfig(initializationContext, configLocation, logFile); - return; - } - initializeWithConventions(initializationContext, logFile); - - markAsInitialized(loggerContext); - } - - private void initializeWithSpecificConfig(LoggingInitializationContext initializationContext, - String configLocation, LogFile logFile) { - configLocation = SystemPropertyUtils.resolvePlaceholders(configLocation); - loadConfiguration(initializationContext, configLocation, logFile); + super.beforeInitialize(); + loggerContext.getConfiguration().addFilter(FILTER); } - private void initializeWithConventions(LoggingInitializationContext initializationContext, - LogFile logFile) { - String config = getSelfInitializationConfig(); - if (config != null && logFile == null) { - // self initialization has occurred, reinitialize in case of property changes - reinitialize(initializationContext); - return; - } - if (config == null) { - config = getSpringInitializationConfig(); - } - if (config != null) { - loadConfiguration(initializationContext, config, logFile); + @Override + public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) { + LoggerContext loggerContext = getLoggerContext(); + if (isAlreadyInitialized(loggerContext)) { return; } - loadDefaults(initializationContext, logFile); + loggerContext.getConfiguration().removeFilter(FILTER); + super.initialize(initializationContext, configLocation, logFile); + markAsInitialized(loggerContext); } @Override protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) { if (logFile != null) { - loadConfiguration(DEFAULT_LOG4j_CONFIG_PATH + "log4j2-file.xml", logFile, - getOverrides(initializationContext)); - } else { - loadConfiguration(DEFAULT_LOG4j_CONFIG_PATH + "log4j2.xml", logFile, - getOverrides(initializationContext)); + loadConfiguration(getPackagedConfigFile("log4j2-file.xml"), logFile, getOverrides(initializationContext)); + } + else { + loadConfiguration(getPackagedConfigFile("log4j2.xml"), logFile, getOverrides(initializationContext)); } } private List getOverrides(LoggingInitializationContext initializationContext) { BindResult> overrides = Binder.get(initializationContext.getEnvironment()) - .bind("logging.log4j2.config.override", Bindable.listOf(String.class)); + .bind("logging.log4j2.config.override", Bindable.listOf(String.class)); return overrides.orElse(Collections.emptyList()); } + @Override + protected void loadConfiguration(LoggingInitializationContext initializationContext, String location, + LogFile logFile) { + super.loadConfiguration(initializationContext, location, logFile); + loadConfiguration(location, logFile, getOverrides(initializationContext)); + } + + /** + * Load the configuration from the given {@code location}. + * @param location the location + * @param logFile log file configuration + * @deprecated since 2.6.0 for removal in 3.0.0 in favor of + * {@link #loadConfiguration(String, LogFile, List)} + */ + @Deprecated protected void loadConfiguration(String location, LogFile logFile) { + this.loadConfiguration(location, logFile, Collections.emptyList()); + } + + /** + * Load the configuration from the given {@code location}, creating a composite using + * the configuration from the given {@code overrides}. + * @param location the location + * @param logFile log file configuration + * @param overrides the overriding locations + * @since 2.6.0 + */ + protected void loadConfiguration(String location, LogFile logFile, List overrides) { Assert.notNull(location, "Location must not be null"); try { + List configurations = new ArrayList<>(); LoggerContext context = getLoggerContext(); - URL url = ResourceUtils.getURL(location); - ConfigurationSource source = getConfigurationSource(url); - - context.start(ConfigurationFactory.getInstance().getConfiguration(context, source)); - } catch (Exception ex) { - throw new IllegalStateException("Could not initialize Log4J2 logging from " + location, - ex); + configurations.add(load(location, context)); + for (String override : overrides) { + configurations.add(load(override, context)); + } + Configuration configuration = (configurations.size() > 1) ? createComposite(configurations) + : configurations.iterator().next(); + context.start(configuration); + } + catch (Exception ex) { + throw new IllegalStateException("Could not initialize Log4J2 logging from " + location, ex); } } - protected void loadConfiguration(String location, LogFile logFile, List overrides) { - loadConfiguration(location, logFile); + private Configuration load(String location, LoggerContext context) throws IOException { + URL url = ResourceUtils.getURL(location); + ConfigurationSource source = getConfigurationSource(url); + return ConfigurationFactory.getInstance().getConfiguration(context, source); } private ConfigurationSource getConfigurationSource(URL url) throws IOException { @@ -227,9 +246,43 @@ private ConfigurationSource getConfigurationSource(URL url) throws IOException { return new ConfigurationSource(stream, url); } + private CompositeConfiguration createComposite(List configurations) { + return new CompositeConfiguration( + configurations.stream().map(AbstractConfiguration.class::cast).collect(Collectors.toList())); + } + @Override protected void reinitialize(LoggingInitializationContext initializationContext) { - getLoggerContext().reconfigure(); + List overrides = getOverrides(initializationContext); + if (!CollectionUtils.isEmpty(overrides)) { + reinitializeWithOverrides(overrides); + } + else { + LoggerContext context = getLoggerContext(); + context.reconfigure(); + } + } + + private void reinitializeWithOverrides(List overrides) { + LoggerContext context = getLoggerContext(); + Configuration base = context.getConfiguration(); + List configurations = new ArrayList<>(); + configurations.add((AbstractConfiguration) base); + for (String override : overrides) { + try { + configurations.add((AbstractConfiguration) load(override, context)); + } + catch (IOException ex) { + throw new RuntimeException("Failed to load overriding configuration from '" + override + "'", ex); + } + } + CompositeConfiguration composite = new CompositeConfiguration(configurations); + context.reconfigure(composite); + } + + @Override + public Set getSupportedLogLevels() { + return LEVELS.getSupported(); } @Override @@ -241,7 +294,8 @@ private void setLogLevel(String loggerName, Level level) { LoggerConfig logger = getLogger(loggerName); if (level == null) { clearLogLevel(loggerName, logger); - } else { + } + else { setLogLevel(loggerName, logger, level); } getLoggerContext().updateLoggers(); @@ -250,16 +304,18 @@ private void setLogLevel(String loggerName, Level level) { private void clearLogLevel(String loggerName, LoggerConfig logger) { if (logger instanceof LevelSetLoggerConfig) { getLoggerContext().getConfiguration().removeLogger(loggerName); - } else { + } + else { logger.setLevel(null); } } private void setLogLevel(String loggerName, LoggerConfig logger, Level level) { if (logger == null) { - getLoggerContext().getConfiguration().addLogger(loggerName, - new LevelSetLoggerConfig(loggerName, level, true)); - } else { + getLoggerContext().getConfiguration() + .addLogger(loggerName, new LevelSetLoggerConfig(loggerName, level, true)); + } + else { logger.setLevel(level); } } @@ -307,48 +363,33 @@ private LoggerConfiguration convertLoggerConfig(String name, LoggerConfig logger if (loggerConfig == null) { return null; } - LogLevel level = LEVELS.convertNativeToSystem(loggerConfig.getLevel()); + LevelConfiguration effectiveLevelConfiguration = getLevelConfiguration(loggerConfig.getLevel()); if (!StringUtils.hasLength(name) || LogManager.ROOT_LOGGER_NAME.equals(name)) { name = ROOT_LOGGER_NAME; } - boolean isLoggerConfigured = loggerConfig.getName().equals(name); - LogLevel configuredLevel = (isLoggerConfigured) ? level : null; - return new LoggerConfiguration(name, configuredLevel, level); + boolean isAssigned = loggerConfig.getName().equals(name); + LevelConfiguration assignedLevelConfiguration = (!isAssigned) ? null : effectiveLevelConfiguration; + return new LoggerConfiguration(name, assignedLevelConfiguration, effectiveLevelConfiguration); + } + + private LevelConfiguration getLevelConfiguration(Level level) { + LogLevel logLevel = LEVELS.convertNativeToSystem(level); + return (logLevel != null) ? LevelConfiguration.of(logLevel) : LevelConfiguration.ofCustom(level.name()); + } + + @Override + public Runnable getShutdownHandler() { + return () -> getLoggerContext().stop(); } @Override public void cleanUp() { - try { - removeJdkLoggingBridgeHandler(); - } catch (Exception e) { - // Ignore and continue - } + super.cleanUp(); LoggerContext loggerContext = getLoggerContext(); markAsUninitialized(loggerContext); loggerContext.getConfiguration().removeFilter(FILTER); } - private void removeJdkLoggingBridgeHandler() { - try { - removeDefaultRootHandler(); - } catch (Throwable ex) { - // Ignore and continue - } - } - - private void removeDefaultRootHandler() { - try { - java.util.logging.Logger rootLogger = java.util.logging.LogManager.getLogManager() - .getLogger(""); - Handler[] handlers = rootLogger.getHandlers(); - if (handlers.length == 1 && handlers[0] instanceof ConsoleHandler) { - rootLogger.removeHandler(handlers[0]); - } - } catch (Throwable ex) { - // Ignore and continue - } - } - private LoggerConfig getLogger(String name) { boolean isRootLogger = !StringUtils.hasLength(name) || ROOT_LOGGER_NAME.equals(name); return findLogger(isRootLogger ? LogManager.ROOT_LOGGER_NAME : name); @@ -364,7 +405,7 @@ private LoggerConfig findLogger(String name) { private LoggerContext getLoggerContext() { return (LoggerContext) LogManager.getContext( - Thread.currentThread().getContextClassLoader(), false); + Thread.currentThread().getContextClassLoader(), false); } private boolean isAlreadyInitialized(LoggerContext loggerContext) { @@ -386,10 +427,7 @@ private void markAsUninitialized(LoggerContext loggerContext) { public static class Factory implements LoggingSystemFactory { private static final boolean PRESENT = ClassUtils - .isPresent( - "org.apache.logging.log4j.core.impl.Log4jContextFactory", - Log4J2LoggingSystem.Factory.class - .getClassLoader()); + .isPresent("org.apache.logging.log4j.core.impl.Log4jContextFactory", Factory.class.getClassLoader()); @Override public LoggingSystem getLoggingSystem(ClassLoader classLoader) { @@ -411,4 +449,5 @@ private static class LevelSetLoggerConfig extends LoggerConfig { } } -} \ No newline at end of file + +} diff --git a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/resources/META-INF/spring.factories b/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/resources/META-INF/spring.factories deleted file mode 100644 index ce9c6afe3..000000000 --- a/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.context.ApplicationListener=\ - com.alipay.sofa.serverless.log4j2.SOFAServerlessLog4j2SpringContextListener diff --git a/sofa-serverless-runtime/sofa-serverless-base-starter/pom.xml b/sofa-serverless-runtime/sofa-serverless-base-starter/pom.xml index 0a75bf765..320319b5e 100644 --- a/sofa-serverless-runtime/sofa-serverless-base-starter/pom.xml +++ b/sofa-serverless-runtime/sofa-serverless-base-starter/pom.xml @@ -34,5 +34,41 @@ sofa-serverless-base-plugin + + + + + + + + + + + + + + + com.alipay.sofa.serverless + sofa-serverless-app-starter + ${revision} + + + + com.alipay.sofa.serverless + sofa-serverless-adapter-apollo + ${revision} + + + + com.alipay.sofa.serverless + sofa-serverless-adapter-log4j2 + ${revision} + + + + com.alipay.sofa.serverless + sofa-serverless-adapter-dubbo2.6 + ${revision} + - \ No newline at end of file +