-
Notifications
You must be signed in to change notification settings - Fork 21
refactor(libdd-telemetry)!: avoid leaking libdd-common types in the public API #2152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,6 @@ | |
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| use ffi::slice::AsBytes; | ||
| use libdd_common::Endpoint; | ||
| use libdd_common_ffi as ffi; | ||
| use libdd_telemetry::{ | ||
| data, | ||
|
|
@@ -155,14 +154,60 @@ pub unsafe extern "C" fn ddog_telemetry_builder_run_metric_logs( | |
| MaybeError::None | ||
| } | ||
|
|
||
| /// Applies endpoint settings to the builder's telemetry config from primitive | ||
| /// values, so `libdd_common::Endpoint` stays out of this crate's public API. | ||
| /// | ||
| /// `api_key` and `test_token` are treated as unset when empty; a `timeout_ms` of | ||
| /// 0 keeps the existing/default timeout. | ||
| fn set_builder_endpoint( | ||
| telemetry_builder: &mut TelemetryWorkerBuilder, | ||
| url: ffi::CharSlice, | ||
| api_key: ffi::CharSlice, | ||
| timeout_ms: u64, | ||
| test_token: ffi::CharSlice, | ||
| use_system_resolver: bool, | ||
| ) -> ffi::MaybeError { | ||
| let url = try_c!(url.try_to_utf8()); | ||
| let api_key = api_key.to_utf8_lossy(); | ||
| let test_token = test_token.to_utf8_lossy(); | ||
| let config = &mut telemetry_builder.config; | ||
| // Set the api key before the url so the telemetry path is resolved correctly. | ||
| if !api_key.is_empty() { | ||
| try_c!(config.set_endpoint_api_key(Some(api_key.as_ref()))); | ||
| } | ||
| try_c!(config.set_endpoint_url(url)); | ||
| if timeout_ms != 0 { | ||
| config.set_endpoint_timeout_ms(timeout_ms); | ||
| } | ||
| if !test_token.is_empty() { | ||
| config.set_endpoint_test_token(Some(test_token.into_owned())); | ||
| } | ||
| config.set_endpoint_use_system_resolver(use_system_resolver); | ||
| ffi::MaybeError::None | ||
| } | ||
|
|
||
| #[no_mangle] | ||
| #[allow(clippy::missing_safety_doc)] | ||
| /// Sets the telemetry endpoint from its component parts. | ||
| /// | ||
| /// * `api_key` / `test_token`: ignored when empty. | ||
| /// * `timeout_ms`: pass 0 to keep the existing/default timeout. | ||
| pub unsafe extern "C" fn ddog_telemetry_builder_with_endpoint_config_endpoint( | ||
| telemetry_builder: &mut TelemetryWorkerBuilder, | ||
| endpoint: &Endpoint, | ||
| url: ffi::CharSlice, | ||
| api_key: ffi::CharSlice, | ||
| timeout_ms: u64, | ||
| test_token: ffi::CharSlice, | ||
| use_system_resolver: bool, | ||
|
Comment on lines
+197
to
+201
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The endpoint seems to carry quite a bit of different fields, that now have to be set manually one by one and inflate function arguments (there's a risk to forget about one field when setting the endpoint now instead of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about that but I ended up adding more parameters here. However you have a point here, maybe taking the same approach as in TelemetryClientConfig would be better? WDYT? |
||
| ) -> ffi::MaybeError { | ||
| try_c!(telemetry_builder.config.set_endpoint(endpoint.clone())); | ||
| ffi::MaybeError::None | ||
| set_builder_endpoint( | ||
| telemetry_builder, | ||
| url, | ||
| api_key, | ||
| timeout_ms, | ||
| test_token, | ||
| use_system_resolver, | ||
| ) | ||
| } | ||
| #[repr(C)] | ||
| #[allow(dead_code)] | ||
|
|
@@ -172,38 +217,56 @@ pub enum TelemetryWorkerBuilderEndpointProperty { | |
|
|
||
| #[no_mangle] | ||
| #[allow(clippy::missing_safety_doc)] | ||
| /// Sets a property from it's string value. | ||
| /// Sets the endpoint property from its component parts. | ||
| /// | ||
| /// Available properties: | ||
| /// | ||
| /// * config.endpoint | ||
| pub unsafe extern "C" fn ddog_telemetry_builder_with_property_endpoint( | ||
| telemetry_builder: &mut TelemetryWorkerBuilder, | ||
| _property: TelemetryWorkerBuilderEndpointProperty, | ||
| endpoint: &Endpoint, | ||
| url: ffi::CharSlice, | ||
| api_key: ffi::CharSlice, | ||
| timeout_ms: u64, | ||
| test_token: ffi::CharSlice, | ||
| use_system_resolver: bool, | ||
| ) -> ffi::MaybeError { | ||
| try_c!(telemetry_builder.config.set_endpoint(endpoint.clone())); | ||
| ffi::MaybeError::None | ||
| set_builder_endpoint( | ||
| telemetry_builder, | ||
| url, | ||
| api_key, | ||
| timeout_ms, | ||
| test_token, | ||
| use_system_resolver, | ||
| ) | ||
| } | ||
| #[no_mangle] | ||
| #[allow(clippy::missing_safety_doc)] | ||
| /// Sets a property from it's string value. | ||
| /// Sets a named endpoint property from its component parts. | ||
| /// | ||
| /// Available properties: | ||
| /// | ||
| /// * config.endpoint | ||
| pub unsafe extern "C" fn ddog_telemetry_builder_with_endpoint_named_property( | ||
| telemetry_builder: &mut TelemetryWorkerBuilder, | ||
| property: ffi::CharSlice, | ||
| endpoint: &Endpoint, | ||
| url: ffi::CharSlice, | ||
| api_key: ffi::CharSlice, | ||
| timeout_ms: u64, | ||
| test_token: ffi::CharSlice, | ||
| use_system_resolver: bool, | ||
| ) -> ffi::MaybeError { | ||
| let property = try_c!(property.try_to_utf8()); | ||
|
|
||
| match property { | ||
| "config . endpoint" => { | ||
| try_c!(telemetry_builder.config.set_endpoint(endpoint.clone())); | ||
| } | ||
| _ => return ffi::MaybeError::None, | ||
| "config . endpoint" => set_builder_endpoint( | ||
| telemetry_builder, | ||
| url, | ||
| api_key, | ||
| timeout_ms, | ||
| test_token, | ||
| use_system_resolver, | ||
| ), | ||
| _ => ffi::MaybeError::None, | ||
| } | ||
| ffi::MaybeError::None | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,13 +4,11 @@ | |
| // Datadog, Inc. | ||
|
|
||
| use std::{ | ||
| borrow::Cow, | ||
| sync::atomic::{AtomicU64, Ordering}, | ||
| time::SystemTime, | ||
| }; | ||
|
|
||
| use http::{header::CONTENT_TYPE, Uri}; | ||
| use libdd_common::Endpoint; | ||
| use http::header::CONTENT_TYPE; | ||
| use libdd_telemetry::{ | ||
| build_host, | ||
| config::Config, | ||
|
|
@@ -111,12 +109,10 @@ async fn async_main() { | |
| let mut config = Config::from_env(); | ||
| config.direct_submission_enabled = true; | ||
| config.debug_enabled = true; | ||
| let api_key = std::env::var("DD_API_KEY").unwrap(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this existed before this PR, but we should avoid reading env vars in libdatadog. Not sure this one can really be avoided in a cross-platform way though...
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, we shouldn't be changing behaviour in a library based on environment vars, it can cause problems for our consumers. Since the scope for the PR is to solve problems with the releases we can fix the env var issue in a subsequent PR? |
||
| config.set_endpoint_api_key(Some(&api_key)).unwrap(); | ||
| config | ||
| .set_endpoint(Endpoint { | ||
| url: Uri::from_static("https://instrumentation-telemetry-intake.datad0g.com"), | ||
| api_key: Some(Cow::Owned(std::env::var("DD_API_KEY").unwrap())), | ||
| ..Default::default() | ||
| }) | ||
| .set_endpoint_url("https://instrumentation-telemetry-intake.datad0g.com") | ||
| .unwrap(); | ||
| push_telemetry(&config, &req).await.unwrap(); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the builder was instantiated from an environment with
_DD_DIRECT_SUBMISSION_ENABLED=trueandDD_API_KEYset, passing an emptyapi_keyhere no longer clears that key while replacing the endpoint. The previousEndpoint-based setter replaced the whole endpoint, soddog_endpoint_from_url(...)produced an endpoint with no API key; now the old key is preserved andset_endpoint_urlrewrites HTTP URLs to the direct-submission path, causing callers that explicitly configure an agent/file endpoint without a key to send with the stale API key and potentially to/api/v2/apmtelemetryinstead of the agent proxy path.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose the solution is to set to
Noneif the api key is empty, instead of not setting anything?