Skip to content
Open
6 changes: 4 additions & 2 deletions libdd-data-pipeline-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ crate-type = ["lib", "staticlib", "cdylib"]
bench = false

[features]
default = ["cbindgen", "catch_panic"]
default = ["cbindgen", "catch_panic", "https", "telemetry"]
catch_panic = []
cbindgen = ["build_common/cbindgen", "libdd-common-ffi/cbindgen"]
https = ["libdd-data-pipeline/https"]
telemetry = ["libdd-data-pipeline/telemetry"]

[build-dependencies]
build_common = { path = "../build-common" }
Expand All @@ -29,8 +31,8 @@ rmp-serde = "1.1.1"
libdd-trace-utils = { path = "../libdd-trace-utils" }

[dependencies]
libdd-data-pipeline = { path = "../libdd-data-pipeline", default-features = false }
libdd-capabilities-impl = { version = "0.1.0", path = "../libdd-capabilities-impl" }
libdd-data-pipeline = { path = "../libdd-data-pipeline" }
libdd-common-ffi = { path = "../libdd-common-ffi", default-features = false }
libdd-tinybytes = { path = "../libdd-tinybytes" }
tracing = { version = "0.1", default-features = false }
2 changes: 1 addition & 1 deletion libdd-data-pipeline-ffi/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

use libdd_data_pipeline::trace_exporter::error::{
use libdd_data_pipeline::trace_exporter::{
AgentErrorKind, BuilderErrorKind, InternalErrorKind, NetworkErrorKind, TraceExporterError,
};
use std::ffi::{c_char, CString};
Expand Down
2 changes: 1 addition & 1 deletion libdd-data-pipeline-ffi/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

//! Define FFI compatible AgentResponse struct

use libdd_data_pipeline::trace_exporter::agent_response::AgentResponse;
use libdd_data_pipeline::trace_exporter::AgentResponse;
use std::ptr::null;

/// Structure containing the agent response to a trace payload
Expand Down
13 changes: 11 additions & 2 deletions libdd-data-pipeline-ffi/src/trace_exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ use libdd_common_ffi::{
{slice::AsBytes, slice::ByteSlice},
};

#[cfg(feature = "telemetry")]
use libdd_data_pipeline::trace_exporter::TelemetryConfig;
use libdd_data_pipeline::trace_exporter::{
TelemetryConfig, TraceExporter as GenericTraceExporter, TraceExporterInputFormat,
TraceExporterOutputFormat,
TraceExporter as GenericTraceExporter, TraceExporterInputFormat, TraceExporterOutputFormat,
};

type TraceExporter = GenericTraceExporter<NativeCapabilities>;

use std::{ptr::NonNull, time::Duration};
#[cfg(feature = "telemetry")]
use tracing::debug;

#[inline]
Expand All @@ -32,6 +34,7 @@ fn sanitize_string(str: CharSlice) -> Result<String, Box<ExporterError>> {
}

/// FFI compatible configuration for the TelemetryClient.
#[cfg(feature = "telemetry")]
#[derive(Debug)]
#[repr(C)]
pub struct TelemetryClientConfig<'a> {
Expand Down Expand Up @@ -68,6 +71,7 @@ pub struct TraceExporterConfig {
output_format: TraceExporterOutputFormat,
compute_stats: bool,
client_computed_stats: bool,
#[cfg(feature = "telemetry")]
telemetry_cfg: Option<TelemetryConfig>,
health_metrics_enabled: bool,
process_tags: Option<String>,
Expand Down Expand Up @@ -291,6 +295,7 @@ pub unsafe extern "C" fn ddog_trace_exporter_config_enable_health_metrics(
}

/// Enables telemetry metrics.
#[cfg(feature = "telemetry")]
#[no_mangle]
pub unsafe extern "C" fn ddog_trace_exporter_config_enable_telemetry(
Comment on lines +298 to 300
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should feature gate it, instead of making it a no-op since it's part of the API

You could imagine that we have a language where we want to build a shared library.
The code in the language would probably look like this

if (!serverless) {
  ddog_trace_exporter_config_enable_telemetry();
}

if we feature gate this, we can't have this switch at rutime and force them to use macros

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was unsure what to do here. In order to maintain ABI compatibility it would be better to write no-op functions but, since most of the data-pipeline crate users are migrating to building their own version from source, I think it'd be cleaner to reduce the API surface as much as possible. At the end of the day they're going to control the features they want to introduce.
Anyway it's an interesting topic to discuss internally because our position is to encourage every consumer to build their own thing but we didn't discuss what to do with the prebuilt binary. I'll bring this up next common standup.

config: Option<&mut TraceExporterConfig>,
Expand Down Expand Up @@ -490,6 +495,7 @@ pub unsafe extern "C" fn ddog_trace_exporter_new(
builder.set_client_computed_stats();
}

#[cfg(feature = "telemetry")]
if let Some(cfg) = &config.telemetry_cfg {
builder.enable_telemetry(cfg.clone());
}
Expand Down Expand Up @@ -596,6 +602,7 @@ mod tests {
assert_eq!(cfg.input_format, TraceExporterInputFormat::V04);
assert_eq!(cfg.output_format, TraceExporterOutputFormat::V04);
assert!(!cfg.compute_stats);
#[cfg(feature = "telemetry")]
assert!(cfg.telemetry_cfg.is_none());
assert!(!cfg.health_metrics_enabled);
assert!(cfg.process_tags.is_none());
Expand Down Expand Up @@ -828,6 +835,7 @@ mod tests {
}

#[test]
#[cfg(feature = "telemetry")]
fn config_telemetry_test() {
unsafe {
let error = ddog_trace_exporter_config_enable_telemetry(
Expand Down Expand Up @@ -1106,6 +1114,7 @@ mod tests {
// Ignore because it seems, at least in the version we're currently using, miri can't emulate
// libc::socket function.
#[cfg_attr(miri, ignore)]
#[cfg(feature = "telemetry")]
fn exporter_send_telemetry_test() {
unsafe {
let server = MockServer::start();
Expand Down
2 changes: 1 addition & 1 deletion libdd-data-pipeline/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ tokio = { version = "1.23", features = [

[features]
default = ["https", "telemetry"]
telemetry = ["libdd-telemetry"]
https = [
"libdd-common/https",
"libdd-telemetry?/https",
"libdd-trace-utils/https",
"libdd-dogstatsd-client/https",
]
telemetry = [ "dep:libdd-telemetry" ]
test-utils = []
6 changes: 3 additions & 3 deletions libdd-data-pipeline/examples/send-traces-with-stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use clap::Parser;
use libdd_capabilities_impl::NativeCapabilities;
use libdd_data_pipeline::trace_exporter::{
TelemetryConfig, TraceExporter, TraceExporterInputFormat, TraceExporterOutputFormat,
TraceExporter, TraceExporterInputFormat, TraceExporterOutputFormat,
};
use libdd_log::logger::{
logger_configure_std, logger_set_log_level, LogEventLevel, StdConfig, StdTarget,
Expand Down Expand Up @@ -55,7 +55,6 @@ fn main() {
logger_set_log_level(LogEventLevel::Debug).expect("Failed to set log level");

let args = Args::parse();
let telemetry_cfg = TelemetryConfig::default();
let mut builder = TraceExporter::<NativeCapabilities>::builder();
builder
.set_url(&args.url)
Expand All @@ -68,8 +67,9 @@ fn main() {
.set_language_version(env!("CARGO_PKG_RUST_VERSION"))
.set_input_format(TraceExporterInputFormat::V04)
.set_output_format(TraceExporterOutputFormat::V04)
.enable_telemetry(telemetry_cfg)
.enable_stats(Duration::from_secs(10));
#[cfg(feature = "telemetry")]
builder.enable_telemetry(libdd_data_pipeline::telemetry::TelemetryConfig::default());
let exporter = builder
.build::<NativeCapabilities>()
.expect("Failed to build TraceExporter");
Expand Down
5 changes: 2 additions & 3 deletions libdd-data-pipeline/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ pub(crate) mod otlp;
#[cfg(not(target_arch = "wasm32"))]
mod pausable_worker;
#[allow(missing_docs)]
pub mod stats_exporter;
#[cfg(feature = "telemetry")]
pub(crate) mod telemetry;
pub(crate) mod stats_exporter;
pub mod telemetry;
#[allow(missing_docs)]
pub mod trace_exporter;
18 changes: 9 additions & 9 deletions libdd-data-pipeline/src/stats_exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ use tokio::select;
use tokio_util::sync::CancellationToken;
use tracing::error;

const STATS_ENDPOINT_PATH: &str = "/v0.6/stats";

/// An exporter that concentrates and sends stats to the agent.
///
/// `H` is the HTTP client implementation, see [`HttpClientTrait`]. Leaf crates
Expand Down Expand Up @@ -193,13 +191,6 @@ fn encode_stats_payload(
}
}

/// Return the stats endpoint url to send stats to the agent at `agent_url`
pub fn stats_url_from_agent_url(agent_url: &str) -> anyhow::Result<http::Uri> {
let mut parts = agent_url.parse::<http::Uri>()?.into_parts();
parts.path_and_query = Some(http::uri::PathAndQuery::from_static(STATS_ENDPOINT_PATH));
Ok(http::Uri::from_parts(parts)?)
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -211,11 +202,20 @@ mod tests {
use time::Duration;
use time::SystemTime;

const STATS_ENDPOINT_PATH: &str = "/v0.6/stats";

fn is_send<T: Send>() {}
fn is_sync<T: Sync>() {}

const BUCKETS_DURATION: Duration = Duration::from_secs(10);

/// Return the stats endpoint url to send stats to the agent at `agent_url`
fn stats_url_from_agent_url(agent_url: &str) -> anyhow::Result<http::Uri> {
let mut parts = agent_url.parse::<http::Uri>()?.into_parts();
parts.path_and_query = Some(http::uri::PathAndQuery::from_static(STATS_ENDPOINT_PATH));
Ok(http::Uri::from_parts(parts)?)
}

/// Fails to compile if stats exporter is not Send and Sync
#[test]
fn test_stats_exporter_sync_send() {
Expand Down
Loading
Loading