Skip to content

Commit

Permalink
Merge pull request #27 from rshivane/master
Browse files Browse the repository at this point in the history
JInsight improvements
  • Loading branch information
rshivane authored Apr 10, 2018
2 parents c1d1cf9 + 2d8c597 commit 5f86a82
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ cache:

before_install:
- sudo apt-get install jq
- wget -O ~/.codacy/reporter/codacy-reporter-latest.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/2.0.2/codacy-coverage-reporter-2.0.2-assembly.jar
- wget -O ~/.codacy/reporter/codacy-reporter-latest.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/4.0.0/codacy-coverage-reporter-4.0.0-assembly.jar
- |
wget -O ~/.rpmlint/rpmlint-1.9.tar.gz https://github.com/rpm-software-management/rpmlint/archive/rpmlint-1.9.tar.gz;
tar xvfz ~/.rpmlint/rpmlint-1.9.tar.gz -C ~/.rpmlint;
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ of your choice: apptuit.ai, Prometheus, Graphite etc.

Instrumenting a JVM with JInsight Java Agent is refreshingly simple:
1. Update your java command line to include the jinsight options:
`java -javaagent:/var/lib/jinsight/jinsight-latest.jar -Djinsight.config=/etc/jinsight/jinsight-config.properties -cp helloworld.jar HelloWorld`
`java -javaagent:/usr/share/java/jinsight.jar -Djinsight.config=/etc/jinsight/jinsight-config.properties -cp helloworld.jar HelloWorld`
2. Save API-TOKEN, global tags, frequency of reporting data etc in the `jinsight-config.properties` file
3. (Re)start your JVM

Expand Down
1 change: 1 addition & 0 deletions pkg/common/jinsight-config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ apptuit.reporting_mode=XCOLLECTOR
#apptuit.reporting_mode=API_PUT
#apptuit.access_token=PASTE_ACCESS_TOKEN_HERE
#global_tags=env:prod, data_center:us-east, micro_service:login
#reporting_frequency=15s
22 changes: 16 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ limitations under the License.
<id>jinsight-bintray</id>
<url>https://dl.bintray.com/apptuitai/maven</url>
</repository>
<!--
<repository>
<id>sonatype-snapshots-repository</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
-->
</repositories>

<properties>
Expand Down Expand Up @@ -95,10 +104,11 @@ limitations under the License.
<netty.version>4.1.15.Final</netty.version>
<surefire.version>2.20.1</surefire.version>
<junit.version>4.12</junit.version>
<jacoco.version>0.8.0</jacoco.version>
<jacoco.version>0.8.1</jacoco.version>
<byteman.version>4.0.2</byteman.version>
<byteman.version>3.0.11</byteman.version>
<metrics.version>3.2.6</metrics.version>
<apptuit.reporter.version>0.7.1</apptuit.reporter.version>
<apptuit.reporter.version>0.7.2</apptuit.reporter.version>

<!-- Acceptance Criteria -->
<enforce.code.style>false</enforce.code.style>
Expand Down Expand Up @@ -142,7 +152,7 @@ limitations under the License.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
<version>1.4.197</version>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -154,19 +164,19 @@ limitations under the License.
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.4.8.v20171121</version>
<version>9.4.9.v20180320</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.27</version>
<version>8.5.28</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.5.27</version>
<version>8.5.28</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/ai/apptuit/metrics/jinsight/Agent.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,10 @@ private static void main0(String agentArgs, Instrumentation instrumentation,

instrumentation.appendToBootstrapClassLoaderSearch(bytemanJar);
delegate.accept(agentArgs, instrumentation);
LOGGER.info("JInsight v["+ConfigService.getInstance().getAgentVersion()
+ "] initialized. Reporting mode: "+ConfigService.getInstance().getReportingMode());
ConfigService configService = ConfigService.getInstance();
LOGGER.info("JInsight v[" + configService.getAgentVersion() + "] initialized. "
+ "Reporting via: [" + configService.getReportingMode() + "] "
+ "every [" + (configService.getReportingFrequency() / 1000) + "] seconds");
}

