Skip to content

feat: add 'opentelemetry-exporter-otlp-json-common' package#4996

Open
herin049 wants to merge 10 commits intoopen-telemetry:mainfrom
herin049:feat/exporter-otlp-json-common
Open

feat: add 'opentelemetry-exporter-otlp-json-common' package#4996
herin049 wants to merge 10 commits intoopen-telemetry:mainfrom
herin049:feat/exporter-otlp-json-common

Conversation

@herin049
Copy link
Copy Markdown
Contributor

@herin049 herin049 commented Mar 18, 2026

Description

Follow up to #4910 to progress towards adding support for OTLP JSON.

Fixes #1003

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

tox -e py314-test-opentelemetry-exporter-otlp-json-common

Does This PR Require a Contrib Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@herin049 herin049 force-pushed the feat/exporter-otlp-json-common branch from a06e192 to 6a0c46f Compare March 19, 2026 02:39
@herin049 herin049 marked this pull request as ready for review March 20, 2026 01:33
@herin049 herin049 requested a review from a team as a code owner March 20, 2026 01:33
@tammy-baylis-swi
Copy link
Copy Markdown
Contributor

Thanks for this and the benchmarks! I like how it's laid out very similarly to the otlp-proto-common.

removal of ~200 lines of Windows getting-started and opentracing-shim jobs from test_0.yml

I believe they were moved to test_1.yml

@herin049
Copy link
Copy Markdown
Contributor Author

Thanks for this and the benchmarks! I like how it's laid out very similarly to the otlp-proto-common.

removal of ~200 lines of Windows getting-started and opentracing-shim jobs from test_0.yml

I believe they were moved to test_1.yml

That was my goal, although I made a few alterations/simplifications.

Copy link
Copy Markdown
Contributor

@tammy-baylis-swi tammy-baylis-swi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm, would be great if others from the discussion to have a look too.

@RahulGopathi
Copy link
Copy Markdown

RahulGopathi commented Apr 2, 2026

Hi, excited to see this progressing! We have a use case where OTLP JSON would be really valuable.

We're building an observability pipeline where traces need to be both forwarded to a backend (Langfuse) and persisted to disk as OTLP JSON files for audit/replay purposes. The current opentelemetry-exporter-otlp-proto-http only supports protobuf serialization, so we ended up writing a workaround using MessageToJson:

  from google.protobuf.json_format import MessageToJson
  from opentelemetry.exporter.otlp.proto.common.trace_encoder import encode_spans
  from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
  from opentelemetry.sdk.trace.export import SpanExportResult


  class OTLPJsonSpanExporter(OTLPSpanExporter):
      """OTLPSpanExporter that sends OTLP JSON instead of protobuf."""

      def export(self, spans):
          try:
              encoded = encode_spans(spans)
              serialized = MessageToJson(encoded, preserving_proto_field_name=True)
              self._session.headers["Content-Type"] = "application/json"
              return self._export(serialized.encode("utf-8"))
          except Exception:
              return SpanExportResult.FAILURE

This works but depends on internal APIs (encode_spans, _export). Having an official otlp-json-common package would give us a stable, supported way to produce spec-compliant OTLP JSON, both for HTTP export and file persistence.

Would love to see this merged. Happy to help test!

Copy link
Copy Markdown
Member

@pmcollins pmcollins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this. LGTM overall, just a concern about raising exceptions.

elif isinstance(sdk_exemplar.value, int):
json_exemplar.as_int = sdk_exemplar.value
else:
raise ValueError("Exemplar value must be an int or float")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this exception is not handled in this PR, but I suppose it could be handled by the caller in a subsequent one (we don't want the SDK to throw an unhandled exception). In any case, even if it were handled I'm not sure we want to fail the encoding call chain on a bad value. May be a better to log and keep going -- convert as much as possible to JSON and log any weird data that had to be skipped rather than skipping the entire message.

]
)
)
raise TypeError(f"Invalid type {type(value)} of value {value}")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto about raising an exception here.

{ name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" },
]
classifiers = [
"Development Status :: 5 - Production/Stable",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should this be 4 - Beta?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

Support JSON over HTTP in OTLP exporter

4 participants