0
# In-Memory Exporters
1
2
In-memory exporters and readers for collecting telemetry data during tests. These components capture spans, metrics, and logs in memory for easy access and validation in test scenarios.
3
4
## Capabilities
5
6
### Span Exporter
7
8
In-memory span exporter that collects SpanData objects during test execution.
9
10
```java { .api }
11
class InMemorySpanExporter implements SpanExporter {
12
// Factory method
13
static InMemorySpanExporter create();
14
15
// Data access
16
List<SpanData> getFinishedSpanItems();
17
void reset();
18
19
// SpanExporter interface methods
20
CompletableResultCode export(Collection<SpanData> spans);
21
CompletableResultCode flush();
22
CompletableResultCode shutdown();
23
}
24
```
25
26
Usage examples:
27
28
```java
29
// Setup in-memory span exporter
30
InMemorySpanExporter spanExporter = InMemorySpanExporter.create();
31
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
32
.addSpanProcessor(BatchSpanProcessor.builder(spanExporter).build())
33
.build();
34
35
// Use OpenTelemetry normally in your code
36
Tracer tracer = tracerProvider.get("test");
37
Span span = tracer.spanBuilder("test-operation").startSpan();
38
span.setAttribute("key", "value");
39
span.end();
40
41
// Access collected spans in tests
42
List<SpanData> spans = spanExporter.getFinishedSpanItems();
43
assertThat(spans).hasSize(1);
44
assertThat(spans.get(0)).hasName("test-operation");
45
46
// Clean up for next test
47
spanExporter.reset();
48
```
49
50
### Metric Exporter
51
52
In-memory metric exporter that collects MetricData objects with configurable aggregation temporality.
53
54
```java { .api }
55
class InMemoryMetricExporter implements MetricExporter {
56
// Factory methods
57
static InMemoryMetricExporter create();
58
static InMemoryMetricExporter create(AggregationTemporality temporality);
59
60
// Data access
61
List<MetricData> getFinishedMetricItems();
62
void reset();
63
64
// MetricExporter interface methods
65
AggregationTemporality getAggregationTemporality(InstrumentType instrumentType);
66
CompletableResultCode export(Collection<MetricData> metrics);
67
CompletableResultCode flush();
68
CompletableResultCode shutdown();
69
}
70
```
71
72
Usage examples:
73
74
```java
75
// Setup in-memory metric exporter with default temporality
76
InMemoryMetricExporter metricExporter = InMemoryMetricExporter.create();
77
SdkMeterProvider meterProvider = SdkMeterProvider.builder()
78
.registerMetricReader(
79
PeriodicMetricReader.builder(metricExporter)
80
.setInterval(Duration.ofSeconds(1))
81
.build())
82
.build();
83
84
// Use OpenTelemetry normally
85
Meter meter = meterProvider.get("test");
86
LongCounter counter = meter.counterBuilder("test-counter").build();
87
counter.add(10, Attributes.of(AttributeKey.stringKey("key"), "value"));
88
89
// Trigger collection and access metrics
90
List<MetricData> metrics = metricExporter.getFinishedMetricItems();
91
assertThat(metrics).hasSize(1);
92
93
// Setup with specific temporality
94
InMemoryMetricExporter deltaExporter = InMemoryMetricExporter.create(AggregationTemporality.DELTA);
95
```
96
97
### Log Record Exporter
98
99
In-memory log record exporter that collects LogRecordData objects during test execution.
100
101
```java { .api }
102
class InMemoryLogRecordExporter implements LogRecordExporter {
103
// Factory method
104
static InMemoryLogRecordExporter create();
105
106
// Data access
107
List<LogRecordData> getFinishedLogRecordItems();
108
void reset();
109
110
// LogRecordExporter interface methods
111
CompletableResultCode export(Collection<LogRecordData> logs);
112
CompletableResultCode flush();
113
CompletableResultCode shutdown();
114
}
115
```
116
117
Usage examples:
118
119
```java
120
// Setup in-memory log exporter
121
InMemoryLogRecordExporter logExporter = InMemoryLogRecordExporter.create();
122
SdkLoggerProvider loggerProvider = SdkLoggerProvider.builder()
123
.addLogRecordProcessor(BatchLogRecordProcessor.builder(logExporter).build())
124
.build();
125
126
// Use OpenTelemetry logging
127
Logger logger = loggerProvider.get("test");
128
logger.logRecordBuilder()
129
.setBody("Test log message")
130
.setSeverity(Severity.INFO)
131
.setAttribute(AttributeKey.stringKey("key"), "value")
132
.emit();
133
134
// Access collected logs
135
List<LogRecordData> logs = logExporter.getFinishedLogRecordItems();
136
assertThat(logs).hasSize(1);
137
assertThat(logs.get(0)).hasBody("Test log message");
138
```
139
140
### Metric Reader
141
142
In-memory metric reader that provides more control over metric collection with configurable aggregation and temporality selection.
143
144
```java { .api }
145
class InMemoryMetricReader implements MetricReader {
146
// Factory methods
147
static InMemoryMetricReaderBuilder builder();
148
static InMemoryMetricReader create();
149
static InMemoryMetricReader create(
150
AggregationTemporalitySelector temporalitySelector,
151
DefaultAggregationSelector aggregationSelector);
152
static InMemoryMetricReader createDelta();
153
154
// Data collection
155
Collection<MetricData> collectAllMetrics();
156
157
// MetricReader interface methods
158
void register(CollectionRegistration registration);
159
AggregationTemporality getAggregationTemporality(InstrumentType instrumentType);
160
Aggregation getDefaultAggregation(InstrumentType instrumentType);
161
CompletableResultCode forceFlush();
162
CompletableResultCode shutdown();
163
MemoryMode getMemoryMode();
164
}
165
```
166
167
Usage examples:
168
169
```java
170
// Create with default configuration
171
InMemoryMetricReader reader = InMemoryMetricReader.create();
172
SdkMeterProvider meterProvider = SdkMeterProvider.builder()
173
.registerMetricReader(reader)
174
.build();
175
176
// Create delta reader for delta temporality
177
InMemoryMetricReader deltaReader = InMemoryMetricReader.createDelta();
178
179
// Create with custom configuration
180
InMemoryMetricReader customReader = InMemoryMetricReader.create(
181
instrumentType -> AggregationTemporality.CUMULATIVE,
182
InstrumentType.HISTOGRAM.equals(instrumentType) ?
183
Aggregation.explicitBucketHistogram() : Aggregation.defaultAggregation()
184
);
185
186
// Collect metrics on demand
187
Collection<MetricData> currentMetrics = reader.collectAllMetrics();
188
assertThat(currentMetrics).hasSize(expectedMetricCount);
189
```
190
191
### Metric Reader Builder
192
193
Builder for creating customized InMemoryMetricReader instances with specific configuration.
194
195
```java { .api }
196
class InMemoryMetricReaderBuilder {
197
// Configuration methods
198
InMemoryMetricReaderBuilder setAggregationTemporalitySelector(AggregationTemporalitySelector selector);
199
InMemoryMetricReaderBuilder setDefaultAggregationSelector(DefaultAggregationSelector selector);
200
InMemoryMetricReaderBuilder setMemoryMode(MemoryMode memoryMode);
201
202
// Build method
203
InMemoryMetricReader build();
204
}
205
```
206
207
Usage examples:
208
209
```java
210
// Build custom metric reader
211
InMemoryMetricReader reader = InMemoryMetricReader.builder()
212
.setAggregationTemporalitySelector(instrumentType -> {
213
if (instrumentType == InstrumentType.COUNTER) {
214
return AggregationTemporality.DELTA;
215
}
216
return AggregationTemporality.CUMULATIVE;
217
})
218
.setDefaultAggregationSelector(instrumentType -> {
219
if (instrumentType == InstrumentType.HISTOGRAM) {
220
return Aggregation.explicitBucketHistogram(Arrays.asList(1.0, 5.0, 10.0, 50.0));
221
}
222
return Aggregation.defaultAggregation();
223
})
224
.setMemoryMode(MemoryMode.REUSABLE_DATA)
225
.build();
226
```
227
228
## Types
229
230
```java { .api }
231
// OpenTelemetry core exporter interfaces
232
interface SpanExporter {
233
CompletableResultCode export(Collection<SpanData> spans);
234
CompletableResultCode flush();
235
CompletableResultCode shutdown();
236
}
237
238
interface MetricExporter {
239
AggregationTemporality getAggregationTemporality(InstrumentType instrumentType);
240
CompletableResultCode export(Collection<MetricData> metrics);
241
CompletableResultCode flush();
242
CompletableResultCode shutdown();
243
}
244
245
interface LogRecordExporter {
246
CompletableResultCode export(Collection<LogRecordData> logs);
247
CompletableResultCode flush();
248
CompletableResultCode shutdown();
249
}
250
251
interface MetricReader {
252
void register(CollectionRegistration registration);
253
AggregationTemporality getAggregationTemporality(InstrumentType instrumentType);
254
Aggregation getDefaultAggregation(InstrumentType instrumentType);
255
CompletableResultCode forceFlush();
256
CompletableResultCode shutdown();
257
MemoryMode getMemoryMode();
258
}
259
260
// Configuration types
261
enum AggregationTemporality { CUMULATIVE, DELTA }
262
enum InstrumentType { COUNTER, UP_DOWN_COUNTER, HISTOGRAM, GAUGE, OBSERVABLE_COUNTER, OBSERVABLE_UP_DOWN_COUNTER, OBSERVABLE_GAUGE }
263
enum MemoryMode { REUSABLE_DATA, IMMUTABLE_DATA }
264
265
// Functional interfaces for configuration
266
interface AggregationTemporalitySelector {
267
AggregationTemporality getAggregationTemporality(InstrumentType instrumentType);
268
}
269
270
interface DefaultAggregationSelector {
271
Aggregation getDefaultAggregation(InstrumentType instrumentType);
272
}
273
274
// Result handling
275
class CompletableResultCode {
276
static CompletableResultCode ofSuccess();
277
static CompletableResultCode ofFailure();
278
CompletableResultCode join(long timeout, TimeUnit unit);
279
boolean isSuccess();
280
}
281
```
282
283
## Integration Patterns
284
285
### Complete Test Setup
286
287
Example showing how to set up all exporters together for comprehensive testing:
288
289
```java
290
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
291
class IntegrationTest {
292
293
private InMemorySpanExporter spanExporter;
294
private InMemoryMetricReader metricReader;
295
private InMemoryLogRecordExporter logExporter;
296
private OpenTelemetry openTelemetry;
297
298
@BeforeAll
299
void setUp() {
300
spanExporter = InMemorySpanExporter.create();
301
metricReader = InMemoryMetricReader.create();
302
logExporter = InMemoryLogRecordExporter.create();
303
304
OpenTelemetrySdk sdk = OpenTelemetrySdk.builder()
305
.setTracerProvider(
306
SdkTracerProvider.builder()
307
.addSpanProcessor(BatchSpanProcessor.builder(spanExporter).build())
308
.build())
309
.setMeterProvider(
310
SdkMeterProvider.builder()
311
.registerMetricReader(metricReader)
312
.build())
313
.setLoggerProvider(
314
SdkLoggerProvider.builder()
315
.addLogRecordProcessor(BatchLogRecordProcessor.builder(logExporter).build())
316
.build())
317
.build();
318
319
openTelemetry = sdk;
320
}
321
322
@BeforeEach
323
void clearData() {
324
spanExporter.reset();
325
logExporter.reset();
326
// Note: metric reader doesn't have reset, use new collection
327
}
328
329
@Test
330
void testFullTelemetry() {
331
// Use openTelemetry instance in your code
332
// Then validate collected data
333
assertThat(spanExporter.getFinishedSpanItems()).hasSize(expectedSpans);
334
assertThat(metricReader.collectAllMetrics()).hasSize(expectedMetrics);
335
assertThat(logExporter.getFinishedLogRecordItems()).hasSize(expectedLogs);
336
}
337
}
338
```