# [[Declarative Configuration for OTel SDKs]]
![[Declarative Configuration for OTel.svg]]
[[Declarative]] configuration for [[OpenTelemetry]] is a new approach to [[Instrumentation]] that uses a [[YAML]]/[[JSON]] file or [[Environment variables]] to define things like:
- how you initialize the OTel [[SDK]]
- instrumentation libraries to use
- exporters and propagators
- resource attributes
and anything else that might otherwise be set in the code for the purposes of *configuring* the instrumentation/implementation.
## Example
### Without declarative config
Without using declarative config, here's what a typical OTel implementation might look like in [[Java]]:
```java
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
public class App {
public static void main(String[] args) {
// 👇 Imperative setup: creating all components manually
// 1. Define service name and resource attributes
Resource resource = Resource.getDefault()
.merge(Resource.builder()
.put("service.name", "payment-service")
.put("service.environment", "production")
.build());
// 2. Create the exporter
OtlpGrpcSpanExporter exporter = OtlpGrpcSpanExporter.builder()
.setEndpoint("https://otel-collector:4317")
.addHeader("x-api-key", System.getenv("OTEL_API_KEY"))
.build();
// 3. Configure the processor
BatchSpanProcessor processor = BatchSpanProcessor.builder(exporter)
.setScheduleDelay(java.time.Duration.ofMillis(5000))
.build();
// 4. Build the tracer provider
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.setResource(resource)
.addSpanProcessor(processor)
.build();
// 5. Initialize the global OpenTelemetry instance
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
.buildAndRegisterGlobal();
// 👇 Your instrumentation (manual or auto) uses this tracer
Tracer tracer = openTelemetry.getTracer("io.example.payment");
tracer.spanBuilder("checkout").startSpan().end();
}
}
```
Note that the code includes both instrumentation and configuration. In fact, most of that is configuration. Only the `Tracer tracer = openTelemetry.getTracer(...)` part is actual instrumentation.
### With declarative configuration
Declarative configuration can replace everything but the actual instrumentation lines.
You'd have the following in something like `otel-config.yaml`:
```yaml
resource:
service.name: payment-service
service.environment: production
traces:
sampler:
type: parentbased_traceidratio
argument: 0.5
processor:
type: batch
schedule_delay: 5000
exporter:
type: otlp
protocol: grpc
endpoint: https://otel-collector:4317
headers:
x-api-key: ${OTEL_API_KEY}
```
and then just have this in your code for the instrumentation:
```java
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
public class App {
public static void main(String[] args) {
// 👇 Declarative setup: automatically loads from environment / YAML
OpenTelemetry openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk();
// Only need to obtain and use a tracer now
Tracer tracer = openTelemetry.getTracer("io.example.payment");
tracer.spanBuilder("checkout").startSpan().end();
}
}
```
OR, instead of instrumenting the code manually, [[OTel Autoconfigure]] can be used to accomplish the same thing:
```
java -Dotel.config.file=otel-config.yaml \
-javaagent:opentelemetry-javaagent.jar \
-jar app.jar
```
## Availability per language
Declarative configuration in SDKs is new and only available for the following languages:
| Language | Status of Support |
| -------- | ----------------- |
| [[Java]] | Experimental |
| [[PHP]] | Experimental |
%%
# Excalidraw Data
## Text Elements
## Drawing
```json
{
"type": "excalidraw",
"version": 2,
"source": "https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/2.1.4",
"elements": [
{
"id": "4y8R7iOA",
"type": "text",
"x": 118.49495565891266,
"y": -333.44393157958984,
"width": 3.8599853515625,
"height": 24,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"roundness": null,
"seed": 967149026,
"version": 2,
"versionNonce": 939059582,
"isDeleted": true,
"boundElements": null,
"updated": 1713723615080,
"link": null,
"locked": false,
"text": "",
"rawText": "",
"fontSize": 20,
"fontFamily": 4,
"textAlign": "left",
"verticalAlign": "top",
"containerId": null,
"originalText": "",
"lineHeight": 1.2
}
],
"appState": {
"theme": "dark",
"viewBackgroundColor": "#ffffff",
"currentItemStrokeColor": "#1e1e1e",
"currentItemBackgroundColor": "transparent",
"currentItemFillStyle": "solid",
"currentItemStrokeWidth": 2,
"currentItemStrokeStyle": "solid",
"currentItemRoughness": 1,
"currentItemOpacity": 100,
"currentItemFontFamily": 4,
"currentItemFontSize": 20,
"currentItemTextAlign": "left",
"currentItemStartArrowhead": null,
"currentItemEndArrowhead": "arrow",
"scrollX": 583.2388916015625,
"scrollY": 573.6323852539062,
"zoom": {
"value": 1
},
"currentItemRoundness": "round",
"gridSize": null,
"gridColor": {
"Bold": "#C9C9C9FF",
"Regular": "#EDEDEDFF"
},
"currentStrokeOptions": null,
"previousGridSize": null,
"frameRendering": {
"enabled": true,
"clip": true,
"name": true,
"outline": true
}
},
"files": {}
}
```
%%