Support collecting logs of log4j, log4j2, and logback in the tracing context (#5914)

This commit is contained in:
vcjmhg 2020-12-10 13:53:30 +08:00 committed by GitHub
parent 5e4b16cbfc
commit 0996151973
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 3367 additions and 1 deletions

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1,50 @@
<!--
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.apache.skywalking</groupId>
<artifactId>optional-plugins</artifactId>
<version>8.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apm-logger-plugin</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.0-alpha5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -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<String> 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<LoggerConfig> 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<LoggerConfig> parseConfigFile(FileInputStream fileInputStream) throws IOException {
Properties p = new Properties();
p.load(fileInputStream);
List<LoggerConfig> 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<String> 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<String> packages = new ArrayList<>();
packages.add("*");
src.setPackages(packages);
}
return src;
}
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public static class LoggerConfig {
private String name;
private List<String> 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<String, String> toMessageMap(String loggerName, String level, Object... args) {
Map<String, String> 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;
}
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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<LogLevel, InstanceMethodsInterceptPoint>) level -> new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> 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);
}
}

View File

@ -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<LogLevel, InstanceMethodsInterceptPoint>) level -> new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> 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);
}
}

View File

@ -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<LogLevel, InstanceMethodsInterceptPoint>) level -> new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> 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);
}
}

View File

@ -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

View File

@ -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));
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -49,6 +49,7 @@
<module>customize-enhance-plugin</module>
<module>kotlin-coroutine-plugin</module>
<module>quartz-scheduler-2.x-plugin</module>
<module>logger-plugin</module>
</modules>
<dependencies>

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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:
<details>
<summary>Only open the bridge for log4j</summary>
```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
```
</details>
<details>
<summary>Open the bridge for log4j and logback</summary>
```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
```
</details>

View File

@ -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 &

View File

@ -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}

View File

@ -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

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>logger-log4j-scenario</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler.version>1.8</compiler.version>
<test.framework.version>1.2.17</test.framework.version>
</properties>
<name>skywalking-logger-log4j-scenario</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.17.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${test.framework.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
</dependencies>
<build>
<finalName>logger-log4j-scenario</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${compiler.version}</source>
<target>${compiler.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
<outputDirectory>./target/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>./bin</directory>
<fileMode>0775</fileMode>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/logger-log4j-scenario.jar</source>
<outputDirectory>./libs</outputDirectory>
<fileMode>0775</fileMode>
</file>
</files>
</assembly>

View File

@ -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
}
}
}

View File

@ -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;
}
}

View File

@ -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<String> responseHandler = new ResponseHandler<String>() {
@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);
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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 &

View File

@ -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}

View File

@ -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

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>logger-log4j2-scenario</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler.version>1.8</compiler.version>
<test.framework.version>2.14.0</test.framework.version>
</properties>
<name>skywalking-logger-log4j2-scenario</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.17.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${test.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.1.17.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
</dependencies>
<build>
<finalName>logger-log4j2-scenario</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${compiler.version}</source>
<target>${compiler.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
<outputDirectory>./target/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>./bin</directory>
<fileMode>0775</fileMode>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/logger-log4j2-scenario.jar</source>
<outputDirectory>./libs</outputDirectory>
<fileMode>0775</fileMode>
</file>
</files>
</assembly>

View File

@ -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
}
}
}

View File

@ -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;
}
}

View File

@ -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<String> responseHandler = new ResponseHandler<String>() {
@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);
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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 &

View File

@ -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}

View File

@ -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

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>org.apache.skywalking.apm.testcase</groupId>
<artifactId>logger-logback-scenario</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler.version>1.8</compiler.version>
<test.framework.version>1.2.3</test.framework.version>
</properties>
<name>skywalking-logger-logback-scenario</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.17.RELEASE</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${test.framework.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.11.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.30</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
</dependencies>
<build>
<finalName>logger-logback-scenario</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${compiler.version}</source>
<target>${compiler.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
<outputDirectory>./target/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>./bin</directory>
<fileMode>0775</fileMode>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/logger-logback-scenario.jar</source>
<outputDirectory>./libs</outputDirectory>
<fileMode>0775</fileMode>
</file>
</files>
</assembly>

View File

@ -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
}
}
}

View File

@ -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;
}
}

View File

@ -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<String> responseHandler = new ResponseHandler<String>() {
@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);
}
}
}

View File

@ -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

View File

@ -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 dont test them
1.2.3