Skip to content

Commit ca26a77

Browse files
authored
fix: allow OTLP allocation and lock thresholds (#351)
Signed-off-by: Arnab Nandy <arnab_nandy7@yahoo.com>
1 parent b9df4dd commit ca26a77

3 files changed

Lines changed: 44 additions & 8 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ The agent can export async-profiler recordings using the experimental OpenTeleme
3636
The agent sends protobuf requests to `<server-address>/v1development/profiles`.
3737

3838
OTLP export requires the default `ASYNC` profiler and is not supported by the JFR profiler used on Windows.
39+
Only one profiling event can run at a time. Allocation and lock thresholds can be configured when their event is
40+
selected, for example with `PYROSCOPE_PROFILER_EVENT=alloc` and `PYROSCOPE_PROFILER_ALLOC=512k`. Multiple events
41+
remain supported in sampling mode because they run sequentially.
3942
The OpenTelemetry Profiles protocol and async-profiler output are experimental and may change incompatibly.
4043

4144
## Building

agent/src/main/java/io/pyroscope/javaagent/config/Config.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,11 @@ public final class Config {
204204
if (format == Format.OTLP && profilerType != ProfilerType.ASYNC) {
205205
throw new IllegalArgumentException("OTLP format is supported only by the ASYNC profiler");
206206
}
207-
if (format == Format.OTLP &&
208-
((profilingAlloc != null && !profilingAlloc.isEmpty()) ||
209-
(profilingLock != null && !profilingLock.isEmpty()))) {
210-
throw new IllegalArgumentException("OTLP format does not support allocation or lock profiling");
207+
final boolean sequentialSampling = samplingDuration != null && samplingEventOrder != null;
208+
if (format == Format.OTLP && !sequentialSampling &&
209+
((profilingAlloc != null && !profilingAlloc.isEmpty() && profilingEvent != EventType.ALLOC) ||
210+
(profilingLock != null && !profilingLock.isEmpty() && profilingEvent != EventType.LOCK))) {
211+
throw new IllegalArgumentException("OTLP format does not support multiple profiling events simultaneously");
211212
}
212213
this.pushQueueCapacity = pushQueueCapacity;
213214
this.labels = Collections.unmodifiableMap(labels);

agent/src/test/java/io/pyroscope/javaagent/config/OtlpConfigTest.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.pyroscope.javaagent.config;
22

33
import io.pyroscope.http.Format;
4+
import io.pyroscope.javaagent.EventType;
45
import io.pyroscope.javaagent.api.ConfigurationProvider;
56
import org.junit.jupiter.api.Test;
67

@@ -26,21 +27,52 @@ void rejectsOtlpWithJfrProfiler() {
2627
}
2728

2829
@Test
29-
void rejectsOtlpWithAllocationProfiling() {
30+
void acceptsOtlpWithAllocationProfiling() {
31+
Config config = Config.build(provider(
32+
"PYROSCOPE_FORMAT", "otlp",
33+
"PYROSCOPE_PROFILER_EVENT", "alloc",
34+
"PYROSCOPE_PROFILER_ALLOC", "512k"));
35+
assertEquals(EventType.ALLOC, config.profilingEvent);
36+
assertEquals("512k", config.profilingAlloc);
37+
}
38+
39+
@Test
40+
void acceptsOtlpWithLockProfiling() {
41+
Config config = Config.build(provider(
42+
"PYROSCOPE_FORMAT", "otlp",
43+
"PYROSCOPE_PROFILER_EVENT", "lock",
44+
"PYROSCOPE_PROFILER_LOCK", "10ms"));
45+
assertEquals(EventType.LOCK, config.profilingEvent);
46+
assertEquals("10ms", config.profilingLock);
47+
}
48+
49+
@Test
50+
void rejectsOtlpWithSimultaneousAllocationProfiling() {
3051
ConfigurationProvider provider = provider(
3152
"PYROSCOPE_FORMAT", "otlp",
3253
"PYROSCOPE_PROFILER_ALLOC", "512k");
3354
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> Config.build(provider));
34-
assertEquals("OTLP format does not support allocation or lock profiling", exception.getMessage());
55+
assertEquals("OTLP format does not support multiple profiling events simultaneously", exception.getMessage());
3556
}
3657

3758
@Test
38-
void rejectsOtlpWithLockProfiling() {
59+
void rejectsOtlpWithSimultaneousLockProfiling() {
3960
ConfigurationProvider provider = provider(
4061
"PYROSCOPE_FORMAT", "otlp",
4162
"PYROSCOPE_PROFILER_LOCK", "10ms");
4263
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> Config.build(provider));
43-
assertEquals("OTLP format does not support allocation or lock profiling", exception.getMessage());
64+
assertEquals("OTLP format does not support multiple profiling events simultaneously", exception.getMessage());
65+
}
66+
67+
@Test
68+
void acceptsOtlpWithSequentialSamplingEvents() {
69+
Config config = Config.build(provider(
70+
"PYROSCOPE_FORMAT", "otlp",
71+
"PYROSCOPE_PROFILER_ALLOC", "512k",
72+
"PYROSCOPE_PROFILER_LOCK", "10ms",
73+
"PYROSCOPE_SAMPLING_DURATION", "1s",
74+
"PYROSCOPE_SAMPLING_EVENT_ORDER", "cpu,alloc,lock"));
75+
assertEquals(3, config.samplingEventOrder.size());
4476
}
4577

4678
private static ConfigurationProvider provider(String... pairs) {

0 commit comments

Comments
 (0)