libdd_library_config/
tracer_metadata.rs

1// Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/
2// SPDX-License-Identifier: Apache-2.0
3use std::default::Default;
4
5/// This struct MUST be backward compatible.
6#[derive(serde::Serialize, Debug)]
7pub struct TracerMetadata {
8    /// Version of the schema.
9    pub schema_version: u8,
10    /// Runtime UUID.
11    #[serde(skip_serializing_if = "Option::is_none")]
12    pub runtime_id: Option<String>,
13    /// Programming language of the tracer library (e.g., “python”). Refers to telemetry
14    /// for valid values.
15    pub tracer_language: String,
16    /// Version of the tracer (e.g., "1.0.0").
17    pub tracer_version: String,
18    /// Identifier of the machine running the process.
19    pub hostname: String,
20    /// Name of the service being instrumented.
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub service_name: Option<String>,
23    /// Environment of the service being instrumented.
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub service_env: Option<String>,
26    /// Version of the service being instrumented.
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub service_version: Option<String>,
29    /// Process tags of the application being instrumented.
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub process_tags: Option<String>,
32    /// Container id seen by the application.
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub container_id: Option<String>,
35}
36
37impl Default for TracerMetadata {
38    fn default() -> Self {
39        TracerMetadata {
40            schema_version: 2,
41            runtime_id: None,
42            tracer_language: String::new(),
43            tracer_version: String::new(),
44            hostname: String::new(),
45            service_name: None,
46            service_env: None,
47            service_version: None,
48            process_tags: None,
49            container_id: None,
50        }
51    }
52}
53
54pub enum AnonymousFileHandle {
55    #[cfg(target_os = "linux")]
56    Linux(memfd::Memfd),
57    #[cfg(not(target_os = "linux"))]
58    Other(()),
59}
60
61#[cfg(target_os = "linux")]
62mod linux {
63    use anyhow::Context;
64    use rand::distributions::Alphanumeric;
65    use rand::Rng;
66    use std::io::Write;
67
68    /// Create a memfd file storing the tracer metadata.
69    pub fn store_tracer_metadata(
70        data: &super::TracerMetadata,
71    ) -> anyhow::Result<super::AnonymousFileHandle> {
72        let uid: String = rand::thread_rng()
73            .sample_iter(&Alphanumeric)
74            .take(8)
75            .map(char::from)
76            .collect();
77
78        let mfd_name: String = format!("datadog-tracer-info-{uid}");
79
80        let mfd = memfd::MemfdOptions::default()
81            .close_on_exec(true)
82            .allow_sealing(true)
83            .create::<&str>(mfd_name.as_ref())
84            .context("unable to create memfd")?;
85
86        let buf = rmp_serde::to_vec_named(data).context("failed serialization")?;
87        mfd.as_file()
88            .write_all(&buf)
89            .context("unable to write into memfd")?;
90
91        mfd.add_seals(&[
92            memfd::FileSeal::SealShrink,
93            memfd::FileSeal::SealGrow,
94            memfd::FileSeal::SealSeal,
95        ])
96        .context("unable to seal memfd")?;
97
98        Ok(super::AnonymousFileHandle::Linux(mfd))
99    }
100}
101
102#[cfg(not(target_os = "linux"))]
103mod other {
104    pub fn store_tracer_metadata(
105        _data: &super::TracerMetadata,
106    ) -> anyhow::Result<super::AnonymousFileHandle> {
107        Ok(super::AnonymousFileHandle::Other(()))
108    }
109}
110
111#[cfg(target_os = "linux")]
112pub use linux::*;
113#[cfg(not(target_os = "linux"))]
114pub use other::*;