> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Span Processors and Exporters

> Explains OpenTelemetry span processors and exporters, their roles, Simple versus Batch processors, exporter behaviors, and production best practices for reliable telemetry delivery.

This lesson expands on span creation and instrumentation by explaining how span processors and span exporters interact within the OpenTelemetry SDK. You'll see how processors hook into span lifecycle events, how exporters deliver span data, and which combinations make sense for development versus production.

Quick example: print spans to the console

```python theme={null}
import requests

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter

# Set up the tracer provider and console exporter
trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer(__name__)

# Configure the processor to print spans to the console
span_processor = SimpleSpanProcessor(ConsoleSpanExporter())
trace.get_tracer_provider().add_span_processor(span_processor)

def call_slow_api():
    with tracer.start_as_current_span("call_httpbin_delay"):
        url = "http://httpbin.org/delay/2"
        response = requests.get(url)
        return response.text

def main():
    with tracer.start_as_current_span("main_function_span"):
        print("Calling slow API...")
        result = call_slow_api()
        print("Done! Response length:", len(result))

if __name__ == "__main__":
    main()
```

When you run the script, the application output might show the usual program prints:

```plaintext theme={null}
Done! Response length: 358
```

And the ConsoleSpanExporter will emit JSON representations of spans, for example:

```json theme={null}
{
  "name": "call_httpbin_delay",
  "context": {
    "trace_id": "0x4998946a263b30828807138967d73",
    "span_id": "0x46dad3e62ea2b0"
  },
  "kind": "SpanKind_INTERNAL",
  "start_time": "2025-06-10T11:57:19.783180Z",
  "end_time": "2025-06-10T11:57:22.079506Z",
  "status_code": "UNSET",
  "attributes": {},
  "events": [],
  "links": [],
  "resource": {
    "attributes": {
      "telemetry.sdk.language": "python",
      "telemetry.sdk.name": "opentelemetry",
      "telemetry.sdk.version": "1.31.1"
    }
  },
  "schema_url": ""
}
```

```json theme={null}
{
  "name": "main_function_span",
  "context": {
    "trace_id": "0x4998946a263b30828807138967d73",
    "span_id": "0x2e4bcac22113"
  },
  "kind": "SpanKind_INTERNAL",
  "start_time": null,
  "end_time": null,
  "status_code": "UNSET",
  "attributes": {},
  "events": [],
  "links": [],
  "resource": {
    "attributes": {
      "telemetry.sdk.language": "python",
      "telemetry.sdk.name": "opentelemetry",
      "telemetry.sdk.version": "1.31.1",
      "service.name": "unknown_service"
    }
  },
  "schema_url": ""
}
```

How processors and exporters fit together
A span processor lives between the TracerProvider and an exporter. It receives lifecycle callbacks (typically onStart and onEnd) so it can observe spans when they start and finish. Processors generally only act on spans that are recording — i.e., `span.is_recording()` — to avoid unnecessary work on non-recording spans.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/OYg0ei_WZpJtYDrJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Span-Processors-and-Exporters/span-processors-three-step-process-diagram.jpg?fit=max&auto=format&n=OYg0ei_WZpJtYDrJ&q=85&s=dfd60c9c224457b3aa0eae6fb5b7b9b2" alt="The image illustrates a three-step process of how span processors work, involving hooking into span start and end, running if the span is recording, and processing spans before export." width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Span-Processors-and-Exporters/span-processors-three-step-process-diagram.jpg" />
</Frame>

Processor types: immediate vs. batched
OpenTelemetry SDKs provide two common processor implementations:

* SimpleSpanProcessor
  * Forwards each finished span immediately to the configured exporter.
  * Great for local development and debugging because spans appear right away.
  * Not ideal for high-volume production workloads: every finished span triggers an export call.

* BatchSpanProcessor
  * Buffers spans in memory and exports them as batches (on a timer or when buffer thresholds are met).
  * Much more efficient for production and recommended as the default.

Think of SimpleSpanProcessor as a firehose (direct and immediate) and BatchSpanProcessor as a postal service (batching and scheduled delivery).

<Callout icon="lightbulb" color="#1CB2FE">
  BatchSpanProcessor is generally recommended for production because it minimizes export overhead. Use SimpleSpanProcessor for learning, debugging, or when you need immediate visibility of spans.
</Callout>