private static JarFile createBytemanJar() {
Expand Down
65 changes: 49 additions & 16 deletions src/main/java/ai/apptuit/metrics/jinsight/ConfigService.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.time.Duration;
import java.time.format.DateTimeParseException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
Expand All @@ -44,45 +46,36 @@
*/
public class ConfigService {

static final String REPORTING_MODE_PROPERTY_NAME = "apptuit.reporting_mode";
static final String REPORTING_FREQ_PROPERTY_NAME = "reporting_frequency";
private static final Logger LOGGER = Logger.getLogger(ConfigService.class.getName());

private static final String CONFIG_SYSTEM_PROPERTY = "jinsight.config";
private static final String DEFAULT_CONFIG_FILE_NAME = "jinsight-config.properties";

private static final String ACCESS_TOKEN_PROPERTY_NAME = "apptuit.access_token";
private static final String API_ENDPOINT_PROPERTY_NAME = "apptuit.api_url";
private static final String REPORTING_MODE_PROPERTY_NAME = "apptuit.reporting_mode";
private static final String GLOBAL_TAGS_PROPERTY_NAME = "global_tags";
private static final String HOST_TAG_NAME = "host";

private static final File JINSIGHT_HOME = new File(System.getProperty("user.home"), ".jinsight");
private static final File UNIX_JINSIGHT_CONF_DIR = new File("/etc/jinsight/");
private static final ReportingMode DEFAULT_REPORTING_MODE = ReportingMode.API_PUT;
private static final String DEFAULT_REPORTING_FREQUENCY = "15s";


private static volatile ConfigService singleton = null;
private final String apiToken;
private final URL apiUrl;
private final ReportingMode reportingMode;
private final long reportingFrequencyMillis;
private final Map<String, String> loadedGlobalTags = new HashMap<>();
private final String agentVersion;
private Map<String, String> globalTags = null;

ConfigService(Properties config) throws ConfigurationException {
this.apiToken = config.getProperty(ACCESS_TOKEN_PROPERTY_NAME);

String configMode = config.getProperty(REPORTING_MODE_PROPERTY_NAME);
ReportingMode mode = null;
if (configMode != null) {
try {
mode = ReportingMode.valueOf(configMode.trim().toUpperCase());
} catch (IllegalArgumentException e) {
LOGGER.severe("Un-supported reporting mode [" + configMode + "]. "
+ "Using default reporting mode: [" + DEFAULT_REPORTING_MODE + "]");
LOGGER.log(Level.FINE, e.toString(), e);
}
}
reportingMode = (mode == null) ? DEFAULT_REPORTING_MODE : mode;
this.reportingMode = readReportingMode(config);
this.reportingFrequencyMillis = readReportingFrequency(config);

if (apiToken == null && reportingMode == ReportingMode.API_PUT) {
throw new ConfigurationException(
Expand All @@ -101,7 +94,7 @@ public class ConfigService {
}
}
this.apiUrl = url;
this.agentVersion=loadAgentVersion();
this.agentVersion = loadAgentVersion();

loadGlobalTags(config);

Expand Down Expand Up @@ -173,6 +166,42 @@ private static Properties loadProperties(File configFilePath) throws IOException
return config;
}

private ReportingMode readReportingMode(Properties config) {
String configMode = config.getProperty(REPORTING_MODE_PROPERTY_NAME);
if (configMode != null) {
try {
return ReportingMode.valueOf(configMode.trim().toUpperCase());
} catch (IllegalArgumentException e) {
LOGGER.severe("Un-supported reporting mode [" + configMode + "]. "
+ "Using default reporting mode: [" + DEFAULT_REPORTING_MODE + "]");
LOGGER.log(Level.FINE, e.toString(), e);
}
}
return DEFAULT_REPORTING_MODE;
}

private long readReportingFrequency(Properties config) {
String configFreq = config.getProperty(REPORTING_FREQ_PROPERTY_NAME);
if (configFreq != null) {
try {
return parseDuration(configFreq);
} catch (DateTimeParseException | IllegalArgumentException e) {
LOGGER.severe("Invalid reporting frequency [" + configFreq + "]. "
+ "Using default reporting frequency: [" + DEFAULT_REPORTING_FREQUENCY + "]");
LOGGER.log(Level.FINE, e.toString(), e);
}
}
return parseDuration(DEFAULT_REPORTING_FREQUENCY);
}

private long parseDuration(String durationString) {
long millis = Duration.parse("PT" + durationString.trim()).toMillis();
if (millis < 0) {
throw new IllegalArgumentException("Frequency cannot be negative");
}
return millis;
}

private void loadGlobalTags(Properties config) throws ConfigurationException {
String tagsString = config.getProperty(GLOBAL_TAGS_PROPERTY_NAME);
if (tagsString != null) {
Expand Down Expand Up @@ -233,6 +262,10 @@ ReportingMode getReportingMode() {
return reportingMode;
}

long getReportingFrequency() {
return reportingFrequencyMillis;
}

public String getAgentVersion() {
return agentVersion;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
package ai.apptuit.metrics.jinsight;

import ai.apptuit.metrics.jinsight.ContextualModuleLoader.ModuleClassLoader;
import java.lang.ref.WeakReference;
import java.lang.ref.SoftReference;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
Expand All @@ -30,7 +32,7 @@
*/
public class ContextualModuleLoader implements ModuleSystem<ModuleClassLoader> {

private final Map<ClassLoader, WeakReference<ModuleClassLoader>> moduleLoaders = Collections
private final Map<ClassLoader, SoftReference<ModuleClassLoader>> moduleLoaders = Collections
.synchronizedMap(new WeakHashMap<>());

public void initialize(String args) {
Expand All @@ -44,9 +46,35 @@ public ModuleClassLoader createLoader(ClassLoader triggerClassLoader, String[] i
throw new IllegalArgumentException("IMPORTs are not supported");
}

WeakReference<ModuleClassLoader> reference = moduleLoaders
.computeIfAbsent(triggerClassLoader, cl -> new WeakReference<>(new ModuleClassLoader(cl)));
return reference.get();
ModuleClassLoader moduleClassLoader = getModuleClassLoader(triggerClassLoader);
if (moduleClassLoader != null) {
return moduleClassLoader;
}
synchronized (moduleLoaders) {
//Double check idiom
moduleClassLoader = getModuleClassLoader(triggerClassLoader);
if (moduleClassLoader != null) {
return moduleClassLoader;
}
moduleClassLoader = AccessController.doPrivileged(
(PrivilegedAction<ModuleClassLoader>) () -> new ModuleClassLoader(triggerClassLoader));
//Since there are no strong references to moduleClassloader, it might be collected
//We should probably hold a PhantomReference to moduleClassloader
//that is collected only after the triggerClassloader is collected
moduleLoaders.put(triggerClassLoader, new SoftReference<>(moduleClassLoader));
return moduleClassLoader;
}
}

private ModuleClassLoader getModuleClassLoader(ClassLoader triggerClassLoader) {
SoftReference<ModuleClassLoader> reference = moduleLoaders.get(triggerClassLoader);
if (reference != null) {
ModuleClassLoader moduleClassLoader = reference.get();
if (moduleClassLoader != null) {
return moduleClassLoader;
}
}
return null;
}

public void destroyLoader(ModuleClassLoader helperLoader) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private RegistryService() {

ScheduledReporter reporter = createReporter(factory, configService.getGlobalTags(),
configService.getApiToken(), configService.getApiUrl(), mode);
reporter.start(5, TimeUnit.SECONDS);
reporter.start(configService.getReportingFrequency(), TimeUnit.MILLISECONDS);

registry.registerAll(new JvmMetricSet());
}
Expand Down
Loading

0 comments on commit 5f86a82

Please sign in to comment.