relay_server/endpoints/
traces.rs

1use axum::RequestExt;
2use axum::extract::{DefaultBodyLimit, Request};
3use axum::http::StatusCode;
4use axum::response::IntoResponse;
5use axum::routing::{MethodRouter, post};
6use bytes::Bytes;
7use relay_config::Config;
8use relay_dynamic_config::Feature;
9
10use crate::endpoints::common;
11use crate::envelope::{ContentType, Envelope, Item, ItemType};
12use crate::extractors::{RawContentType, RequestMeta};
13use crate::service::ServiceState;
14
15async fn handle(
16    state: ServiceState,
17    content_type: RawContentType,
18    meta: RequestMeta,
19    request: Request,
20) -> axum::response::Result<impl IntoResponse> {
21    let content_type @ (ContentType::Json | ContentType::Protobuf) =
22        ContentType::from(content_type.as_ref())
23    else {
24        return Ok(StatusCode::UNSUPPORTED_MEDIA_TYPE);
25    };
26    let payload: Bytes = request.extract().await?;
27    let mut envelope = Envelope::from_request(None, meta);
28    envelope.require_feature(Feature::OtelEndpoint);
29
30    envelope.add_item({
31        let mut item = Item::new(ItemType::OtelTracesData);
32        item.set_payload(content_type, payload);
33        item
34    });
35
36    common::handle_envelope(&state, envelope).await?;
37
38    Ok(StatusCode::ACCEPTED)
39}
40
41pub fn route(config: &Config) -> MethodRouter<ServiceState> {
42    post(handle).route_layer(DefaultBodyLimit::max(config.max_envelope_size()))
43}