Skip to content

Instantly share code, notes, and snippets.

@korniltsev
Created October 25, 2023 07:00
Show Gist options
  • Save korniltsev/68afb0dd09c596b7fd0306fa8b14ba6b to your computer and use it in GitHub Desktop.
Save korniltsev/68afb0dd09c596b7fd0306fa8b14ba6b to your computer and use it in GitHub Desktop.
App.java
import io.pyroscope.http.Format;
import io.pyroscope.javaagent.Profiler;
import io.pyroscope.javaagent.PyroscopeAgent;
import io.pyroscope.javaagent.Snapshot;
import io.pyroscope.javaagent.api.Exporter;
import io.pyroscope.javaagent.api.Logger;
import io.pyroscope.javaagent.api.ProfilingScheduler;
import io.pyroscope.javaagent.config.Config;
import io.pyroscope.javaagent.impl.DefaultLogger;
import io.pyroscope.javaagent.impl.PyroscopeExporter;
import io.pyroscope.labels.Pyroscope;
import io.pyroscope.labels.LabelsSet;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class App {
public static final int N_THREADS = 8;
public static void main(String[] args) {
Config config = new Config.Builder()
.setApplicationName("demo.app{qweqwe=asdasd}")
.setServerAddress("http://localhost:4040")
.setFormat(Format.JFR)
.setLogLevel(Logger.Level.DEBUG)
.setLabels(mapOf("user", "tolyan"))
.build();
DefaultLogger l = new DefaultLogger(Logger.Level.DEBUG, System.err);
PyroscopeExporter exporter = new PyroscopeExporter(config, l);
MyProfilingScheduler scheduler = new MyProfilingScheduler(exporter, l);
PyroscopeAgent.start(
new PyroscopeAgent.Options.Builder(config)
.setExporter(exporter)
.setScheduler(scheduler)
.build()
);
Pyroscope.setStaticLabels(mapOf("region", "us-east-1"));
new Thread(() -> {
while (true) {
scheduler.enable();
try {
Thread.sleep(20_000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
try {
scheduler.disable();
Thread.sleep(20_000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}).start();
appLogic();
}
private static void appLogic() {
ExecutorService executors = Executors.newFixedThreadPool(N_THREADS);
for (int i = 0; i < N_THREADS; i++) {
executors.submit(() -> {
Pyroscope.LabelsWrapper.run(new LabelsSet("thread_name", Thread.currentThread().getName()), () -> {
while (true) {
try {
fib(32L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
);
});
}
}
private static Map<String, String> mapOf(String... args) {
Map<String, String> staticLabels = new HashMap<>();
for (int i = 0; i < args.length; i += 2) {
staticLabels.put(args[i], args[i + 1]);
}
return staticLabels;
}
private static long fib(Long n) throws InterruptedException {
if (n == 0L) {
return 0L;
}
if (n == 1L) {
return 1L;
}
// Thread.sleep(100);
return fib(n - 1) + fib(n - 2);
}
private static class MyStdoutExporter implements Exporter {
@Override
public void export(Snapshot snapshot) {
System.out.printf("Export %d %d%n", snapshot.data.length, snapshot.labels.toByteArray().length);
}
}
private static class MyProfilingScheduler implements ProfilingScheduler, Runnable {
private final PyroscopeExporter exporter;
private final DefaultLogger log;
private boolean enabled = true;
private Thread myThread;
private Profiler profiler;
public MyProfilingScheduler(PyroscopeExporter exporter, DefaultLogger l) {
this.exporter = exporter;
this.log = l;
}
@Override
public void start(Profiler profiler) {
synchronized (this) {
this.profiler = profiler;
if (enabled) {
myThread = new Thread(this);
myThread.start();
}
}
}
public void enable() {
log.log(Logger.Level.DEBUG, "enable");
synchronized (this) {
if (enabled) {
return;
}
this.enabled = true;
if (this.profiler != null) {
if (myThread != null) {
throw new IllegalStateException();
}
myThread = new Thread(this);
myThread.start();
}
}
}
public void disable() throws InterruptedException {
log.log(Logger.Level.DEBUG, "disable");
Thread t = myThread;
synchronized (this) {
if (!enabled) {
return;
}
if (t != null) {
t.interrupt();
}
enabled = false;
}
if (t != null) {
log.log(Logger.Level.DEBUG, "joining");
t.join();
log.log(Logger.Level.DEBUG, "joined");
}
}
@Override
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) {
break;
}
Instant startTime = Instant.now();
profiler.start();
log.log(Logger.Level.DEBUG, "started at %s", startTime.toString());
try {
Thread.sleep(2_000);
} catch (InterruptedException e) {
log.log(Logger.Level.DEBUG, "interrupted at %s", Instant.now().toString());
profiler.stop();
Thread.currentThread().interrupt();
break;
}
profiler.stop();
Instant endTime = Instant.now();
log.log(Logger.Level.DEBUG, "stopped at %s", startTime.toString());
exporter.export(profiler.dumpProfile(startTime, endTime));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment