-
Notifications
You must be signed in to change notification settings - Fork 336
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(traces): add
v1/traces
HTTP endpoint to handle `ExportTraceSer…
…viceRequest` (#1968) feat(traces): add `v1/traces` HTTP endpoint to handle `ExportTraceServiceRequest`
- Loading branch information
1 parent
d5e5a85
commit 3c94dea
Showing
2 changed files
with
62 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import asyncio | ||
import gzip | ||
import zlib | ||
from typing import Protocol | ||
|
||
from google.protobuf.message import DecodeError | ||
from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ( | ||
ExportTraceServiceRequest, | ||
) | ||
from opentelemetry.proto.trace.v1.trace_pb2 import Span | ||
from starlette.endpoints import HTTPEndpoint | ||
from starlette.requests import Request | ||
from starlette.responses import Response | ||
from starlette.status import HTTP_415_UNSUPPORTED_MEDIA_TYPE, HTTP_422_UNPROCESSABLE_ENTITY | ||
|
||
|
||
class SupportsPutSpan(Protocol): | ||
def put(self, span: Span) -> None: | ||
... | ||
|
||
|
||
class TraceHandler(HTTPEndpoint): | ||
queue: SupportsPutSpan | ||
|
||
async def post(self, request: Request) -> Response: | ||
content_type = request.headers.get("content-type") | ||
if content_type != "application/x-protobuf": | ||
return Response( | ||
content=f"Unsupported content type: {content_type}", | ||
status_code=HTTP_415_UNSUPPORTED_MEDIA_TYPE, | ||
) | ||
content_encoding = request.headers.get("content-encoding") | ||
if content_encoding and content_encoding not in ("gzip", "deflate"): | ||
return Response( | ||
content=f"Unsupported content encoding: {content_encoding}", | ||
status_code=HTTP_415_UNSUPPORTED_MEDIA_TYPE, | ||
) | ||
body = await request.body() | ||
if content_encoding == "gzip": | ||
body = gzip.decompress(body) | ||
elif content_encoding == "deflate": | ||
body = zlib.decompress(body) | ||
req = ExportTraceServiceRequest() | ||
try: | ||
req.ParseFromString(body) | ||
except DecodeError: | ||
return Response( | ||
content="Request body is invalid ExportTraceServiceRequest", | ||
status_code=HTTP_422_UNPROCESSABLE_ENTITY, | ||
) | ||
for resource_spans in req.resource_spans: | ||
for scope_span in resource_spans.scope_spans: | ||
for span in scope_span.spans: | ||
self.queue.put(span) | ||
await asyncio.sleep(0) | ||
return Response() |