Skip to content
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

Convert local root span id to u64, fix clippy lints #80

Merged
merged 10 commits into from
Jan 11, 2023
12 changes: 6 additions & 6 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion ddcommon-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

[package]
name = "ddcommon-ffi"
version = "1.0.1"
version = "2.0.0"
edition = "2021"
license = "Apache-2.0"

Expand Down
2 changes: 1 addition & 1 deletion ddcommon-ffi/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl<T> From<alloc::vec::Vec<T>> for Vec<T> {
impl From<anyhow::Error> for Vec<u8> {
fn from(err: anyhow::Error) -> Self {
let mut vec = vec![];
write!(vec, "{}", err).expect("write to vec to always succeed");
write!(vec, "{err}").expect("write to vec to always succeed");
Self::from(vec)
}
}
Expand Down
2 changes: 1 addition & 1 deletion ddcommon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
edition = "2021"
license = "Apache-2.0"
name = "ddcommon"
version = "1.0.1"
version = "2.0.0"

[lib]
crate-type = ["lib"]
Expand Down
6 changes: 3 additions & 3 deletions ddcommon/src/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ impl Tag {

let mut chars = chunk.chars();
if chars.next() == Some(':') {
return Err(format!("tag '{}' begins with a colon", chunk).into());
return Err(format!("tag '{chunk}' begins with a colon").into());
}
if chars.last() == Some(':') {
return Err(format!("tag '{}' ends with a colon", chunk).into());
return Err(format!("tag '{chunk}' ends with a colon").into());
}

Ok(Tag {
Expand All @@ -74,7 +74,7 @@ impl Tag {
let key = key.as_ref();
let value = value.as_ref();

Tag::from_value(format!("{}:{}", key, value))
Tag::from_value(format!("{key}:{value}"))
}
}

Expand Down
6 changes: 3 additions & 3 deletions ddtelemetry-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

[package]
name = "ddtelemetry-ffi"
version = "1.0.1"
version = "2.0.0"
edition = "2021"

[lib]
crate-type = ["lib", "staticlib", "cdylib"]

[dependencies]
ddtelemetry = { path = "../ddtelemetry", version = "1.0.1" }
ddcommon-ffi = { path = "../ddcommon-ffi", version = "1.0.1" }
ddtelemetry = { path = "../ddtelemetry" }
ddcommon-ffi = { path = "../ddcommon-ffi" }
paste = "1"
libc = "0.2"
2 changes: 1 addition & 1 deletion ddtelemetry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
edition = "2021"
license = "Apache 2.0"
name = "ddtelemetry"
version = "1.0.1"
version = "2.0.0"

[dependencies]
anyhow = {version = "1.0"}
Expand Down
2 changes: 1 addition & 1 deletion ddtelemetry/benches/ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn criterion_benchmark(c: &mut Criterion) {
_ => panic!("shouldn't happen"),
};

println!("Total requests handled: {}", requests_received);
println!("Total requests handled: {requests_received}");

drop(transport);
worker.join().unwrap();
Expand Down
10 changes: 5 additions & 5 deletions ddtelemetry/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl FromEnv {
let agent_host =
env::var(DD_AGENT_HOST).unwrap_or_else(|_| String::from(DEFAULT_AGENT_HOST));

format!("http://{}:{}", agent_host, agent_port)
format!("http://{agent_host}:{agent_port}")
}

fn get_intake_base_url() -> String {
Expand All @@ -63,9 +63,9 @@ impl FromEnv {

if let Ok(dd_site) = env::var(DD_SITE) {
if dd_site.is_empty() {
format!("{}.{}", PROD_INTAKE_FORMAT_PREFIX, DEFAULT_DD_SITE)
format!("{PROD_INTAKE_FORMAT_PREFIX}.{DEFAULT_DD_SITE}")
} else {
format!("{}.{}", PROD_INTAKE_FORMAT_PREFIX, dd_site)
format!("{PROD_INTAKE_FORMAT_PREFIX}.{dd_site}")
}
} else {
String::from(STAGING_INTAKE)
Expand All @@ -77,9 +77,9 @@ impl FromEnv {

let telemetry_url = if api_key.is_some() {
let telemetry_intake_base_url = Self::get_intake_base_url();
format!("{}{}", telemetry_intake_base_url, DIRECT_TELEMETRY_URL_PATH)
format!("{telemetry_intake_base_url}{DIRECT_TELEMETRY_URL_PATH}")
} else {
format!("{}{}", &agent_url, AGENT_TELEMETRY_URL_PATH)
format!("{}{AGENT_TELEMETRY_URL_PATH}", &agent_url)
Copy link
Member

Choose a reason for hiding this comment

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

Interesting -- is there no extended way for format! that can embed &agent_url directly?

Copy link
Contributor

Choose a reason for hiding this comment

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

No, the inline format values can only contain simple identifiers https://rust-lang.github.io/rfcs/2795-format-args-implicit-identifiers.html

For the sake of uniformity, maybe named arguments would be better

Suggested change
format!("{}{AGENT_TELEMETRY_URL_PATH}", &agent_url)
format!("{agent_url}{AGENT_TELEMETRY_URL_PATH}", agent_url=&agent_url)

};

let telemetry_uri = Uri::from_str(&telemetry_url).ok()?;
Expand Down
2 changes: 1 addition & 1 deletion ddtelemetry/src/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ pub mod tests {
sock_a.read_to_string(&mut out).unwrap();

assert_child_exit!(pid);
assert_eq!(format!("child-{}", pid), out);
assert_eq!(format!("child-{pid}"), out);
}

#[test]
Expand Down
3 changes: 1 addition & 2 deletions ddtelemetry/src/ipc/platform/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ mod tests {
fs::File,
io::{self, Read, Seek, Write},
os::unix::prelude::{AsRawFd, RawFd},
path::Path,
};

use crate::ipc::platform::{metadata::ChannelMetadata, unix::message::MAX_FDS};
Expand Down Expand Up @@ -53,7 +52,7 @@ mod tests {
.map(|p| format!("{}", p))
.unwrap_or_else(|| "self".into());

let fds_path = Path::new("/proc").join(proc).join("fd");
let fds_path = std::path::Path::new("/proc").join(proc).join("fd");
let fds = std::fs::read_dir(fds_path)?
.filter_map(|r| r.ok())
.filter_map(|r| {
Expand Down
4 changes: 2 additions & 2 deletions ddtelemetry/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,14 @@ mod test {
for (i, &a) in assertions.iter().enumerate() {
if a(e) {
if used[i] {
panic!("Assertion {} has been used multiple times", i);
panic!("Assertion {i} has been used multiple times");
}
found = true;
break;
}
}
if !found {
panic!("No assertion found for elem {:?}", e)
panic!("No assertion found for elem {e:?}")
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion profiling-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

[package]
name = "datadog-profiling-ffi"
version = "1.0.1"
version = "2.0.0"
edition = "2021"
license = "Apache-2.0"

Expand Down
10 changes: 4 additions & 6 deletions profiling-ffi/src/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,22 +353,20 @@ pub extern "C" fn ddog_prof_Profile_add(
///
/// # Arguments
/// * `profile` - a reference to the profile that will contain the samples.
/// * `local_root_span_id` - the value of the local root span id label to look for.
/// * `local_root_span_id`
Copy link
Member

Choose a reason for hiding this comment

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

Minor: This is a weird change -- was it intentional?

/// * `endpoint` - the value of the endpoint label to add for matching samples.
///
/// # Safety
/// The `profile` ptr must point to a valid Profile object created by this
/// module.
/// This call is _NOT_ thread-safe.
#[no_mangle]
pub unsafe extern "C" fn ddog_prof_Profile_set_endpoint<'a>(
pub unsafe extern "C" fn ddog_prof_Profile_set_endpoint(
profile: &mut datadog_profiling::profile::Profile,
local_root_span_id: CharSlice<'a>,
endpoint: CharSlice<'a>,
local_root_span_id: u64,
endpoint: CharSlice,
) {
let local_root_span_id = local_root_span_id.to_utf8_lossy();
let endpoint = endpoint.to_utf8_lossy();

profile.add_endpoint(local_root_span_id, endpoint);
}

Expand Down
2 changes: 1 addition & 1 deletion profiling/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

[package]
name = "datadog-profiling"
version = "1.0.1"
version = "2.0.0"
edition = "2021"
license = "Apache-2.0"

Expand Down
2 changes: 1 addition & 1 deletion profiling/src/exporter/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn agent(base_url: Uri) -> anyhow::Result<Endpoint> {
Some(pq) => {
let path = pq.path();
let path = path.strip_suffix('/').unwrap_or(path);
Some(format!("{}/profiling/v1/input", path).parse()?)
Some(format!("{path}/profiling/v1/input").parse()?)
}
};
parts.path_and_query = p_q;
Expand Down
52 changes: 41 additions & 11 deletions profiling/src/profile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub struct Profile {
}

pub struct Endpoints {
mappings: FxIndexMap<i64, i64>,
mappings: FxIndexMap<u64, i64>,
local_root_span_id_label: i64,
endpoint_label: i64,
stats: ProfiledEndpointsStats,
Expand Down Expand Up @@ -426,18 +426,19 @@ impl Profile {
Some(profile)
}

pub fn add_endpoint(&mut self, local_root_span_id: Cow<str>, endpoint: Cow<str>) {
/// Add the endpoint data to the endpoint mappings. The `endpoint` will be
/// interned, as will the strings "local root span id" and "trace endpoint".
pub fn add_endpoint(&mut self, local_root_span_id: u64, endpoint: Cow<str>) {
if self.endpoints.mappings.is_empty() {
self.endpoints.local_root_span_id_label = self.intern("local root span id");
self.endpoints.endpoint_label = self.intern("trace endpoint");
}

let interned_span_id = self.intern(local_root_span_id.as_ref());
let interned_endpoint = self.intern(endpoint.as_ref());

self.endpoints
.mappings
.insert(interned_span_id, interned_endpoint);
.insert(local_root_span_id, interned_endpoint);
}

pub fn add_endpoint_count(&mut self, endpoint: Cow<str>, value: i64) {
Expand Down Expand Up @@ -488,6 +489,35 @@ impl Profile {
pub fn get_string(&self, id: i64) -> Option<&String> {
self.strings.get_index(id as usize)
}

fn get_endpoint_for_label(&self, label: &Label) -> anyhow::Result<&i64> {
let local_root_span_id: u64 = if label.str == 0 {
/* Safety: the value is a u64, but pprof only has signed values,
* so we transmute it; the backend does the same.
*/
unsafe { std::intrinsics::transmute(label.num) }
} else {
/* Sad path: have to fetch the string from the table and convert
* it back into a u64. Clients should change to use numbers!
*/
let string = match self.strings.get_index(label.str as usize) {
None => anyhow::bail!(
"failed to retrieve index {} from the string table when looking for endpoint data",
label.str
),
Some(string) => string,
};
string.as_str().parse()?
};
Copy link
Member

Choose a reason for hiding this comment

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

As this PR changes add_endpoint to take a u64 and not a String, I'm not quite sure we need this.

E.g., what clients would use the new numberic add_endpoint but still send the labels as strings elsewhere?

Copy link
Contributor Author

@morrisonlevi morrisonlevi Dec 16, 2022

Choose a reason for hiding this comment

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

This is coming from a label, and there's nothing that stops a client from attaching the label value as a string instead of a number. So it seems prudent to have the path, although it shouldn't be used.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm... I think having the fallback path is a sharper edge, as it makes things work even when they're not set up the way they should.

E.g., if someone does it wrong, they will still get the right output, which is dangerous...

One suggestion is to consider failing serialization and complaining that this label should not be a string. The serialize operation already returns a Result<EncodedProfile, EncodeError> so clients already need to handle errors, and perhaps modifying from to potentially return an error would allow us to report back what's wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, I've started working on fixing this. There will be two changes:

  1. At serialization time, verify that any local root span id labels use .num.
  2. When the sample is added, verify that any local root span id labels use .num.


match self.endpoints.mappings.get(&local_root_span_id) {
None => Err(anyhow::anyhow!(
"failed to retrieve endpoint information for local root span id {}",
local_root_span_id
)),
Some(endpoint_string_id) => Ok(endpoint_string_id),
}
}
}

impl From<&Profile> for pprof::Profile {
Expand All @@ -509,14 +539,14 @@ impl From<&Profile> for pprof::Profile {

if !profile.endpoints.mappings.is_empty() {
for sample in samples.iter_mut() {
let mut endpoint: Option<&i64> = None;

for label in &sample.labels {
let endpoint = sample.labels.iter().find_map(|label| {
// todo: log errors in get_endpoint_for_label (should not happen)
if label.key == profile.endpoints.local_root_span_id_label {
endpoint = profile.endpoints.mappings.get(&label.str);
break;
profile.get_endpoint_for_label(label).ok()
} else {
None
}
}
});

if let Some(endpoint_value) = endpoint {
sample.labels.push(pprof::Label {
Expand Down Expand Up @@ -907,7 +937,7 @@ mod api_test {

profile.add(sample2).expect("add to success");

profile.add_endpoint(Cow::from("10"), Cow::from("my endpoint"));
profile.add_endpoint(10, Cow::from("my endpoint"));

let serialized_profile: pprof::Profile = (&profile).into();

Expand Down