Skip to content

Commit

Permalink
[pinpoint-apm#195] implemented application type detector
Browse files Browse the repository at this point in the history
  • Loading branch information
Xylus committed Mar 19, 2015
1 parent 00cc3bc commit a291356
Show file tree
Hide file tree
Showing 20 changed files with 1,049 additions and 297 deletions.
6 changes: 5 additions & 1 deletion agent/src/main/resources/pinpoint.config
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ profiler.tcpdatasender.command.accept.enable=true
#profiler.applicationservertype=TOMCAT
#profiler.applicationservertype=BLOC

###########################################################
# application type detect order #
###########################################################
profiler.type.detect.order=

###########################################################
# user defined classes #
Expand Down Expand Up @@ -216,4 +220,4 @@ profiler.log4j.logging.transactioninfo=false
###########################################################
# logback
###########################################################
profiler.logback.logging.transactioninfo=false
profiler.logback.logging.transactioninfo=false
6 changes: 5 additions & 1 deletion agent/src/test/resources/pinpoint-spring-bean-test.config
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ profiler.tcpdatasender.command.accept.enable=true
#profiler.applicationservertype=TOMCAT
#profiler.applicationservertype=BLOC

###########################################################
# application type detect order #
###########################################################
profiler.type.detect.order=

###########################################################
# user defined classes #
Expand Down Expand Up @@ -194,4 +198,4 @@ profiler.log4j.logging.transactioninfo=false
###########################################################
# logback
###########################################################
profiler.logback.logging.transactioninfo=false
profiler.logback.logging.transactioninfo=false
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@

import com.navercorp.pinpoint.bootstrap.util.NumberUtils;
import com.navercorp.pinpoint.bootstrap.util.spring.PropertyPlaceholderHelper;
import com.navercorp.pinpoint.common.ServiceType;
import com.navercorp.pinpoint.common.util.PropertyUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -210,6 +212,7 @@ public static ProfilerConfig load(String pinpointConfigFileName) throws IOExcept
private long agentInfoSendRetryInterval = DEFAULT_AGENT_INFO_SEND_RETRY_INTERVAL;

private String applicationServerType;
private List<String> applicationTypeDetectOrder = Collections.emptyList();
private boolean log4jLoggingTransactionInfo;
private boolean logbackLoggingTransactionInfo;

Expand Down Expand Up @@ -589,6 +592,10 @@ public boolean isRedisPipelineEnabled() {
public Filter<String> getProfilableClassFilter() {
return profilableClassFilter;
}

public List<String> getApplicationTypeDetectOrder() {
return applicationTypeDetectOrder;
}

public String getApplicationServerType() {
return applicationServerType;
Expand Down Expand Up @@ -768,8 +775,10 @@ void readPropertyValues() {
this.agentInfoSendRetryInterval = readLong("profiler.agentInfo.send.retry.interval", DEFAULT_AGENT_INFO_SEND_RETRY_INTERVAL);

// service type
this.applicationServerType = readString("profiler.applicationservertype", ServiceType.STAND_ALONE.getName());
this.applicationServerType = readString("profiler.applicationservertype", null);

// application type detector order
this.applicationTypeDetectOrder = readTypeDetectOrder("profiler.type.detect.order");

// TODO have to remove
// profile package included in order to test "call stack view".
Expand Down Expand Up @@ -836,6 +845,15 @@ public long readLong(String propertyName, long defaultValue) {
return result;
}

public List<String> readTypeDetectOrder(String propertyName) {
String value = properties.getProperty(propertyName);
if (value == null) {
return Collections.emptyList();
}
String[] orders = value.trim().split(",");
return Arrays.asList(orders);
}

public boolean readBoolean(String propertyName, boolean defaultValue) {
String value = properties.getProperty(propertyName, Boolean.toString(defaultValue));
boolean result = Boolean.parseBoolean(value);
Expand All @@ -845,7 +863,6 @@ public boolean readBoolean(String propertyName, boolean defaultValue) {
return result;
}


@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ProfilerConfig{");
Expand Down Expand Up @@ -929,6 +946,7 @@ public String toString() {
sb.append(", profilableClassFilter=").append(profilableClassFilter);
sb.append(", DEFAULT_AGENT_INFO_SEND_RETRY_INTERVAL=").append(DEFAULT_AGENT_INFO_SEND_RETRY_INTERVAL);
sb.append(", agentInfoSendRetryInterval=").append(agentInfoSendRetryInterval);
sb.append(", applicationTypeDetectOrder='").append(applicationTypeDetectOrder).append('\'');
sb.append(", applicationServerType=").append(applicationServerType);
sb.append('}');
return sb.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,36 @@
*/
package com.navercorp.pinpoint.bootstrap.plugin;

import com.navercorp.pinpoint.bootstrap.resolver.ConditionProvider;
import com.navercorp.pinpoint.common.ServiceType;

/**
* @author Jongho Moon
* @author HyunGil Jeong
*
*/
public interface ServerTypeDetector {
public String getServerTypeName();
public boolean detect();
public boolean canOverride(String serverType);

/**
* Returns the {@link ServiceType} representing the current plugin,
* with code in a range corresponding to {@link com.navercorp.pinpoint.common.ServiceTypeCategory#SERVER}
*
* @return the {@link ServiceType} representing the current plugin
* @see ServiceType#isWas()
* @see com.navercorp.pinpoint.common.ServiceTypeCategory#SERVER
*/
public ServiceType getServerType();

/**
* Checks whether the provided conditions satisfy the requirements given by the plugins implementing this class.
*
* <p>This method allows the agent to go through each of the registered plugins with classes implementing this interface,
* checking whether the execution environment satisfies the requirements specified in them, returning <tt>true</tt> if the
* requirements are satisfied.
*
* @param provider conditions provided by the current application
* @return <tt>true</tt> if the provided conditions satisfy the requirements, <tt>false</tt> if otherwise
* @see ConditionProvider
*/
public boolean detect(ConditionProvider provider);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.navercorp.pinpoint.bootstrap.resolver;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.navercorp.pinpoint.bootstrap.plugin.ServerTypeDetector;
import com.navercorp.pinpoint.common.ServiceType;

/**
* This class attempts to resolve the current application type through {@link ServerTypeDetector}s.
* The application type is resolved by checking the conditions defined in each of the loaded detector's {@code detect} method.
* <p>
* If no match is found, the application type defaults to {@code ServiceType.STAND_ALONE}
*
* @author HyunGil Jeong
*/
public class ApplicationServerTypePluginResolver {

private final Logger logger = Logger.getLogger(ApplicationServerTypePluginResolver.class.getName());

private final List<ServerTypeDetector> serverTypeDetectors;

private final ConditionProvider conditionProvider;

private static final ServiceType DEFAULT_SERVER_TYPE = ServiceType.STAND_ALONE;

public ApplicationServerTypePluginResolver(List<ServerTypeDetector> serverTypeDetectors) {
this(serverTypeDetectors, ConditionProvider.DEFAULT_CONDITION_PROVIDER);
}

public ApplicationServerTypePluginResolver(List<ServerTypeDetector> serverTypeDetectors, ConditionProvider conditionProvider) {
if (serverTypeDetectors == null) {
throw new IllegalArgumentException("serverTypeDetectors should not be null");
}
if (conditionProvider == null) {
throw new IllegalArgumentException("conditionProvider should not be null");
}
this.serverTypeDetectors = serverTypeDetectors;
this.conditionProvider = conditionProvider;
}

public ServiceType resolve() {
for (ServerTypeDetector currentDetector : this.serverTypeDetectors) {
logger.log(Level.INFO, "Attempting to resolve using " + currentDetector.getClass());
if (currentDetector.detect(this.conditionProvider)) {
logger.log(Level.INFO, "Match found using " + currentDetector.getClass().getSimpleName());
return currentDetector.getServerType();
} else {
logger.log(Level.INFO, "No match found using " + currentDetector.getClass());
}
}
logger.log(Level.INFO, "Server type not resolved. Defaulting to " + DEFAULT_SERVER_TYPE.getName());
return DEFAULT_SERVER_TYPE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.navercorp.pinpoint.bootstrap.resolver;

import java.util.HashMap;
import java.util.Map;

import com.navercorp.pinpoint.bootstrap.resolver.condition.Condition;
import com.navercorp.pinpoint.bootstrap.resolver.condition.LibraryClassCondition;
import com.navercorp.pinpoint.bootstrap.resolver.condition.MainClassCondition;
import com.navercorp.pinpoint.bootstrap.resolver.condition.SystemPropertyCondition;

/**
* @author HyunGil Jeong
*/
public class ConditionProvider {

public static final ConditionProvider DEFAULT_CONDITION_PROVIDER = new ConditionProvider();

private final Map<Class<? extends Condition<?>>, Condition<?>> conditions;

public ConditionProvider() {
this(new HashMap<Class<? extends Condition<?>>, Condition<?>>());
}

public ConditionProvider(Map<Class<? extends Condition<?>>, Condition<?>> conditions) {
this.conditions = conditions;
addDefaultConditions();
}

private void addDefaultConditions() {
this.conditions.put(MainClassCondition.class, new MainClassCondition());
this.conditions.put(SystemPropertyCondition.class, new SystemPropertyCondition());
this.conditions.put(LibraryClassCondition.class, new LibraryClassCondition());
}

public <T extends Condition<?>> T getCondition(Class<T> conditionClass) {
@SuppressWarnings("unchecked")
T condition = (T)this.conditions.get(conditionClass);
return condition;
}

/**
* Returns {@link MainClassCondition} that allows plugins to check for the application's bootstrap main class.
*
* @return the {@link MainClassCondition}
*/
public MainClassCondition getMainClassCondition() {
return (MainClassCondition)this.conditions.get(MainClassCondition.class);
}

/**
* Returns {@link SystemPropertyCondition} that allows plugins to check for system property keys.
*
* @return the {@link SystemPropertyCondition}
*/
public SystemPropertyCondition getSystemPropertyCondition() {
return (SystemPropertyCondition)this.conditions.get(SystemPropertyCondition.class);
}

/**
* Returns {@link LibraryClassCondition} that allows plugins to check for classes accessible by
* the system class loader.
*
* @return the {@link LibraryClassCondition}
*/
public LibraryClassCondition getLibraryClassCondition() {
return (LibraryClassCondition)this.conditions.get(LibraryClassCondition.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.navercorp.pinpoint.bootstrap.resolver.condition;

/**
* @author HyunGil Jeong
*/
public interface Condition<T> {

public boolean matches(T condition);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2015 NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.navercorp.pinpoint.bootstrap.resolver.condition;

/**
* @author HyunGil Jeong
*/
public interface ConditionValue<V> {

public V getValue();

}
Loading

0 comments on commit a291356

Please # to comment.