Skip to content

Commit

Permalink
v0.3.1: use batch mode to send events and added disableStackTraces op…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
PeterPaul-Perfana committed Apr 4, 2024
1 parent 5bf5b63 commit 34fe4de
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 74 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ To use JfrExporter:

## Download

Direct [download version 0.3.0](https://github.com/perfana/jfr-exporter/releases/download/0.3.0/jfr-exporter-0.3.0.jar)
Direct [download version 0.3.1](https://github.com/perfana/jfr-exporter/releases/download/0.3.1/jfr-exporter-0.3.1.jar)

Download the latest release from the [releases page](https://github.com/perfana/jfr-exporter/releases).

Expand Down Expand Up @@ -73,6 +73,7 @@ The monitored process needs to be started with JFR enabled: `-XX:StartFlightReco
```bash
Usage: java JfrExporter
--debug,-d
--disableStackTraces
--processId,-p <processId>
--duration <ISO-duration>
--application,-a <application>
Expand All @@ -86,6 +87,8 @@ Usage: java JfrExporter

The default InfluxDB database name is `jfr`.

Use `--disableStackTraces` to limit stacktraces to only the first three frames.

Example to connect to process with id 1234 and send events with application name afterburner:
```bash
java -jar jfr-exporter.jar --processId 1234 --application afterburner \
Expand All @@ -111,7 +114,7 @@ For reference: [list of JFR events](https://bestsolution-at.github.io/jfr-doc/in

## Stacktraces

Stack traces for several events are sent to InfuxDB.
Stack traces for several events are sent to InfluxDB.
Via the dashboard you can see the details by clicking in the stacktrace columns.

Example of a big memory allocation stacktrace:
Expand Down Expand Up @@ -139,3 +142,8 @@ Debug and tracing will output a lot of data, so only use for troubleshooting.
### v0.3.0: January 2024
* Added new events: Java Monitor waits and enters, Network read/write
* New dashboard with new events

### v0.3.1: April 2024
* Make use of buffer to send events in batches
* Make event handling more robust by catching exceptions
* Added disableStackTraces option to limit the amount of stacktrace data
33 changes: 27 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,49 @@
<dependency>
<groupId>com.influxdb</groupId>
<artifactId>influxdb-client-java</artifactId>
<version>6.12.0</version>
<version>7.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.1</version>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.4.0</version>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>3.6.3</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<version>3.3.0</version>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
Expand All @@ -90,7 +111,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<version>3.13.0</version>
<configuration>
<source>17</source>
<target>17</target>
Expand All @@ -99,7 +120,7 @@
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>4.2</version>
<version>4.3</version>
<configuration>
<licenseSets>
<licenseSet>
Expand Down
36 changes: 12 additions & 24 deletions src/main/java/io/perfana/jfr/Arguments.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,21 @@ public class Arguments {
private String influxUser = "";
private String influxPassword = "";
private boolean debug = false;
private String perfanaUrl = null;
private String perfanaApiKey = null;
private Duration duration = null;
private String influxRetentionPolicy = "autogen";
private long bigObjectThresholdBytes = 256_000L;
private long bigObjectSampleWeightThresholdBytes = 48_000_000L;
private boolean enableStackTraces = true;

public static String usage() {
return "Usage: java JfrExporter " +
"--debug,-d --processId,-p <processId> " +
" --duration <ISO-duration> --application,-a <application>" +
" --bigObjectThreshold <bytes>" +
" --bigObjectSampleWeightThreshold <bytes>" +
" --disableStackTraces" +
" --influxUrl <influxUrl> --influxDatabase <influxDatabase>" +
" --influxUser <influxUser> --influxPassword <influxPassword>" +
" --perfanaUrl <perfanaUrl> --perfanaApiKey <perfanaApiKey>";
" --influxUser <influxUser> --influxPassword <influxPassword>";
}

public static void print(String message) {
Expand All @@ -69,6 +68,11 @@ public static Arguments parseArgs(String[] args) {
continue;
}

if (matches(arg, "--disableStackTraces", "disableStackTraces")) {
arguments.enableStackTraces = false;
continue;
}

if (matches(arg, "-p", "--processId", "processId")) {
String processId = options.remove();
arguments.processId = Integer.parseInt(processId);
Expand Down Expand Up @@ -100,16 +104,6 @@ public static Arguments parseArgs(String[] args) {
continue;
}

if (matches(arg, "", "--perfanaUrl", "perfanaUrl")) {
arguments.perfanaUrl = options.remove();
continue;
}

if (matches(arg, "", "--perfanaApiKey", "perfanaApiKey")) {
arguments.perfanaApiKey = options.remove();
continue;
}

if (matches(arg, "", "--duration", "duration")) {
arguments.duration = Duration.parse(options.remove());
continue;
Expand Down Expand Up @@ -171,14 +165,6 @@ public boolean isDebug() {
return debug;
}

public String getPerfanaUrl() {
return perfanaUrl;
}

public String getPerfanaApiKey() {
return perfanaApiKey;
}

public Duration getDuration() {
return duration;
}
Expand All @@ -194,15 +180,17 @@ public String toString() {
", influxUser='" + influxUser + '\'' +
", influxPassword='" + influxPassword + '\'' +
", debug=" + debug +
", perfanaUrl='" + perfanaUrl + '\'' +
", perfanaApiKey='" + perfanaApiKey + '\'' +
", duration=" + duration +
", enableStackTraces=" + enableStackTraces +
'}';
}

public String getInfluxRetentionPolicy() {
return influxRetentionPolicy;
}

public boolean isEnableStackTraces() {
return enableStackTraces;
}
}

9 changes: 8 additions & 1 deletion src/main/java/io/perfana/jfr/JfrEventHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@ public void register(JfrEventSettings jfrEventSettings) {
void handle(String eventName, RecordedEvent event) {
JfrEventSettings jfrEventSettings = events.get(eventName);
if (jfrEventSettings != null) {
jfrEventSettings.getOnJfrEvent().onEvent(event);
try {
jfrEventSettings.getOnJfrEvent().onEvent(event);
} catch (Throwable e) {
log.error("Error handling event %s: %s", eventName, e.getMessage());
}
}
else {
log.trace("Skip handle event: no event settings for event %s", eventName);
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/main/java/io/perfana/jfr/JfrExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,14 @@ private static void autoClose(JfrEventProcessor eventProcessor) {
}

private JfrEventProcessor createInfluxEventProcessor(Arguments args) {
InfluxWriterConfig config = new InfluxWriterConfig(args.getInfluxUrl(), args.getInfluxDatabase(), args.getInfluxUser(), args.getInfluxPassword(), args.getInfluxRetentionPolicy(), args.getApplication());
InfluxWriterConfig config = new InfluxWriterConfig(
args.getInfluxUrl(),
args.getInfluxDatabase(),
args.getInfluxUser(),
args.getInfluxPassword(),
args.getInfluxRetentionPolicy(),
args.getApplication(),
args.isEnableStackTraces());
InfluxWriter writer = new InfluxWriterNative(config);
return new InfluxEventProcessor(writer);
}
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/io/perfana/jfr/influx/InfluxWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@
package io.perfana.jfr.influx;

import io.perfana.jfr.ProcessedJfrEvent;
import org.jetbrains.annotations.NotNull;

import java.time.Instant;
import java.util.List;

public interface InfluxWriter extends AutoCloseable {

String STACKTRACE_DELIMITER = " --- ";

boolean isHealthy();

void writeMetricPoint(ProcessedJfrEvent event);
Expand All @@ -28,6 +33,15 @@ static long toEpochNs(Instant timestamp) {
return (timestamp.toEpochMilli() * 1_000_000) + timestamp.getNano();
}

@NotNull
static String formatStacktrace(List<String> stacktrace1, boolean enableStacktraces) {
return enableStacktraces
? String.join(STACKTRACE_DELIMITER, stacktrace1)
: stacktrace1.get(0)
+ STACKTRACE_DELIMITER + stacktrace1.get(1)
+ STACKTRACE_DELIMITER + stacktrace1.get(2);
}

@Override
void close() throws Exception;
}
5 changes: 4 additions & 1 deletion src/main/java/io/perfana/jfr/influx/InfluxWriterClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
public class InfluxWriterClient implements InfluxWriter, AutoCloseable {

private static final Logger log = Logger.getLogger(InfluxWriterClient.class);
private final boolean enableStacktraces;

private String application;

Expand All @@ -47,6 +48,8 @@ public InfluxWriterClient(InfluxWriterConfig config) {
);

this.writeApi = influxDBClient.makeWriteApi();

this.enableStacktraces = config.enableStacktraces();
}

@Override
Expand All @@ -62,7 +65,7 @@ public void writeMetricPoint(ProcessedJfrEvent event) {
.addField(event.field(), event.value());

if (!event.stacktrace().isEmpty()) {
String stacktrace = String.join("\n", event.stacktrace());
String stacktrace = InfluxWriter.formatStacktrace(event.stacktrace(), enableStacktraces);
point.addField("stacktrace", stacktrace);
}

Expand Down
12 changes: 9 additions & 3 deletions src/main/java/io/perfana/jfr/influx/InfluxWriterConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
*/
package io.perfana.jfr.influx;

public record InfluxWriterConfig(String url, String database, String username, String password, String retentionPolicy,
String application) {
}
public record InfluxWriterConfig(
String url,
String database,
String username,
String password,
String retentionPolicy,
String application,
boolean enableStacktraces)
{ }
Loading

0 comments on commit 34fe4de

Please sign in to comment.