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

Report profiling data in v2.4 intake format; compress files #53

Merged
merged 10 commits into from
Sep 27, 2022
2 changes: 2 additions & 0 deletions Cargo.lock

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

12 changes: 10 additions & 2 deletions examples/ffi/exporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,16 @@ int main(int argc, char *argv[]) {

ddog_Slice_file files = {.ptr = files_, .len = sizeof files_ / sizeof *files_};

ddog_Request *request = ddog_ProfileExporter_build(exporter, encoded_profile->start,
encoded_profile->end, files, nullptr, 30000);
ddog_Request *request = ddog_ProfileExporter_build(
exporter,
encoded_profile->start,
encoded_profile->end,
files,
nullptr,
30000,
DDOG_CHARSLICE_C("exporter-example"),
DDOG_CHARSLICE_C("1.2.3")
);

ddog_CancellationToken *cancel = ddog_CancellationToken_new();
ddog_CancellationToken *cancel_for_background_thread = ddog_CancellationToken_clone(cancel);
Expand Down
6 changes: 6 additions & 0 deletions profiling-ffi/src/exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ pub unsafe extern "C" fn profile_exporter_build(
files: Slice<File>,
additional_tags: Option<&ddcommon_ffi::Vec<Tag>>,
timeout_ms: u64,
profile_library_name: CharSlice,
profile_library_version: CharSlice,
) -> Option<Box<Request>> {
match exporter {
None => None,
Expand All @@ -174,6 +176,8 @@ pub unsafe extern "C" fn profile_exporter_build(
converted_files.as_slice(),
tags.as_ref(),
timeout,
profile_library_name.to_utf8_lossy().as_ref(),
profile_library_version.to_utf8_lossy().as_ref(),
) {
Ok(request) => Some(Box::new(Request(request))),
Err(_) => None,
Expand Down Expand Up @@ -384,6 +388,8 @@ mod test {
Slice::from(files),
None,
timeout_milliseconds,
CharSlice::from("dd-trace-foo"),
CharSlice::from("1.2.3"),
)
};

Expand Down
2 changes: 2 additions & 0 deletions profiling/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ hyper = {version = "0.14", features = ["client"], default-features = false}
hyper-multipart-rfc7578 = "0.7.0"
indexmap = "1.8"
libc = "0.2"
mime = "0.3.16"
mime_guess = {version = "2.0", default-features = false}
percent-encoding = "2.1"
prost = "0.10"
serde_json = {version = "1.0"}
tokio = {version = "1.8", features = ["rt", "macros"]}
tokio-util = "0.7.1"
2 changes: 1 addition & 1 deletion profiling/src/exporter/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub fn agentless<AsStrRef: AsRef<str>, IntoCow: Into<Cow<'static, str>>>(
site: AsStrRef,
api_key: IntoCow,
) -> anyhow::Result<Endpoint> {
let intake_url: String = format!("https://intake.profile.{}/v1/input", site.as_ref());
let intake_url: String = format!("https://intake.profile.{}/api/v2/profile", site.as_ref());

Ok(Endpoint {
url: Uri::from_str(intake_url.as_str())?,
Expand Down
44 changes: 34 additions & 10 deletions profiling/src/exporter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pub use chrono::{DateTime, Utc};
pub use ddcommon::tag::Tag;
pub use hyper::Uri;
use hyper_multipart_rfc7578::client::multipart;
use mime;
use serde_json::json;
use tokio::runtime::Runtime;
use tokio_util::sync::CancellationToken;

Expand Down Expand Up @@ -120,26 +122,46 @@ impl ProfileExporter {
}

/// Build a Request object representing the profile information provided.
#[allow(clippy::too_many_arguments)]
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO this is fine for now, but we should probably work on breaking this up when we add support for the extra attributes feature.

pub fn build(
&self,
start: DateTime<Utc>,
end: DateTime<Utc>,
files: &[File],
additional_tags: Option<&Vec<Tag>>,
timeout: std::time::Duration,
profile_library_name: &str,
profile_library_version: &str,
) -> anyhow::Result<Request> {
let mut form = multipart::Form::default();

form.add_text("version", "3");
form.add_text("start", start.format("%Y-%m-%dT%H:%M:%S%.9fZ").to_string());
form.add_text("end", end.format("%Y-%m-%dT%H:%M:%S%.9fZ").to_string());
form.add_text("family", self.family.as_ref());

for tags in self.tags.as_ref().iter().chain(additional_tags.iter()) {
for tag in tags.iter() {
form.add_text("tags[]", tag.to_string());
}
// combine tags and additional_tags
let mut tags_profiler = String::new();
let other_tags = additional_tags.into_iter();
for tag in self.tags.iter().chain(other_tags).flatten() {
tags_profiler.push_str(tag.as_ref());
tags_profiler.push(',');
}
tags_profiler.pop(); // clean up the trailing comma

let attachments: Vec<String> = files.iter().map(|file| file.name.to_owned()).collect();

let event = json!({
"attachments": attachments,
"tags_profiler": tags_profiler,
"start": start.format("%Y-%m-%dT%H:%M:%S%.9fZ").to_string(),
"end": end.format("%Y-%m-%dT%H:%M:%S%.9fZ").to_string(),
"family": self.family.as_ref(),
"version":"4",
})
.to_string();

form.add_reader_file_with_mime(
"event",
Cursor::new(event),
"event.json",
mime::APPLICATION_JSON,
);

for file in files {
form.add_reader_file(
Expand All @@ -153,7 +175,9 @@ impl ProfileExporter {
.endpoint
.into_request_builder(concat!("DDProf/", env!("CARGO_PKG_VERSION")))?
.method(http::Method::POST)
.header("Connection", "close");
.header("Connection", "close")
.header("DD-EVP-ORIGIN", profile_library_name)
.header("DD-EVP-ORIGIN-VERSION", profile_library_version);

Ok(
Request::from(form.set_body_convert::<hyper::Body, multipart::Body>(builder)?)
Expand Down
4 changes: 2 additions & 2 deletions profiling/tests/form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn multipart(exporter: &ProfileExporter) -> Request {
let timeout = std::time::Duration::from_secs(10);

let request = exporter
.build(start, end, files, None, timeout)
.build(start, end, files, None, timeout, "dd-trace-foo", "1.2.3")
.expect("request to be built");

let actual_timeout = request.timeout().expect("timeout to exist");
Expand Down Expand Up @@ -82,7 +82,7 @@ mod tests {

assert_eq!(
request.uri().to_string(),
"https://intake.profile.datadoghq.com/v1/input"
"https://intake.profile.datadoghq.com/api/v2/profile"
);

let actual_headers = request.headers();
Expand Down