Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 61 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/capabilities/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ bytes = "1.4"
futures-core = "0.3"
anyhow = "1"
# TODO: Replace this temporary libdatadog PR rev with the official release/tag
# that contains DataDog/libdatadog#2235, then regenerate Cargo.lock.
libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "8cd68ab922fb7aade0f089ccfc91291d874673af" }
# that contains DataDog/libdatadog#2172, then regenerate Cargo.lock.
libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "73f23a2c03be39971c966e444785d63b6fd52e81" }

[dev-dependencies]
wasm-bindgen-test = "0.3"
17 changes: 9 additions & 8 deletions crates/pipeline/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
libdatadog-nodejs-capabilities = { path = "../capabilities" }
# TODO: Replace these temporary libdatadog PR revs with the official release/tag
# that contains DataDog/libdatadog#2235, then regenerate Cargo.lock.
libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "8cd68ab922fb7aade0f089ccfc91291d874673af" }
libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "8cd68ab922fb7aade0f089ccfc91291d874673af", default-features = false }
libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "8cd68ab922fb7aade0f089ccfc91291d874673af", default-features = false }
libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog.git", rev = "8cd68ab922fb7aade0f089ccfc91291d874673af", default-features = false, features = ["change-buffer"] }
libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog.git", rev = "8cd68ab922fb7aade0f089ccfc91291d874673af", default-features = false }
libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "8cd68ab922fb7aade0f089ccfc91291d874673af", default-features = false }
libdd-shared-runtime = { git = "https://github.com/DataDog/libdatadog.git", rev = "8cd68ab922fb7aade0f089ccfc91291d874673af", default-features = false }
# that contains DataDog/libdatadog#2172, then regenerate Cargo.lock.
libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "73f23a2c03be39971c966e444785d63b6fd52e81" }
libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "73f23a2c03be39971c966e444785d63b6fd52e81", default-features = false }
libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "73f23a2c03be39971c966e444785d63b6fd52e81", default-features = false, features = ["telemetry"] }
libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog.git", rev = "73f23a2c03be39971c966e444785d63b6fd52e81", default-features = false, features = ["change-buffer"] }
libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog.git", rev = "73f23a2c03be39971c966e444785d63b6fd52e81", default-features = false }
libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "73f23a2c03be39971c966e444785d63b6fd52e81", default-features = false }
libdd-shared-runtime = { git = "https://github.com/DataDog/libdatadog.git", rev = "73f23a2c03be39971c966e444785d63b6fd52e81", default-features = false }
rmp-serde = "1"
bytes = "1"
http = "1"
web-time = "1"
console_error_panic_hook = "0.1"

[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand Down
34 changes: 33 additions & 1 deletion crates/pipeline/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use libdatadog_nodejs_capabilities::WasmCapabilities;
use libdd_data_pipeline::trace_exporter::agent_response::AgentResponse;
use libdd_data_pipeline::trace_exporter::{
TraceExporter, TraceExporterBuilder, TraceExporterOutputFormat,
TelemetryConfig, TraceExporter, TraceExporterBuilder, TraceExporterOutputFormat,
};
use libdd_data_pipeline::OtlpProtocol;
use libdd_shared_runtime::LocalRuntime;
Expand Down Expand Up @@ -204,6 +204,11 @@ pub struct WasmSpanState {
/// Extra HTTP headers for OTLP export (e.g. collector auth), as key/value
/// pairs. Only applied when `otlp_endpoint` is set.
otlp_headers: RefCell<Vec<(String, String)>>,
/// When set, the lazily-built exporter has telemetry enabled with this
/// config (`heartbeat`/`runtime_id`/`debug_enabled` — see libdatadog's
/// `TelemetryConfig`). Only takes effect if set before the first send
/// (when the exporter is built).
telemetry_config: RefCell<Option<TelemetryConfig>>,
/// Latched message from a failed lazy `build_async`. Building is one-shot and
/// a failure is fatal (bad config), so once set every send returns it (as a
/// distinguishable error) instead of a misleading "builder already consumed",
Expand Down Expand Up @@ -338,6 +343,7 @@ impl WasmSpanState {
otlp_endpoint: RefCell::new(None),
otlp_protocol: Cell::new(None),
otlp_headers: RefCell::new(Vec::new()),
telemetry_config: RefCell::new(None),
build_error: RefCell::new(None),
})
}
Expand Down Expand Up @@ -374,6 +380,29 @@ impl WasmSpanState {
Ok(())
}

/// Enable telemetry on the lazily-built trace exporter. Off by default —
/// dd-trace-js opts in from JS. `heartbeat_ms`sets the metric-flush cadence
/// (0 defers to libdatadog's default interval), `runtime_id` tags telemetry
/// payloads with the tracer's runtime id when provided, and `debug_enabled`
/// toggles libdd-telemetry's verbose logging.
///
/// Must be called before the first `sendPreparedChunk` — the exporter is
/// built lazily on first send and telemetry config is fixed at build time,
/// so later calls have no effect.
#[wasm_bindgen(js_name = "enableTelemetry")]
pub fn enable_telemetry(
&self,
heartbeat_ms: u32,
runtime_id: Option<String>,
debug_enabled: bool,
) {
*self.telemetry_config.borrow_mut() = Some(TelemetryConfig {
heartbeat: heartbeat_ms as u64,
runtime_id,
debug_enabled,
});
}

/// Set extra HTTP headers for OTLP export as a flat `[key, value, ...]`
/// array (the host flattens its key/value map). Only takes effect with an
/// OTLP endpoint set, before the first send. A trailing unpaired element on
Expand Down Expand Up @@ -530,6 +559,9 @@ impl WasmSpanState {
builder.set_otlp_headers(headers.clone());
}
}
if let Some(cfg) = self.telemetry_config.borrow().clone() {
builder.enable_telemetry(cfg);
}
match builder.build_async::<WasmCapabilities>().await {
Ok(built) => *exporter_slot = Some(built),
Err(e) => {
Expand Down
11 changes: 6 additions & 5 deletions crates/pipeline/src/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
//! HTTP transport for flushing stats to the Datadog agent's `/v0.6/stats`
//! endpoint.

use std::time::{Duration, SystemTime};
use std::time::Duration;
use web_time::SystemTime;

/// Wall-clock now() for wasm. `std::time::SystemTime::now()` is unimplemented on
/// `wasm32-unknown-unknown` (it panics/traps), so derive the time from JS
/// `Date.now()` (milliseconds since the Unix epoch).
/// Wall-clock now() for wasm. Delegates to `web_time::SystemTime::now()`,
/// which routes to JS `Date.now()` on `wasm32-unknown-unknown` (native
/// `std::time::SystemTime::now()` is unimplemented on that target and traps).
fn now() -> SystemTime {
SystemTime::UNIX_EPOCH + Duration::from_millis(js_sys::Date::now() as u64)
SystemTime::now()
}

use bytes::Bytes;
Expand Down
Loading