> ## 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.

# Demo Status Codes

> Explains how to set OpenTelemetry span status to OK or ERROR for HTTP calls, record attributes like http.status_code, propagate context, and handle exceptions for accurate tracing.

This lesson explains how to set the status code on OpenTelemetry spans to reflect success or failure of operations (for example, outgoing HTTP calls). By default OpenTelemetry leaves a span's status as `UNSET` until your application or instrumentation sets it explicitly. When an application crash occurs, instrumentation often marks the span as `ERROR` automatically. For normal request flows you should explicitly set status to `OK` for success and `ERROR` for handled failures.

<Callout icon="lightbulb" color="#1CB2FE">
  Spans default to `UNSET`. To represent success or failure in traces, explicitly set the span status to `OK` or `ERROR` and record relevant attributes like `http.status_code`.
</Callout>

Below is an example trace timeline from Jaeger showing a payment service with a failed request span (image preserved from original content):

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/OYg0ei_WZpJtYDrJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Demo-Status-Codes/jaeger-ui-payment-service-timeline.jpg?fit=max&auto=format&n=OYg0ei_WZpJtYDrJ&q=85&s=9611b41d946e1657adb8dafd49b68203" alt="The image shows a trace timeline from the Jaeger UI, detailing operations of a payment service. It includes spans for validating a card and a failed request to the charge API with an error message related to a connection issue." width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Demo-Status-Codes/jaeger-ui-payment-service-timeline.jpg" />
</Frame>

Why set span status?

* Communicates high-level outcome of an operation to downstream analysis tools.
* Helps filtering and alerting in tracing backends (errors vs. successful traces).
* Augments other attributes (like `http.status_code`) for richer context.

Recommended steps for an outgoing HTTP call

1. Add semantic attributes to the span: HTTP method, URL.
2. Propagate context (inject headers) before making the request.
3. Record events for request lifecycle (sending, sent, received).
4. Set `http.status_code` as a span attribute using the HTTP response.
5. Explicitly set span status to `OK` or `ERROR` depending on the outcome.

Example: minimal, corrected Python instrumentation and status handling

* First, configure tracing (tracer provider, resource, and exporter):

```python theme={null}
# configure_tracer.py
import requests
from opentelemetry import trace
from opentelemetry.trace import Status, StatusCode
from opentelemetry.propagate import inject
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter

def configure_tracer():
    resource = Resource.create({
        "service.name": "payment-service",
        "service.version": "0.2.0"
    })
    provider = TracerProvider(resource=resource)
    provider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
    trace.set_tracer_provider(provider)
    return trace.get_tracer(__name__, "0.1.0")
```

* Then use the tracer when making HTTP calls, set attributes, record events, and set status:

```python theme={null}
# payment.py
import requests
from opentelemetry.propagate import inject
from opentelemetry.trace import Status, StatusCode
from configure_tracer import configure_tracer

tracer = configure_tracer()

def call_charge_api():
    url = "http://127.0.0.1:5002/charge"

    with tracer.start_as_current_span("Request to Charge API") as span:
        # Use semantic attribute names
        span.set_attributes({
            "http.method": "GET",
            "http.url": url
        })

        headers = {}
        inject(headers)  # propagate context
        span.add_event("Sending Request")

        try:
            resp = requests.get(url, headers=headers)
            span.add_event("Request sent", {"url": url})
            # record HTTP status code as an attribute
            span.set_attribute("http.status_code", resp.status_code)

            # Set span status explicitly based on response
            # Treat 2xx responses as success, others as errors (adjust as needed)
            if 200 <= resp.status_code < 300:
                span.set_status(Status(StatusCode.OK))
            else:
                span.set_status(Status(StatusCode.ERROR))

            return resp

        except requests.RequestException as exc:
            # Network/connection failures should set status to ERROR
            span.record_exception(exc)
            span.set_status(Status(StatusCode.ERROR))
            raise
```

Mapping HTTP responses to span status (recommended defaults)

| HTTP result       | Example codes | Recommended span status   | Why                                                                  |
| ----------------- | ------------- | ------------------------- | -------------------------------------------------------------------- |
| Success           | `200–299`     | `OK`                      | Successful response; mark span successful.                           |
| Client error      | `400–499`     | `ERROR` (or custom logic) | Most client errors are failures; you may treat some codes specially. |
| Server error      | `500–599`     | `ERROR`                   | Server-side failures indicate error conditions.                      |
| Network/exception | N/A           | `ERROR`                   | Exceptions and timeouts should mark the span `ERROR`.                |

<Callout icon="warning" color="#FF6B6B">
  Do not rely solely on span status for debugging. Always record attributes like `http.status_code`, add meaningful events, and call `span.record_exception()` when catching exceptions to preserve stack/exception details.
</Callout>

Notes and best practices

* Import and use `Status` and `StatusCode` from `opentelemetry.trace` and call `span.set_status(Status(StatusCode.OK))` or `span.set_status(Status(StatusCode.ERROR))`.
* Recording `http.status_code` as an attribute helps trace UIs and analysis tools provide richer context and filters.
* Define your application's notion of "success"—for example, some APIs return 404 or 409 in normal flows; you may decide to mark those as `OK` in specific contexts.
* Always propagate context (`inject`) for distributed traces so downstream services are linked.

After implementing the above and running the application with a successful request, the trace timeline will show the "Request to Charge API" span marked as `OK`. The Jaeger UI for that trace is shown below (image preserved from original content):

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/OYg0ei_WZpJtYDrJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Demo-Status-Codes/jaeger-ui-trace-timeline-payment-service.jpg?fit=max&auto=format&n=OYg0ei_WZpJtYDrJ&q=85&s=b93b2ae5ce414da93ed8a44fe5bd0abe" alt="The image shows a Jaeger UI displaying a trace timeline for a payment service. It details various spans, including HTTP method and status code for the &#x22;Request to Charge API.&#x22;" width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Instrumentation/Demo-Status-Codes/jaeger-ui-trace-timeline-payment-service.jpg" />
</Frame>

Links and references

* OpenTelemetry: [https://opentelemetry.io/](https://opentelemetry.io/)
* Jaeger Tracing: [https://www.jaegertracing.io/](https://www.jaegertracing.io/)
* OpenTelemetry semantic conventions (HTTP): [https://opentelemetry.io/docs/reference/specification/trace/semantic\_conventions/http/](https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/)

<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/b38469f5-8819-4aea-8538-63233d729256" />
</CardGroup>
