Skip to main content

libdd_telemetry/worker/
http_client.rs

1// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/
2// SPDX-License-Identifier: Apache-2.0
3
4use libdd_common::HttpRequestBuilder;
5
6use crate::config::Config;
7use tracing::{debug, error};
8
9pub mod header {
10    #![allow(clippy::declare_interior_mutable_const)]
11    use http::header::HeaderName;
12    pub const REQUEST_TYPE: HeaderName = HeaderName::from_static("dd-telemetry-request-type");
13    pub const API_VERSION: HeaderName = HeaderName::from_static("dd-telemetry-api-version");
14    pub const LIBRARY_LANGUAGE: HeaderName = HeaderName::from_static("dd-client-library-language");
15    pub const LIBRARY_VERSION: HeaderName = HeaderName::from_static("dd-client-library-version");
16
17    pub const DEBUG_ENABLED: HeaderName = HeaderName::from_static("dd-telemetry-debug-enabled");
18
19    pub const DD_SESSION_ID: HeaderName = HeaderName::from_static("dd-session-id");
20    pub const DD_ROOT_SESSION_ID: HeaderName = HeaderName::from_static("dd-root-session-id");
21    pub const DD_PARENT_SESSION_ID: HeaderName = HeaderName::from_static("dd-parent-session-id");
22}
23
24/// `session_id`, then `parent_session_id`, then `root_session_id` (must match call sites in
25/// `build_request`).
26pub(crate) fn add_instrumentation_session_headers(
27    mut builder: HttpRequestBuilder,
28    session_id: Option<&str>,
29    parent_session_id: Option<&str>,
30    root_session_id: Option<&str>,
31) -> HttpRequestBuilder {
32    let Some(s) = session_id.filter(|id| !id.is_empty()) else {
33        return builder;
34    };
35    builder = builder.header(header::DD_SESSION_ID, s);
36    if let Some(r) = root_session_id
37        .filter(|r| !r.is_empty())
38        .filter(|r| *r != s)
39    {
40        builder = builder.header(header::DD_ROOT_SESSION_ID, r);
41    }
42    if let Some(p) = parent_session_id
43        .filter(|p| !p.is_empty())
44        .filter(|p| *p != s)
45    {
46        builder = builder.header(header::DD_PARENT_SESSION_ID, p);
47    }
48    builder
49}
50
51pub fn request_builder(c: &Config) -> anyhow::Result<HttpRequestBuilder> {
52    match &c.endpoint {
53        Some(e) => {
54            debug!(
55                endpoint.url = %e.url,
56                endpoint.timeout_ms = e.timeout_ms,
57                telemetry.version = env!("CARGO_PKG_VERSION"),
58                "Building telemetry request"
59            );
60            let mut builder =
61                e.to_request_builder(concat!("telemetry/", env!("CARGO_PKG_VERSION")));
62            if c.debug_enabled {
63                debug!(
64                    telemetry.debug_enabled = true,
65                    "Telemetry debug mode enabled"
66                );
67                builder = Ok(builder?.header(header::DEBUG_ENABLED, "true"))
68            }
69            builder
70        }
71        None => {
72            error!("No valid telemetry endpoint found, cannot build request");
73            Err(anyhow::Error::msg(
74                "no valid endpoint found, can't build the request".to_string(),
75            ))
76        }
77    }
78}