diff --git a/.github/workflows/plugins-test.1.yaml b/.github/workflows/plugins-test.1.yaml index fe2f46125..0d68244d6 100644 --- a/.github/workflows/plugins-test.1.yaml +++ b/.github/workflows/plugins-test.1.yaml @@ -56,6 +56,9 @@ jobs: - kafka-scenario - kotlin-coroutine-scenario - lettuce-scenario + - logger-logback-scenario + - logger-log4j-scenario + - logger-log4j2-scenario - mongodb-3.x-scenario - mongodb-4.x-scenario - netty-socketio-scenario diff --git a/CHANGES.md b/CHANGES.md index a6a66f0de..a06f660ab 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ Release Notes. #### Java Agent * The operation name of quartz-scheduler plugin, has been changed as the `quartz-scheduler/${className}` format. * Fix jdk-http and okhttp-3.x plugin did not overwrite the old trace header. +* Support collecting logs of log4j, log4j2, and logback in the tracing context with a new `logger-plugin`. #### OAP-Backend * Make meter receiver support MAL. diff --git a/apm-sniffer/optional-plugins/logger-plugin/pom.xml b/apm-sniffer/optional-plugins/logger-plugin/pom.xml new file mode 100644 index 000000000..057700a51 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/pom.xml @@ -0,0 +1,50 @@ + + + + + org.apache.skywalking + optional-plugins + 8.4.0-SNAPSHOT + + 4.0.0 + apm-logger-plugin + jar + + + + log4j + log4j + 1.2.17 + provided + + + org.apache.logging.log4j + log4j-core + 2.8.1 + provided + + + ch.qos.logback + logback-classic + 1.3.0-alpha5 + provided + + + + diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ContextConfig.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ContextConfig.java new file mode 100644 index 000000000..7213590c3 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ContextConfig.java @@ -0,0 +1,243 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import lombok.Setter; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException; +import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * contains all config of the logger plugin. + */ +@Getter +public class ContextConfig { + + private final LoggerConfig logbackConfig; + private final LoggerConfig log4jConfig; + private final LoggerConfig log4j2Config; + + private ContextConfig(LoggerConfig logbackConfig, LoggerConfig log4jConfig, LoggerConfig log4j2Config) { + this.logbackConfig = logbackConfig; + this.log4jConfig = log4jConfig; + this.log4j2Config = log4j2Config; + } + + public static ContextConfig getInstance() { + return HolderContextConfig.INSTANCE; + } + + //use singleton + private static class HolderContextConfig { + private final static ContextConfig INSTANCE = initContextConfig(); + + private static ContextConfig initContextConfig() { + // judge whether has config file + final ILog logger = LogManager.getLogger(HolderContextConfig.class); + LoggerConfig logbackConfig = null, log4jConfig = null, log4j2Config = null; + File configFile = null; + try { + configFile = new File(AgentPackagePath.getPath(), "/config/logger-plugin/logconfig.properties"); + } catch (AgentPackageNotFoundException e) { + logger.error("Agent package not found.", e); + } + // not has config file, make config default + if (configFile == null || !configFile.exists()) { + List packages = new ArrayList<>(); + packages.add("*"); + logbackConfig = new LoggerConfig("logback", packages, LogLevel.ERROR, false); + log4jConfig = new LoggerConfig("log4j", packages, LogLevel.ERROR, false); + log4j2Config = new LoggerConfig("log4j2", packages, LogLevel.ERROR, false); + } else { + // use config file to init ContextConfig + try (FileInputStream configFileInputStream = new FileInputStream(configFile)) { + List configs = parseConfigFile(configFileInputStream); + // initialization of variables which are described in config file + for (LoggerConfig loggerConfig : configs) { + if ("logback".equals(loggerConfig.getName())) { + logbackConfig = fillLoggerConfig(loggerConfig); + } else if ("log4j".equals(loggerConfig.getName())) { + log4jConfig = fillLoggerConfig(loggerConfig); + } else if ("log4j2".equals(loggerConfig.getName())) { + log4j2Config = fillLoggerConfig(loggerConfig); + } else { + logger.error("logconfig.properties was not configured properly.Please check again."); + return null; + } + } + } catch (IOException e) { + logger.error("Logger plugin initialized failure.Please check again.", e); + } + } + if (logbackConfig != null && logbackConfig.level == LogLevel.FATAL) { + logger.error("Logback not support fatal level. Please check again."); + logbackConfig = null; + } + return new ContextConfig(logbackConfig, log4jConfig, log4j2Config); + } + + /** + * @param fileInputStream the input stream of config file + * @return the list of configuration file analysis result objects + */ + private static List parseConfigFile(FileInputStream fileInputStream) throws IOException { + Properties p = new Properties(); + p.load(fileInputStream); + List configs = new ArrayList<>(); + LoggerConfig logback, log4j, log4j2; + logback = fillPackageAndLevel(p.getProperty("logback.packages"), p.getProperty("logback.level")); + log4j = fillPackageAndLevel(p.getProperty("log4j.packages"), p.getProperty("log4j.level")); + log4j2 = fillPackageAndLevel(p.getProperty("log4j2.packages"), p.getProperty("log4j2.level")); + if (logback != null) { + logback.setName("logback"); + configs.add(logback); + } + if (log4j != null) { + log4j.setName("log4j"); + configs.add(log4j); + } + if (log4j2 != null) { + log4j2.setName("log4j2"); + configs.add(log4j2); + } + return configs; + } + + private static LoggerConfig fillPackageAndLevel(String packages, String level) { + LoggerConfig loggerConfig = null; + if (packages != null || level != null) { + loggerConfig = new LoggerConfig(); + if (packages != null) { + loggerConfig.setPackages(splitPackages(packages)); + } + if (level != null) { + loggerConfig.setLevel(LogLevel.valueOf(level.toUpperCase())); + } + } + return loggerConfig; + } + + private static List splitPackages(String packages) { + return Arrays.asList(packages.split(",")); + } + + /** + * @param src instance which need to fill + * @return object that has been filled with default values + */ + private static LoggerConfig fillLoggerConfig(LoggerConfig src) { + if (src == null) { + return null; + } + if (src.getLevel() == null) { + src.setLevel(LogLevel.ERROR); + } + if (src.getPackages() == null) { + List packages = new ArrayList<>(); + packages.add("*"); + src.setPackages(packages); + } + return src; + } + } + + @Getter + @Setter + @AllArgsConstructor + @NoArgsConstructor + public static class LoggerConfig { + private String name; + private List packages; + private LogLevel level; + private boolean isValid; + + /** + * Encapsulate the obtained log information into a map + * + * @param loggerName the name of log system,eg:logback + * @param level which level of log need to recorder + * @param args the params of log + * @return a message map + */ + private Map toMessageMap(String loggerName, String level, Object... args) { + Map messageMap = new HashMap<>(); + messageMap.put("log.kind", loggerName); + messageMap.put("event", level); + int paramStart = 2; + // like `warn(String format, Object arg)` + if (args[0] instanceof String) { + paramStart = 1; + messageMap.put("message", args[0].toString()); + } else { + messageMap.put("message", args[1].toString()); + } + //build log + for (int i = paramStart; i < args.length; i++) { + String key = "param." + (i - paramStart + 1); + messageMap.put(key, args[i].toString()); + } + return messageMap; + } + + private boolean isLoggable(String name) { + return packages.stream().anyMatch(it -> it.equals("*") || name.startsWith(it)); + } + + public void logIfNecessary(String loggerName, String level, Object[] allArguments) { + if (ContextManager.isActive() && isLoggable(loggerName)) { + ContextManager.activeSpan().log(System.currentTimeMillis(), + toMessageMap(loggerName, level, allArguments)); + } + } + } + + public enum LogLevel { + FATAL(50), + ERROR(40), + WARN(30), + INFO(20), + DEBUG(10), + TRACE(0); + + private final int priority; + + LogLevel(int priority) { + this.priority = priority; + } + + public int getPriority() { + return priority; + } + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/DebugLog4j2LoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/DebugLog4j2LoggerInterceptor.java new file mode 100644 index 000000000..6eb0d82c3 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/DebugLog4j2LoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.logging.log4j.core.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class DebugLog4j2LoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4j2Config(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (org.apache.logging.log4j.core.Logger) objInst; + if (logger.isDebugEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/DebugLog4jLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/DebugLog4jLoggerInterceptor.java new file mode 100644 index 000000000..be8c5cbb3 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/DebugLog4jLoggerInterceptor.java @@ -0,0 +1,49 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.log4j.Level; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.log4j.Logger; + +import java.lang.reflect.Method; + +public class DebugLog4jLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4jConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) objInst; + if (logger.isEnabledFor(Level.DEBUG)) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/DebugLogbackLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/DebugLogbackLoggerInterceptor.java new file mode 100644 index 000000000..4ceb40009 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/DebugLogbackLoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import ch.qos.logback.classic.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class DebugLogbackLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLogbackConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) ((Object) objInst); + if (logger.isDebugEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ErrorLog4j2LoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ErrorLog4j2LoggerInterceptor.java new file mode 100644 index 000000000..bd418473a --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ErrorLog4j2LoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.logging.log4j.core.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class ErrorLog4j2LoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4j2Config(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (org.apache.logging.log4j.core.Logger) objInst; + if (logger.isErrorEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ErrorLog4jLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ErrorLog4jLoggerInterceptor.java new file mode 100644 index 000000000..8c7168f30 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ErrorLog4jLoggerInterceptor.java @@ -0,0 +1,49 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class ErrorLog4jLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4jConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) objInst; + if (logger.isEnabledFor(Level.ERROR)) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ErrorLogbackLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ErrorLogbackLoggerInterceptor.java new file mode 100644 index 000000000..f45e43e2d --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/ErrorLogbackLoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import ch.qos.logback.classic.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class ErrorLogbackLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLogbackConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) ((Object) objInst); + if (logger.isErrorEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/FatalLog4j2LoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/FatalLog4j2LoggerInterceptor.java new file mode 100644 index 000000000..eaf0ab9a1 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/FatalLog4j2LoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.logging.log4j.core.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class FatalLog4j2LoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4j2Config(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (org.apache.logging.log4j.core.Logger) objInst; + if (logger.isFatalEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/FatalLog4jLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/FatalLog4jLoggerInterceptor.java new file mode 100644 index 000000000..9ab99f99a --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/FatalLog4jLoggerInterceptor.java @@ -0,0 +1,49 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class FatalLog4jLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4jConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) objInst; + if (logger.isEnabledFor(Level.FATAL)) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/InfoLog4j2LoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/InfoLog4j2LoggerInterceptor.java new file mode 100644 index 000000000..24aa06234 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/InfoLog4j2LoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.logging.log4j.core.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class InfoLog4j2LoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4j2Config(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (org.apache.logging.log4j.core.Logger) objInst; + if (logger.isInfoEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/InfoLog4jLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/InfoLog4jLoggerInterceptor.java new file mode 100644 index 000000000..7d32ffaee --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/InfoLog4jLoggerInterceptor.java @@ -0,0 +1,49 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class InfoLog4jLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4jConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) objInst; + if (logger.isEnabledFor(Level.INFO)) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/InfoLogbackLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/InfoLogbackLoggerInterceptor.java new file mode 100644 index 000000000..477bbbaca --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/InfoLogbackLoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import ch.qos.logback.classic.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class InfoLogbackLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLogbackConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) ((Object) objInst); + if (logger.isInfoEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/TraceLog4j2LoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/TraceLog4j2LoggerInterceptor.java new file mode 100644 index 000000000..a3296b607 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/TraceLog4j2LoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.logging.log4j.core.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class TraceLog4j2LoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4j2Config(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (org.apache.logging.log4j.core.Logger) objInst; + if (logger.isTraceEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/TraceLog4jLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/TraceLog4jLoggerInterceptor.java new file mode 100644 index 000000000..736fa0790 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/TraceLog4jLoggerInterceptor.java @@ -0,0 +1,49 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class TraceLog4jLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4jConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) objInst; + if (logger.isEnabledFor(Level.TRACE)) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/TraceLogbackLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/TraceLogbackLoggerInterceptor.java new file mode 100644 index 000000000..ea1d81a53 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/TraceLogbackLoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import ch.qos.logback.classic.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class TraceLogbackLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLogbackConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) ((Object) objInst); + if (logger.isTraceEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/WarnLog4j2LoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/WarnLog4j2LoggerInterceptor.java new file mode 100644 index 000000000..7a8351193 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/WarnLog4j2LoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.logging.log4j.core.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class WarnLog4j2LoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4j2Config(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (org.apache.logging.log4j.core.Logger) objInst; + if (logger.isWarnEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/WarnLog4jLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/WarnLog4jLoggerInterceptor.java new file mode 100644 index 000000000..6c1114bac --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/WarnLog4jLoggerInterceptor.java @@ -0,0 +1,49 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class WarnLog4jLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4jConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) objInst; + if (logger.isEnabledFor(Level.WARN)) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/WarnLogbackLoggerInterceptor.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/WarnLogbackLoggerInterceptor.java new file mode 100644 index 000000000..924775a6c --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/WarnLogbackLoggerInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import ch.qos.logback.classic.Logger; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; + +public class WarnLogbackLoggerInterceptor implements InstanceMethodsAroundInterceptor { + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLogbackConfig(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Logger logger = (Logger) ((Object) objInst); + if (logger.isWarnEnabled()) { + CONFIG.logIfNecessary(logger.getName(), method.getName(), allArguments); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + return null; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/define/Log4j2LoggerInstrumentation.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/define/Log4j2LoggerInstrumentation.java new file mode 100644 index 000000000..a2db749c9 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/define/Log4j2LoggerInstrumentation.java @@ -0,0 +1,75 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; +import org.apache.skywalking.apm.plugin.logger.ContextConfig; +import org.apache.skywalking.apm.plugin.logger.ContextConfig.LogLevel; + +import java.util.Arrays; +import java.util.function.Function; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class Log4j2LoggerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + private static final String ENHANCE_CLASS = "org.apache.logging.log4j.spi.AbstractLogger"; + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4j2Config(); + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + if (CONFIG == null) { + return null; + } + return Arrays.stream(LogLevel.values()) + .filter(it -> it.getPriority() >= CONFIG.getLevel().getPriority()) + .map((Function) level -> new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(level.name().toLowerCase()); + } + + @Override + public String getMethodsInterceptor() { + return String.format("org.apache.skywalking.apm.plugin.logger.%sLog4j2LoggerInterceptor", + level.name().charAt(0) + level.name().substring(1).toLowerCase()); + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }).toArray(InstanceMethodsInterceptPoint[]::new); + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/define/Log4jLoggerInstrumentation.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/define/Log4jLoggerInstrumentation.java new file mode 100644 index 000000000..fbf919fda --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/define/Log4jLoggerInstrumentation.java @@ -0,0 +1,75 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; +import org.apache.skywalking.apm.plugin.logger.ContextConfig; +import org.apache.skywalking.apm.plugin.logger.ContextConfig.LogLevel; + +import java.util.Arrays; +import java.util.function.Function; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class Log4jLoggerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + private static final String ENHANCE_CLASS = "org.apache.log4j.Category"; + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLog4jConfig(); + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + if (CONFIG == null) { + return null; + } + return Arrays.stream(LogLevel.values()) + .filter(it -> it.getPriority() >= CONFIG.getLevel().getPriority()) + .map((Function) level -> new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(level.name().toLowerCase()); + } + + @Override + public String getMethodsInterceptor() { + return String.format("org.apache.skywalking.apm.plugin.logger.%sLog4jLoggerInterceptor", + level.name().charAt(0) + level.name().substring(1).toLowerCase()); + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }).toArray(InstanceMethodsInterceptPoint[]::new); + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/define/LogbackLoggerInstrumentation.java b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/define/LogbackLoggerInstrumentation.java new file mode 100644 index 000000000..3a5ca54ca --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/java/org/apache/skywalking/apm/plugin/logger/define/LogbackLoggerInstrumentation.java @@ -0,0 +1,75 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; +import org.apache.skywalking.apm.plugin.logger.ContextConfig; +import org.apache.skywalking.apm.plugin.logger.ContextConfig.LogLevel; + +import java.util.Arrays; +import java.util.function.Function; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class LogbackLoggerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + private static final String ENHANCE_CLASS = "ch.qos.logback.classic.Logger"; + private static final ContextConfig.LoggerConfig CONFIG = ContextConfig.getInstance().getLogbackConfig(); + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + if (CONFIG == null) { + return null; + } + return Arrays.stream(LogLevel.values()) + .filter(it -> it.getPriority() >= CONFIG.getLevel().getPriority() && it != LogLevel.FATAL) + .map((Function) level -> new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(level.name().toLowerCase()); + } + + @Override + public String getMethodsInterceptor() { + return String.format("org.apache.skywalking.apm.plugin.logger.%sLogbackLoggerInterceptor", + level.name().charAt(0) + level.name().substring(1).toLowerCase()); + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }).toArray(InstanceMethodsInterceptPoint[]::new); + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/optional-plugins/logger-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..f233464bb --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,18 @@ +# 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. +logback-logger=org.apache.skywalking.apm.plugin.logger.define.LogbackLoggerInstrumentation +log4j2-logger=org.apache.skywalking.apm.plugin.logger.define.Log4j2LoggerInstrumentation +log4j-logger=org.apache.skywalking.apm.plugin.logger.define.Log4jLoggerInstrumentation \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/test/org/apache/skywalking/apm/plugin/logger/ContextConfigDefaultTest.java b/apm-sniffer/optional-plugins/logger-plugin/src/test/org/apache/skywalking/apm/plugin/logger/ContextConfigDefaultTest.java new file mode 100644 index 000000000..dbdd27f94 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/test/org/apache/skywalking/apm/plugin/logger/ContextConfigDefaultTest.java @@ -0,0 +1,44 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ContextConfigDefaultTest { + @Test + public void testDefaultConfig() { + ContextConfig config = ContextConfig.getInstance(); + ContextConfig.LoggerConfig log4jConfig = config.getLog4jConfig(); + ContextConfig.LoggerConfig log4j2Config = config.getLog4j2Config(); + ContextConfig.LoggerConfig logbackConfig = config.getLogbackConfig(); + //test log4j configuration + assertEquals("log4j", log4jConfig.getName()); + assertEquals("ERROR", log4jConfig.getLevel().toString()); + assertEquals("*", log4jConfig.getPackages().get(0)); + //test log4j2 configuration + assertEquals("log4j2", log4j2Config.getName()); + assertEquals("ERROR", log4j2Config.getLevel().toString()); + assertEquals("*", log4j2Config.getPackages().get(0)); + //test logback configuration + assertEquals("logback", logbackConfig.getName()); + assertEquals("ERROR", logbackConfig.getLevel().toString()); + assertEquals("*", logbackConfig.getPackages().get(0)); + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/test/org/apache/skywalking/apm/plugin/logger/ContextConfigExceptionTest.java b/apm-sniffer/optional-plugins/logger-plugin/src/test/org/apache/skywalking/apm/plugin/logger/ContextConfigExceptionTest.java new file mode 100644 index 000000000..2b9f5791a --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/test/org/apache/skywalking/apm/plugin/logger/ContextConfigExceptionTest.java @@ -0,0 +1,94 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException; +import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath; +import org.junit.*; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + + +public class ContextConfigExceptionTest { + @Before + public void setup() throws AgentPackageNotFoundException, IOException { + String configFilePath = AgentPackagePath.getPath() + "/config/logger-plugin/logconfig.properties"; + String configFileBackPath = configFilePath + ".bak"; + // create configuration file + File configFile = new File(configFilePath); + File configBackFile = new File(configFileBackPath); + //backup logconfig.properties + if (configFile.exists()) { + configFile.renameTo(configBackFile); + } else { + if (!configFile.getParentFile().exists()) { + configFile.getParentFile().mkdirs(); + } + configFile.createNewFile(); + //write configuration file + Properties properties = new Properties(); + // write content + properties.setProperty("logback.level", "fatal"); + properties.setProperty("logback.packages", "package1,package2"); + properties.setProperty("log4j.level", "debug"); + properties.setProperty("log4j.packages", "*"); + FileWriter writer = new FileWriter(configFilePath); + properties.store(writer, "set fatal level for logback"); + writer.flush(); + writer.close(); + } + } + + @Test + public void testHasConfigError() { + ContextConfig config = ContextConfig.getInstance(); + ContextConfig.LoggerConfig logbackConfig = config.getLogbackConfig(); + ContextConfig.LoggerConfig log4jConfig = config.getLog4jConfig(); + ContextConfig.LoggerConfig log4j2Config = config.getLog4j2Config(); + //test logback + assertEquals(logbackConfig, null); + //test log4j + assertEquals("log4j", log4jConfig.getName()); + assertEquals("DEBUG", log4jConfig.getLevel().toString()); + assertEquals("*", log4jConfig.getPackages().get(0)); + //test log4j2 + assertEquals("log4j2", log4j2Config.getName()); + assertEquals("ERROR", log4j2Config.getLevel().toString()); + assertEquals("*", log4j2Config.getPackages().get(0)); + + } + + @After + public void reset() throws AgentPackageNotFoundException { + String configFilePath = AgentPackagePath.getPath() + "/config/logger-plugin/logconfig.properties"; + String configFileBackPath = configFilePath + ".bak"; + File configFile = new File(configFilePath); + File configBackFile = new File(configFileBackPath); + if (configFile.exists()) { + configFile.delete(); + } + if (configBackFile.exists()) { + configBackFile.renameTo(configFile); + } + } +} diff --git a/apm-sniffer/optional-plugins/logger-plugin/src/test/org/apache/skywalking/apm/plugin/logger/ContextConfigTest.java b/apm-sniffer/optional-plugins/logger-plugin/src/test/org/apache/skywalking/apm/plugin/logger/ContextConfigTest.java new file mode 100644 index 000000000..895c75f25 --- /dev/null +++ b/apm-sniffer/optional-plugins/logger-plugin/src/test/org/apache/skywalking/apm/plugin/logger/ContextConfigTest.java @@ -0,0 +1,97 @@ +/* + * 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 org.apache.skywalking.apm.plugin.logger; + +import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException; +import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +public class ContextConfigTest { + @Before + public void setup() throws AgentPackageNotFoundException, IOException { + String configFilePath = AgentPackagePath.getPath() + "/config/logger-plugin/logconfig.properties"; + String configFileBackPath = configFilePath + ".bak"; + // create configuration file + File configFile = new File(configFilePath); + File configBackFile = new File(configFileBackPath); + //backup logconfig.properties + if (configFile.exists()) { + configFile.renameTo(configBackFile); + } else { + if (!configFile.getParentFile().exists()) { + configFile.getParentFile().mkdirs(); + } + configFile.createNewFile(); + //write configuration file + Properties properties = new Properties(); + // write content + properties.setProperty("logback.level", "error"); + properties.setProperty("logback.packages", "package1,package2"); + properties.setProperty("log4j.level", "debug"); + properties.setProperty("log4j.packages", "*"); + FileWriter writer = new FileWriter(configFilePath); + properties.store(writer, "Open the bridge for log4j2 and logback."); + writer.flush(); + writer.close(); + } + } + + @Test + public void testTwoLogger() { + // test + ContextConfig config = ContextConfig.getInstance(); + ContextConfig.LoggerConfig logbackConfig = config.getLogbackConfig(); + ContextConfig.LoggerConfig log4jConfig = config.getLog4jConfig(); + ContextConfig.LoggerConfig log4j2Config = config.getLog4j2Config(); + //test logback + assertEquals("logback", logbackConfig.getName()); + assertEquals("package1", logbackConfig.getPackages().get(0)); + assertEquals("package2", logbackConfig.getPackages().get(1)); + assertEquals("ERROR", logbackConfig.getLevel().toString()); + //test log4j + assertEquals("log4j", log4jConfig.getName()); + assertEquals("*", log4jConfig.getPackages().get(0)); + assertEquals("DEBUG", log4jConfig.getLevel().toString()); + //test log4j2 + assertEquals(log4j2Config, null); + } + + @After + public void reset() throws AgentPackageNotFoundException { + String configFilePath = AgentPackagePath.getPath() + "/config/logger-plugin/logconfig.properties"; + String configFileBackPath = configFilePath + ".bak"; + File configFile = new File(configFilePath); + File configBackFile = new File(configFileBackPath); + if (configFile.exists()) { + configFile.delete(); + } + if (configBackFile.exists()) { + configBackFile.renameTo(configFile); + } + } +} diff --git a/apm-sniffer/optional-plugins/pom.xml b/apm-sniffer/optional-plugins/pom.xml index 105479a96..86c3f1a99 100644 --- a/apm-sniffer/optional-plugins/pom.xml +++ b/apm-sniffer/optional-plugins/pom.xml @@ -49,6 +49,7 @@ customize-enhance-plugin kotlin-coroutine-plugin quartz-scheduler-2.x-plugin + logger-plugin diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md index 04feebf87..f735f4940 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -39,6 +39,9 @@ - kotlin-coroutine - lettuce-5.x - light4j +- log4j-logger +- log4j2-logger +- logback-logger - mariadb-2.x - memcache-2.x - mongodb-2.x diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md index 8c237da27..6bb00f02c 100755 --- a/docs/en/setup/service-agent/java-agent/README.md +++ b/docs/en/setup/service-agent/java-agent/README.md @@ -175,6 +175,7 @@ Now, we have the following known optional plugins. * [Plugin of Kotlin coroutine](agent-optional-plugins/Kotlin-Coroutine-plugin.md) provides the tracing across coroutines automatically. As it will add local spans to all across routines scenarios, Please assess the performance impact. * Plugin of quartz-scheduler-2.x in the optional plugin folder. The reason for being an optional plugin is, many task scheduling systems are based on quartz-scheduler, this will cause duplicate tracing and link different sub-tasks as they share the same quartz level trigger, such as ElasticJob. * Plugin of spring-webflux-5.x in the optional plugin folder. Please only activate this plugin when you use webflux alone as a web container. If you are using SpringMVC 5 or Spring Gateway, you don't need this plugin. +* [Plugin of logger(logback, log4j, log4j2)](agent-optional-plugins/Logger-plugin.md) in the optional plugin folder. For the performance perspective, please only activate it when you need to add logs(from logback,log4j, or log4j2) to the span log event. **Notice, collecting logs in the tracing would impact the performance and memory seriously. Only collect necessary logs.** ## Bootstrap class plugins All bootstrap plugins are optional, due to unexpected risk. Bootstrap plugins are provided in `bootstrap-plugins` folder. diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index 9ca608dbd..b9d6aa594 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -116,7 +116,10 @@ metrics based on the tracing data. * [Graphql](https://github.com/graphql-java) 8.0 -> 15.x * Pool * [Apache Commons DBCP](https://github.com/apache/commons-dbcp) 2.x - +* Logging Framework + * [log4j](https://github.com/apache/log4j) 2.x + * [log4j2](https://github.com/apache/logging-log4j2) 1.2.x + * [logback](https://github.com/qos-ch/logback) 1.2.x # Meter Plugins The meter plugin provides the advanced metrics collections, which are not a part of tracing. diff --git a/docs/en/setup/service-agent/java-agent/agent-optional-plugins/Logger-plugin.md b/docs/en/setup/service-agent/java-agent/agent-optional-plugins/Logger-plugin.md new file mode 100644 index 000000000..b3fd463e8 --- /dev/null +++ b/docs/en/setup/service-agent/java-agent/agent-optional-plugins/Logger-plugin.md @@ -0,0 +1,78 @@ +# Overview + +`logger-plugin` can store the logs generated by the program during the call, such as the content of the error log, into the span log. Through the configuration file, you can control the log source (log4j2, logback, log4j), package name, and level. Please note that the original `log4j.xml`(or other log framework config files) has a higher priority than the `logconfig.properties`. + +# Configuration file + +By default, the configuration file is in `apache-skywalking-apm-bin/agent/config/logger-plugin/logconfig.properties`. Of course, **If the file does not exist, the default configurations are as following:** + +```properties +log4j.packages=* +log4j.level=error +log4j2.packages=* +log4j2.level=error +logback.packages=* +logback.level=error +``` + +The meaning of the above configuration is as follows: + +1. SkyWalking opened the adaptor(bridge) between tracing kernel and log frameworks, including `log4j`, `log4j2`, `logback`. +2. Only collect logs at the `error` level, others would be ignored, including `trace`, `debug`, `info`, `warn`. +3. Wouldn't filter the logs by the package name. + +# Property description + +## packages + +**package attribute**: Specify the package name of the log that needs log conversion. **The default value is `*`, and it will match all packages.** + +packages value: + +* the name of package, eg: `org.apache.skywalking` +* `*`:match all + +**Notice:** + +When matching multiple packages, the names of different packages should be separated by a comma. + +## level + +**level attribute** : The level of the log for conversion. **By default it is `error` level**. + +The hierarchy order of log levels from low to high is as follows: + +`trace` < `debug` < `info` <`warn`< `error` < `fatal` + +**Notice:** + +Because `logback` does not support the `fatal` log level, the highest level you may set it to is **logback.level=error**. + +# Use Cases: +
+ +Only open the bridge for log4j + +```properties +# only collect the logs from package1 and package2 +log4j.packages=package1,package2 +# Only collect logs at the `fatal` level, others would be ignored, including `error`,`trace`, `debug`, `info`, `warn` +log4j.level=fatal +``` + +
+ +
+ +Open the bridge for log4j and logback + +```properties +# for log4j, only collect the logs from package1 and collect logs at the `error` level and `fatal` level +log4j.packages=package1 +log4j.level=error +# for logback, wouldn't filter the logs by the package name. and all level logs except `trace` level +logback.packages=* +logback.level=debug +``` + +
diff --git a/test/plugin/scenarios/logger-log4j-scenario/bin/startup.sh b/test/plugin/scenarios/logger-log4j-scenario/bin/startup.sh new file mode 100644 index 000000000..3071d8dfd --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/bin/startup.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# 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. + +home="$(cd "$(dirname $0)"; pwd)" + +java -jar ${agent_opts} ${home}/../libs/logger-log4j-scenario.jar & diff --git a/test/plugin/scenarios/logger-log4j-scenario/config/expectedData.yaml b/test/plugin/scenarios/logger-log4j-scenario/config/expectedData.yaml new file mode 100644 index 000000000..68a032961 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/config/expectedData.yaml @@ -0,0 +1,138 @@ +# 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. +segmentItems: + - serviceName: logger-log4j-scenario + segmentSize: 4 + segments: + - segmentId: 6bda4582407147a78b86e600dfcf7e07.44.16065475238850000 + spans: + - operationName: /log4j/healthCheck + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j/healthCheck'} + - {key: http.method, value: HEAD} + - segmentId: not null + spans: + - operationName: /log4j/no-param + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j/no-param'} + - {key: http.method, value: GET} + logs: + - logEvent: + - {key: event, value: 'error'} + - {key: message, value: 'no-param'} + - {key: log.kind, value: 'org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + refs: + - {parentEndpoint: /log4j/testcase, networkAddress: 'localhost:8080', refType: CrossProcess, + parentSpanId: 1, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: logger-log4j-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: /log4j/one-param + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j/one-param'} + - {key: http.method, value: GET} + logs: + - logEvent: + - {key: param.1, value: 'java.lang.Exception'} + - {key: event, value: 'error'} + - {key: message, value: 'throwable-param'} + - {key: log.kind, value: 'org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + refs: + - {parentEndpoint: /log4j/testcase, networkAddress: 'localhost:8080', refType: CrossProcess, + parentSpanId: 2, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: logger-log4j-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: /log4j/no-param + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 2 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j/no-param'} + - {key: http.method, value: GET} + - operationName: /log4j/one-param + operationId: 0 + parentSpanId: 0 + spanId: 2 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 2 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j/one-param'} + - {key: http.method, value: GET} + - operationName: /log4j/testcase + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j/testcase'} + - {key: http.method, value: GET} diff --git a/test/plugin/scenarios/logger-log4j-scenario/configuration.yml b/test/plugin/scenarios/logger-log4j-scenario/configuration.yml new file mode 100644 index 000000000..bfd5196d8 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/configuration.yml @@ -0,0 +1,22 @@ +# 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. + +type: jvm +entryService: http://localhost:8080/log4j/testcase +healthCheck: http://localhost:8080/log4j/healthCheck +startScript: ./bin/startup.sh +runningMode: with_optional +withPlugins: apm-logger-plugin-*.jar diff --git a/test/plugin/scenarios/logger-log4j-scenario/pom.xml b/test/plugin/scenarios/logger-log4j-scenario/pom.xml new file mode 100644 index 000000000..678d88a42 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/pom.xml @@ -0,0 +1,105 @@ + + + + + org.apache.skywalking.apm.testcase + logger-log4j-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 1.8 + 1.2.17 + + + skywalking-logger-log4j-scenario + + + + org.springframework.boot + spring-boot-starter-web + 2.1.17.RELEASE + + + org.springframework.boot + spring-boot-starter-logging + + + + + log4j + log4j + ${test.framework.version} + + + org.apache.httpcomponents + httpclient + 4.5.6 + + + + + logger-log4j-scenario + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + maven-compiler-plugin + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/logger-log4j-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/logger-log4j-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..8e9ff99ea --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/logger-log4j-scenario.jar + ./libs + 0775 + + + \ No newline at end of file diff --git a/test/plugin/scenarios/logger-log4j-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/Application.java b/test/plugin/scenarios/logger-log4j-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/Application.java new file mode 100644 index 000000000..740027508 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/Application.java @@ -0,0 +1,34 @@ +/* + * 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 org.apache.skywalking.apm.testcase.logger; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + try { + SpringApplication.run(Application.class, args); + } catch (Exception e) { + // Never do this + } + } +} diff --git a/test/plugin/scenarios/logger-log4j-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/controller/CaseController.java b/test/plugin/scenarios/logger-log4j-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/controller/CaseController.java new file mode 100644 index 000000000..5eedee200 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/controller/CaseController.java @@ -0,0 +1,64 @@ +/* + * 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 org.apache.skywalking.apm.testcase.logger.controller; + +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.apache.skywalking.apm.testcase.logger.utils.HttpUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/log4j") +public class CaseController { + + private static final Logger logger = LogManager.getLogger(CaseController.class); + private static final String SUCCESS = "Success"; + @Value("${logger.host:localhost:8080}") + private String loggerAddress; + + @RequestMapping("/no-param") + @ResponseBody + public String noParam() { + logger.error("no-param"); + return "no-param"; + } + + @RequestMapping("/one-param") + @ResponseBody + public String oneParam() { + logger.error("throwable-param", new Exception()); + return "one param"; + } + + @RequestMapping("/testcase") + public String testcase() { + HttpUtils.visit("http://" + loggerAddress + "/log4j/no-param"); + HttpUtils.visit("http://" + loggerAddress + "/log4j/one-param"); + return "test"; + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() { + return SUCCESS; + } +} diff --git a/test/plugin/scenarios/logger-log4j-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/utils/HttpUtils.java b/test/plugin/scenarios/logger-log4j-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/utils/HttpUtils.java new file mode 100644 index 000000000..bbc864a30 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/utils/HttpUtils.java @@ -0,0 +1,57 @@ +/* + * 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 org.apache.skywalking.apm.testcase.logger.utils; + +import org.apache.http.HttpEntity; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Component +public class HttpUtils { + + public static String visit(String url) { + try { + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + HttpGet httpget = new HttpGet(url); + ResponseHandler responseHandler = new ResponseHandler() { + @Override + public String handleResponse( + org.apache.http.HttpResponse response) throws ClientProtocolException, IOException { + HttpEntity entity = response.getEntity(); + return entity != null ? EntityUtils.toString(entity) : null; + } + + }; + return httpclient.execute(httpget, responseHandler); + + } finally { + httpclient.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/test/plugin/scenarios/logger-log4j-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/logger-log4j-scenario/src/main/resources/application.yaml new file mode 100644 index 000000000..fd38f43b7 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/src/main/resources/application.yaml @@ -0,0 +1,19 @@ +# +# 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. +# +# +server: + port: 8080 \ No newline at end of file diff --git a/test/plugin/scenarios/logger-log4j-scenario/support-version.list b/test/plugin/scenarios/logger-log4j-scenario/support-version.list new file mode 100644 index 000000000..6f8fb9605 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j-scenario/support-version.list @@ -0,0 +1,17 @@ +# 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. + +1.2.17 \ No newline at end of file diff --git a/test/plugin/scenarios/logger-log4j2-scenario/bin/startup.sh b/test/plugin/scenarios/logger-log4j2-scenario/bin/startup.sh new file mode 100644 index 000000000..ecaff9629 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/bin/startup.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# 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. + +home="$(cd "$(dirname $0)"; pwd)" + +java -jar ${agent_opts} ${home}/../libs/logger-log4j2-scenario.jar & diff --git a/test/plugin/scenarios/logger-log4j2-scenario/config/expectedData.yaml b/test/plugin/scenarios/logger-log4j2-scenario/config/expectedData.yaml new file mode 100644 index 000000000..2c0813eb3 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/config/expectedData.yaml @@ -0,0 +1,180 @@ +# 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. +segmentItems: + - serviceName: logger-log4j2-scenario + segmentSize: 5 + segments: + - segmentId: not null + spans: + - operationName: /log4j2/healthCheck + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j2/healthCheck'} + - {key: http.method, value: HEAD} + - segmentId: not null + spans: + - operationName: /log4j2/no-param + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j2/no-param'} + - {key: http.method, value: GET} + logs: + - logEvent: + - {key: event, value: 'error'} + - {key: message, value: 'no-param'} + - {key: log.kind, value: 'org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + refs: + - {parentEndpoint: /log4j2/testcase, networkAddress: 'localhost:8080', refType: CrossProcess, + parentSpanId: 1, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: logger-log4j2-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: /log4j2/one-param + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j2/one-param'} + - {key: http.method, value: GET} + logs: + - logEvent: + - {key: param.1, value: 'class org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + - {key: event, value: 'error'} + - {key: message, value: 'one param is {}'} + - {key: log.kind, value: 'org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + refs: + - {parentEndpoint: /log4j2/testcase, networkAddress: 'localhost:8080', refType: CrossProcess, + parentSpanId: 2, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: logger-log4j2-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: /log4j2/marker + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j2/marker'} + - {key: http.method, value: GET} + logs: + - logEvent: + - {key: event, value: 'error'} + - {key: message, value: 'test marker'} + - {key: log.kind, value: 'org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + refs: + - {parentEndpoint: /log4j2/testcase, networkAddress: 'localhost:8080', refType: CrossProcess, + parentSpanId: 3, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: logger-log4j2-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: /log4j2/no-param + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 2 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j2/no-param'} + - {key: http.method, value: GET} + - operationName: /log4j2/one-param + operationId: 0 + parentSpanId: 0 + spanId: 2 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 2 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j2/one-param'} + - {key: http.method, value: GET} + - operationName: /log4j2/marker + operationId: 0 + parentSpanId: 0 + spanId: 3 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 2 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j2/marker'} + - {key: http.method, value: GET} + - operationName: /log4j2/testcase + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/log4j2/testcase'} + - {key: http.method, value: GET} diff --git a/test/plugin/scenarios/logger-log4j2-scenario/configuration.yml b/test/plugin/scenarios/logger-log4j2-scenario/configuration.yml new file mode 100644 index 000000000..5a8cbb95f --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/configuration.yml @@ -0,0 +1,22 @@ +# 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. + +type: jvm +entryService: http://localhost:8080/log4j2/testcase +healthCheck: http://localhost:8080/log4j2/healthCheck +startScript: ./bin/startup.sh +runningMode: with_optional +withPlugins: apm-logger-plugin-*.jar diff --git a/test/plugin/scenarios/logger-log4j2-scenario/pom.xml b/test/plugin/scenarios/logger-log4j2-scenario/pom.xml new file mode 100644 index 000000000..6953f723f --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/pom.xml @@ -0,0 +1,110 @@ + + + + + org.apache.skywalking.apm.testcase + logger-log4j2-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 1.8 + 2.14.0 + + + skywalking-logger-log4j2-scenario + + + + org.springframework.boot + spring-boot-starter-web + 2.1.17.RELEASE + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.apache.logging.log4j + log4j-core + ${test.framework.version} + + + org.springframework.boot + spring-boot-starter-log4j2 + 2.1.17.RELEASE + + + org.apache.httpcomponents + httpclient + 4.5.6 + + + + + logger-log4j2-scenario + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + maven-compiler-plugin + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/logger-log4j2-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/logger-log4j2-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..8a2264360 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/logger-log4j2-scenario.jar + ./libs + 0775 + + + \ No newline at end of file diff --git a/test/plugin/scenarios/logger-log4j2-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/Application.java b/test/plugin/scenarios/logger-log4j2-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/Application.java new file mode 100644 index 000000000..740027508 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/Application.java @@ -0,0 +1,34 @@ +/* + * 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 org.apache.skywalking.apm.testcase.logger; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + try { + SpringApplication.run(Application.class, args); + } catch (Exception e) { + // Never do this + } + } +} diff --git a/test/plugin/scenarios/logger-log4j2-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/controller/CaseController.java b/test/plugin/scenarios/logger-log4j2-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/controller/CaseController.java new file mode 100644 index 000000000..7943fbd0b --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/controller/CaseController.java @@ -0,0 +1,72 @@ +/* + * 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 org.apache.skywalking.apm.testcase.logger.controller; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.MarkerManager; +import org.apache.skywalking.apm.testcase.logger.utils.HttpUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/log4j2") +public class CaseController { + + private static final Logger logger = LogManager.getLogger(CaseController.class); + private static final String SUCCESS = "Success"; + @Value("${logger.host:localhost:8080}") + private String loggerAddress; + + @RequestMapping("/no-param") + @ResponseBody + public String noParam() { + logger.error("no-param"); + return "no-param"; + } + + @RequestMapping("/one-param") + @ResponseBody + public String oneParam() { + logger.error("one param is {}", CaseController.class); + return "one param"; + } + @RequestMapping("/marker") + @ResponseBody + public String testMarker() { + logger.error(MarkerManager.getMarker("TEST"), "test marker"); + return "test marker"; + } + + @RequestMapping("/testcase") + public String testcase() { + HttpUtils.visit("http://" + loggerAddress + "/log4j2/no-param"); + HttpUtils.visit("http://" + loggerAddress + "/log4j2/one-param"); + HttpUtils.visit("http://" + loggerAddress + "/log4j2/marker"); + return "test"; + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() { + return SUCCESS; + } +} diff --git a/test/plugin/scenarios/logger-log4j2-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/utils/HttpUtils.java b/test/plugin/scenarios/logger-log4j2-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/utils/HttpUtils.java new file mode 100644 index 000000000..bbc864a30 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/utils/HttpUtils.java @@ -0,0 +1,57 @@ +/* + * 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 org.apache.skywalking.apm.testcase.logger.utils; + +import org.apache.http.HttpEntity; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Component +public class HttpUtils { + + public static String visit(String url) { + try { + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + HttpGet httpget = new HttpGet(url); + ResponseHandler responseHandler = new ResponseHandler() { + @Override + public String handleResponse( + org.apache.http.HttpResponse response) throws ClientProtocolException, IOException { + HttpEntity entity = response.getEntity(); + return entity != null ? EntityUtils.toString(entity) : null; + } + + }; + return httpclient.execute(httpget, responseHandler); + + } finally { + httpclient.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/test/plugin/scenarios/logger-log4j2-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/logger-log4j2-scenario/src/main/resources/application.yaml new file mode 100644 index 000000000..fd38f43b7 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/src/main/resources/application.yaml @@ -0,0 +1,19 @@ +# +# 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. +# +# +server: + port: 8080 \ No newline at end of file diff --git a/test/plugin/scenarios/logger-log4j2-scenario/support-version.list b/test/plugin/scenarios/logger-log4j2-scenario/support-version.list new file mode 100644 index 000000000..7634b67e1 --- /dev/null +++ b/test/plugin/scenarios/logger-log4j2-scenario/support-version.list @@ -0,0 +1,31 @@ +# 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. + +2.14.0 +2.13.0 +2.12.0 +2.11.0 +2.10.0 +2.9.0 +#2.8 +#2.7 +#2.6 +#2.5 +#2.4 +#2.3 +#2.2 +#2.1 +#2.0 diff --git a/test/plugin/scenarios/logger-logback-scenario/bin/startup.sh b/test/plugin/scenarios/logger-logback-scenario/bin/startup.sh new file mode 100644 index 000000000..50415c45b --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/bin/startup.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# 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. + +home="$(cd "$(dirname $0)"; pwd)" + +java -jar ${agent_opts} ${home}/../libs/logger-logback-scenario.jar & diff --git a/test/plugin/scenarios/logger-logback-scenario/config/expectedData.yaml b/test/plugin/scenarios/logger-logback-scenario/config/expectedData.yaml new file mode 100644 index 000000000..3580f206d --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/config/expectedData.yaml @@ -0,0 +1,181 @@ +# 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. +segmentItems: + - serviceName: logger-logback-scenario + segmentSize: 5 + segments: + - segmentId: not null + spans: + - operationName: /logback/healthCheck + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/logback/healthCheck'} + - {key: http.method, value: HEAD} + - segmentId: not null + spans: + - operationName: /logback/no-param + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/logback/no-param'} + - {key: http.method, value: GET} + logs: + - logEvent: + - {key: event, value: 'error'} + - {key: message, value: 'no-param'} + - {key: log.kind, value: 'org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + refs: + - {parentEndpoint: /logback/testcase, networkAddress: 'localhost:8080', refType: CrossProcess, + parentSpanId: 1, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: logger-logback-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: /logback/one-param + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/logback/one-param'} + - {key: http.method, value: GET} + logs: + - logEvent: + - {key: param.1, value: 'class org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + - {key: event, value: 'error'} + - {key: message, value: 'one param is {}'} + - {key: log.kind, value: 'org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + refs: + - {parentEndpoint: /logback/testcase, networkAddress: 'localhost:8080', refType: CrossProcess, + parentSpanId: 2, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: logger-logback-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: /logback/marker + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/logback/marker'} + - {key: http.method, value: GET} + logs: + - logEvent: + - {key: event, value: 'error'} + - {key: message, value: 'test marker'} + - {key: log.kind, value: 'org.apache.skywalking.apm.testcase.logger.controller.CaseController'} + refs: + - {parentEndpoint: /logback/testcase, networkAddress: 'localhost:8080', refType: CrossProcess, + parentSpanId: 3, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: logger-logback-scenario, + traceId: not null} + - segmentId: not null + spans: + - operationName: /logback/no-param + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 2 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/logback/no-param'} + - {key: http.method, value: GET} + - operationName: /logback/one-param + operationId: 0 + parentSpanId: 0 + spanId: 2 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 2 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/logback/one-param'} + - {key: http.method, value: GET} + - operationName: /logback/marker + operationId: 0 + parentSpanId: 0 + spanId: 3 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 2 + isError: false + spanType: Exit + peer: localhost:8080 + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/logback/marker'} + - {key: http.method, value: GET} + - operationName: /logback/testcase + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/logback/testcase'} + - {key: http.method, value: GET} + diff --git a/test/plugin/scenarios/logger-logback-scenario/configuration.yml b/test/plugin/scenarios/logger-logback-scenario/configuration.yml new file mode 100644 index 000000000..5a3159562 --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/configuration.yml @@ -0,0 +1,22 @@ +# 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. + +type: jvm +entryService: http://localhost:8080/logback/testcase +healthCheck: http://localhost:8080/logback/healthCheck +startScript: ./bin/startup.sh +runningMode: with_optional +withPlugins: apm-logger-plugin-*.jar diff --git a/test/plugin/scenarios/logger-logback-scenario/pom.xml b/test/plugin/scenarios/logger-logback-scenario/pom.xml new file mode 100644 index 000000000..af8964419 --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/pom.xml @@ -0,0 +1,111 @@ + + + + + org.apache.skywalking.apm.testcase + logger-logback-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 1.8 + 1.2.3 + + + skywalking-logger-logback-scenario + + + + org.springframework.boot + spring-boot-starter-web + 2.1.17.RELEASE + + + ch.qos.logback + logback-classic + ${test.framework.version} + + + org.apache.logging.log4j + log4j-to-slf4j + 2.11.2 + compile + + + org.slf4j + jul-to-slf4j + 1.7.30 + compile + + + org.apache.httpcomponents + httpclient + 4.5.6 + + + + + logger-logback-scenario + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + maven-compiler-plugin + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/logger-logback-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/logger-logback-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..589e96cc8 --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/logger-logback-scenario.jar + ./libs + 0775 + + + \ No newline at end of file diff --git a/test/plugin/scenarios/logger-logback-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/Application.java b/test/plugin/scenarios/logger-logback-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/Application.java new file mode 100644 index 000000000..740027508 --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/Application.java @@ -0,0 +1,34 @@ +/* + * 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 org.apache.skywalking.apm.testcase.logger; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + try { + SpringApplication.run(Application.class, args); + } catch (Exception e) { + // Never do this + } + } +} diff --git a/test/plugin/scenarios/logger-logback-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/controller/CaseController.java b/test/plugin/scenarios/logger-logback-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/controller/CaseController.java new file mode 100644 index 000000000..eccd91e02 --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/controller/CaseController.java @@ -0,0 +1,73 @@ +/* + * 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 org.apache.skywalking.apm.testcase.logger.controller; + +import org.apache.skywalking.apm.testcase.logger.utils.HttpUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MarkerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/logback") +public class CaseController { + + private static final Logger logger = LoggerFactory.getLogger(CaseController.class); + private static final String SUCCESS = "Success"; + @Value("${logger.host:localhost:8080}") + private String loggerAddress; + + @RequestMapping("/no-param") + @ResponseBody + public String noParam() { + logger.error("no-param"); + return "no-param"; + } + + @RequestMapping("/one-param") + @ResponseBody + public String oneParam() { + logger.error("one param is {}", CaseController.class); + return "one param"; + } + + @RequestMapping("/marker") + @ResponseBody + public String testMarker() { + logger.error(MarkerFactory.getMarker("TEST"), "test marker"); + return "test marker"; + } + + @RequestMapping("/testcase") + public String testcase() { + HttpUtils.visit("http://" + loggerAddress + "/logback/no-param"); + HttpUtils.visit("http://" + loggerAddress + "/logback/one-param"); + HttpUtils.visit("http://" + loggerAddress + "/logback/marker"); + return "test"; + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() { + return SUCCESS; + } +} diff --git a/test/plugin/scenarios/logger-logback-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/utils/HttpUtils.java b/test/plugin/scenarios/logger-logback-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/utils/HttpUtils.java new file mode 100644 index 000000000..bbc864a30 --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/src/main/java/org/apache/skywalking/apm/testcase/logger/utils/HttpUtils.java @@ -0,0 +1,57 @@ +/* + * 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 org.apache.skywalking.apm.testcase.logger.utils; + +import org.apache.http.HttpEntity; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Component +public class HttpUtils { + + public static String visit(String url) { + try { + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + HttpGet httpget = new HttpGet(url); + ResponseHandler responseHandler = new ResponseHandler() { + @Override + public String handleResponse( + org.apache.http.HttpResponse response) throws ClientProtocolException, IOException { + HttpEntity entity = response.getEntity(); + return entity != null ? EntityUtils.toString(entity) : null; + } + + }; + return httpclient.execute(httpget, responseHandler); + + } finally { + httpclient.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/test/plugin/scenarios/logger-logback-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/logger-logback-scenario/src/main/resources/application.yaml new file mode 100644 index 000000000..fd38f43b7 --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/src/main/resources/application.yaml @@ -0,0 +1,19 @@ +# +# 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. +# +# +server: + port: 8080 \ No newline at end of file diff --git a/test/plugin/scenarios/logger-logback-scenario/support-version.list b/test/plugin/scenarios/logger-logback-scenario/support-version.list new file mode 100644 index 000000000..d726b70b0 --- /dev/null +++ b/test/plugin/scenarios/logger-logback-scenario/support-version.list @@ -0,0 +1,19 @@ +# 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. + +# 2.0.0-2.1.0 are supported, but due to the status code bug(https://github.com/spring-projects/spring-framework/issues/21901) +# we don’t test them +1.2.3