micromegas/servers/
firehose_cloudwatch_logs.rs1use super::firehose_common::{firehose_auth_middleware, firehose_response, request_id_from};
16use super::ingestion_limits::apply_ingestion_body_limits;
17use axum::Extension;
18use axum::Router;
19use axum::http::{HeaderMap, StatusCode};
20use axum::middleware;
21use axum::response::Response;
22use axum::routing::post;
23use micromegas_auth::types::AuthProvider;
24use micromegas_ingestion::web_ingestion_service::WebIngestionService;
25use micromegas_otel_ingestion::{Signal, cloudwatch_logs, handler};
26use micromegas_tracing::prelude::*;
27use std::sync::Arc;
28
29async fn cloudwatch_logs_firehose_handler(
30 Extension(service): Extension<Arc<WebIngestionService>>,
31 headers: HeaderMap,
32 body: bytes::Bytes,
33) -> Response {
34 let mut request_id = request_id_from(&headers);
35 let envelope = match handler::decode_firehose_envelope(&body, Signal::Logs) {
36 Ok(e) => e,
37 Err(err) => {
38 error!("cloudwatch logs firehose decode error: {err}");
39 let status = StatusCode::from_u16(err.http_status())
40 .unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
41 return firehose_response(status, &request_id, Some(&err.public_message()));
42 }
43 };
44 if request_id.is_empty() {
45 request_id = envelope.request_id.clone();
46 }
47 match cloudwatch_logs::ingest_cloudwatch_logs_firehose(service, envelope.records).await {
48 Ok(()) => firehose_response(StatusCode::OK, &request_id, None),
49 Err(err) => {
50 error!("cloudwatch logs firehose ingest error: {err}");
51 let status = StatusCode::from_u16(err.http_status())
52 .unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
53 firehose_response(status, &request_id, Some(&err.public_message()))
54 }
55 }
56}
57
58pub fn firehose_router(
67 service: Arc<WebIngestionService>,
68 auth_provider: Option<Arc<dyn AuthProvider>>,
69) -> Router {
70 let mut router = Router::new()
71 .route(
72 "/ingestion/cloudwatch/v1/logs/firehose",
73 post(cloudwatch_logs_firehose_handler),
74 )
75 .layer(Extension(service));
76 if let Some(provider) = auth_provider {
77 router = router.layer(middleware::from_fn(move |req, next| {
78 firehose_auth_middleware(provider.clone(), req, next)
79 }));
80 }
81 apply_ingestion_body_limits(router)
82}