Exporters: destinations and responsibilities
A span exporter takes span data and delivers it to an external destination (console, OTLP endpoint, or a vendor backend). The exporter is responsible for converting span objects into the expected wire/transport format and transmitting them.

Common exporters and when to use them:

|            Exporter | Purpose / Use case                   | Notes / Examples                                                                                                         |
| ------------------: | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| ConsoleSpanExporter | Print spans to stdout for debugging  | Quick feedback during development                                                                                        |
|      OTLP exporters | Send spans using the `OTLP` protocol | Use with OpenTelemetry Collector or OTLP-compatible backends ([OTLP protocol](https://opentelemetry.io/protocols/otlp/)) |
|      JaegerExporter | Send spans to Jaeger                 | Use when your observability backend is Jaeger ([Jaeger](https://www.jaegertracing.io/))                                  |
|      ZipkinExporter | Send spans to Zipkin                 | Use when your backend is Zipkin ([Zipkin](https://zipkin.io/))                                                           |

Exporter lifecycle and important methods
Exporters expose a small set of behaviors application authors should understand:

1. export(spans): Send a batch of spans to the configured destination (BatchSpanProcessor calls this automatically).
2. shutdown(): Stop exporting and release resources. Call during application termination to avoid losing telemetry.
3. force\_flush() / forceFlush(): Attempt to immediately export any buffered spans, bypassing normal batching.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/OYg0ei_WZpJtYDrJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Span-Processors-and-Exporters/exporter-behaviors-export-shutdown-forceflush.jpg?fit=max&auto=format&n=OYg0ei_WZpJtYDrJ&q=85&s=d94e98c2870f0c3269f120b12bcab356" alt="The image describes three key exporter behaviors: &#x22;export()&#x22; to send a batch of spans, &#x22;shutdown()&#x22; to clean up and stop exporting, and &#x22;forceFlush()&#x22; to try exporting pending spans immediately." width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Span-Processors-and-Exporters/exporter-behaviors-export-shutdown-forceflush.jpg" />
</Frame>

Putting the pieces together

* Tracer: creates spans as your application instrumentations run.
* Processor: observes span lifecycle events (onStart/onEnd). SimpleSpanProcessor exports immediately; BatchSpanProcessor buffers and exports in batches (recommended for production).
* Exporter: formats and transmits spans to a destination (console, OTLP, Jaeger, Zipkin, etc.). Use `force_flush()` and `shutdown()` to ensure reliable delivery at shutdown.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/OYg0ei_WZpJtYDrJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Span-Processors-and-Exporters/span-processors-exporters-recap-batch.jpg?fit=max&auto=format&n=OYg0ei_WZpJtYDrJ&q=85&s=89ae62a20f468b7acdc1760165603a93" alt="The image is a recap of span processors and exporters, explaining their roles and recommending the use of BatchSpanProcessor in production." width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Span-Processors-and-Exporters/span-processors-exporters-recap-batch.jpg" />
</Frame>

Best practices and production guidance

* Use BatchSpanProcessor for production to reduce network and CPU overhead.
* Configure exporter timeouts and retry policies (when supported) to handle transient failures.
* Always call `shutdown()` (or ensure the SDK does so) during graceful shutdown to minimize data loss.
* If you need telemetry routing, enrichment, or buffering across services, send spans to an OpenTelemetry Collector using OTLP and let the Collector forward to your backends.

<Callout icon="warning" color="#FF6B6B">
  Be sure to call exporter `shutdown()` or use `force_flush()` on application shutdown. Failing to flush buffered spans can result in lost telemetry.
</Callout>

Collector and typical deployment patterns
Many deployments route telemetry from applications to an OpenTelemetry Collector using OTLP. The Collector centralizes processing, sampling, batching, and routing to one or more backends — improving flexibility and operational control.

Links and references

* [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/)
* [OTLP protocol](https://opentelemetry.io/protocols/otlp/)
* [Kubernetes Observability patterns and the OpenTelemetry Collector](https://opentelemetry.io/docs/)
* [Jaeger Tracing](https://www.jaegertracing.io/)
* [Zipkin](https://zipkin.io/)

That concludes this lesson on span processors and exporters.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/prep-course-opentelemetry-certified-associate-certification-otca/module/d97970ef-6201-45c2-813e-e03bc75ad77a/lesson/0a375888-a1fc-452e-889e-7380e7b4de65" />
</CardGroup>
