1616from opentelemetry .metrics import CallbackT , Counter , Histogram , UpDownCounter
1717from opentelemetry .sdk .trace import ReadableSpan , Span
1818from opentelemetry .semconv .trace import SpanAttributes
19- from opentelemetry .trace import Tracer
19+ from opentelemetry .trace import StatusCode , Tracer
2020from opentelemetry .util import types as otel_types
2121from typing_extensions import LiteralString , ParamSpec
2222
2626from .config import GLOBAL_CONFIG , LogfireConfig
2727from .constants import (
2828 ATTRIBUTES_JSON_SCHEMA_KEY ,
29+ ATTRIBUTES_LOG_LEVEL_NUM_KEY ,
2930 ATTRIBUTES_MESSAGE_KEY ,
3031 ATTRIBUTES_MESSAGE_TEMPLATE_KEY ,
3132 ATTRIBUTES_SAMPLE_RATE_KEY ,
3233 ATTRIBUTES_SPAN_TYPE_KEY ,
3334 ATTRIBUTES_TAGS_KEY ,
3435 ATTRIBUTES_VALIDATION_ERROR_KEY ,
3536 DISABLE_CONSOLE_KEY ,
37+ LEVEL_NUMBERS ,
3638 NULL_ARGS_KEY ,
3739 OTLP_MAX_INT_SIZE ,
3840 LevelName ,
@@ -663,6 +665,11 @@ def log(
663665 exc_info = exc_info [1 ]
664666 if isinstance (exc_info , BaseException ):
665667 _record_exception (span , exc_info )
668+ if otlp_attributes [ATTRIBUTES_LOG_LEVEL_NUM_KEY ] >= LEVEL_NUMBERS ['error' ]: # type: ignore
669+ # Set the status description to the exception message.
670+ # OTEL only lets us set the description when the status code is ERROR,
671+ # which we only want to do when the log level is error.
672+ _set_exception_status (span , exc_info )
666673 elif exc_info is not None : # pragma: no cover
667674 raise TypeError (f'Invalid type for exc_info: { exc_info .__class__ .__name__ } ' )
668675
@@ -1773,6 +1780,15 @@ def _exit_span(span: trace_api.Span, exception: BaseException | None) -> None:
17731780 _record_exception (span , exception , escaped = True )
17741781
17751782
1783+ def _set_exception_status (span : trace_api .Span , exception : BaseException ):
1784+ span .set_status (
1785+ trace_api .Status (
1786+ status_code = StatusCode .ERROR ,
1787+ description = f'{ exception .__class__ .__name__ } : { exception } ' ,
1788+ )
1789+ )
1790+
1791+
17761792@handle_internal_errors ()
17771793def _record_exception (
17781794 span : trace_api .Span ,
@@ -1788,12 +1804,7 @@ def _record_exception(
17881804 # This means we know that the exception hasn't been handled,
17891805 # so we can set the OTEL status and the log level to error.
17901806 if escaped :
1791- span .set_status (
1792- trace_api .Status (
1793- status_code = trace_api .StatusCode .ERROR ,
1794- description = f'{ exception .__class__ .__name__ } : { exception } ' ,
1795- )
1796- )
1807+ _set_exception_status (span , exception )
17971808 span .set_attributes (log_level_attributes ('error' ))
17981809
17991810 attributes = {** (attributes or {})}
0 commit comments