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

Publish relevant crate names #5

Draft
wants to merge 45 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4af6146
Deliver libddprof_ffi as a shared library (#22)
nsavoire Feb 15, 2022
8e2246e
Bump version to 0.4.0-rc.1 (#25)
r1viollet Feb 21, 2022
16b5a77
Add support for packaging shared library for Ruby on x86-64 Linux and…
ivoanjo Feb 22, 2022
2f588cf
Fix `ffi-build.sh: line 78: fix_macos_rpath: unbound variable` issue …
ivoanjo Feb 22, 2022
eaf1e5f
Ship debug information in a separate file from the shared library (#29)
ivoanjo Feb 23, 2022
c7d3570
RFC: Introduce `ddprof_ffi_Buffer_from_byte_slice` function to enable…
ivoanjo Feb 24, 2022
52322bb
Increase reported profile timestamp precision (#31)
ivoanjo Mar 9, 2022
06e9611
[PROF-4780] Breaking change: Change FFI File struct to contain a Buff…
ivoanjo Mar 11, 2022
63bef61
Switch ddprof http client (#32)
paullegranddc Mar 15, 2022
89f8ef8
Fix clippy lints,expose dependencies of API, remove unused Exporter A…
morrisonlevi Mar 18, 2022
a4de688
Add helper for creating CharSlice from a string literal (#36)
ivoanjo Mar 21, 2022
e2bf03e
Fix tests (#37)
morrisonlevi Mar 21, 2022
6454bce
Note the upgrade to Rust 1.56
morrisonlevi Mar 22, 2022
8c87c09
Bump version to v0.5.0-rc.1 (#38)
morrisonlevi Mar 24, 2022
2bbd55c
Ruby updates: 0.5.0 packaging + package arm64 + change fallback packa…
ivoanjo Mar 29, 2022
88277c1
Allow sending tags when building the HTTP request (#40)
morrisonlevi Mar 31, 2022
e6d6574
Add Vec type, remove Buffer, add SendResult_drop (#41)
morrisonlevi Mar 31, 2022
a311381
Return SerializeResult for serializing a profile (#42)
morrisonlevi Mar 31, 2022
da6864e
Github CI lint and and tests (#46)
pawelchcki Apr 12, 2022
079d96a
Cleanup slices, strings, tags, and vecs (#44)
morrisonlevi Apr 12, 2022
19b92af
Refactoring of https connector to make root certificates optional (#47)
pawelchcki Apr 13, 2022
baea3a4
Add missing copyright headers (#51)
pawelchcki Apr 13, 2022
c84b2ec
Enhance Tags API (#49)
morrisonlevi Apr 13, 2022
c64a3e3
Bump version to 0.6.0-rc.1 (#53)
r1viollet Apr 14, 2022
c5dcf33
Asynchronous cancellation for ddprof_ffi_ProfileExporterV3_send (#45)
ivoanjo Apr 14, 2022
bb2f6e4
Fix license check
r1viollet Apr 14, 2022
bfc2654
Import simple telemetry implementation without native_deps and langua…
pawelchcki Apr 15, 2022
7cb9f7e
Fix failing gitlab CI lints (#57)
paullegranddc Apr 21, 2022
eb5b0e8
Add more lints to correspond with existing build system (#58)
pawelchcki Apr 21, 2022
85be26e
Test rust 1.56.1 compatibility (#54)
pawelchcki Apr 21, 2022
6dbf2eb
Initial version of CODEOWNERS (#52)
pawelchcki Apr 21, 2022
be43188
Fix license paths
morrisonlevi Apr 21, 2022
a82bd9c
Release v0.6.0
morrisonlevi Apr 21, 2022
0711e0d
Fix inconsistency between `SendResult` and other results (#60)
ivoanjo Apr 26, 2022
4b305cd
Package 0.6.0 release for Ruby (#59)
ivoanjo May 3, 2022
0ebe874
Grab the datadog-profiler crate
r1viollet May 6, 2022
2d5ceb9
Define license to prevent upload error
r1viollet May 6, 2022
a71832a
Create an empty datadog telemetry crate
r1viollet May 6, 2022
6fc2342
Adding placeholder crates for Datadog
r1viollet May 6, 2022
e4eab02
Fix duplicated description in crate
r1viollet May 6, 2022
ca7d337
Remove existing apm crate
r1viollet May 6, 2022
5ed73fd
Fix missing license
r1viollet May 6, 2022
13022e3
Merge remote-tracking branch 'libdd/main' into m
pawelchcki May 10, 2022
7dbf423
Merge branch 'm' into r1viollet/publish_crates
pawelchcki May 10, 2022
8ba99f7
Create placeholder for `datadog-profiling` crate
ivoanjo Aug 9, 2022
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
Prev Previous commit
Next Next commit
Return SerializeResult for serializing a profile (#42)
* Return SerializeResult for serializing a profile

This removes the direct `eprintln` usage and allows the caller to
choose what to do with it instead.

Adds these FFI functions:

- `ddprof_ffi_SerializeResult_drop`
- `ddprof_ffi_Vec_u8_as_slice`. The EncodedProfile has a Vec<u8> but
  the struct ddprof_ffi_File requires a Slice<u8>.

And removes `ddprof_ffi_EncodedProfile_delete`.

* Clean up exporter

* Add #[must use] to ddprof_ffi_Vec_u8_as_slice
  • Loading branch information
morrisonlevi authored and r1viollet committed May 5, 2022
commit a311381fc6a07864a8e2e36583387bf2e884513e
4 changes: 2 additions & 2 deletions ddprof-ffi/src/exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ pub enum NewProfileExporterV3Result {
Err(crate::Vec<u8>),
}

#[export_name = "ddprof_ffi_NewProfileExporterV3Result_dtor"]
pub unsafe extern "C" fn new_profile_exporter_v3_result_dtor(result: NewProfileExporterV3Result) {
#[export_name = "ddprof_ffi_NewProfileExporterV3Result_drop"]
pub unsafe extern "C" fn new_profile_exporter_v3_result_drop(result: NewProfileExporterV3Result) {
match result {
NewProfileExporterV3Result::Ok(ptr) => {
let exporter = Box::from_raw(ptr);
Expand Down
46 changes: 23 additions & 23 deletions ddprof-ffi/src/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use crate::{CharSlice, Slice, Timespec};
use ddprof_profiles as profiles;
use std::convert::{TryFrom, TryInto};
use std::error::Error;
use std::str::Utf8Error;

#[repr(C)]
Expand Down Expand Up @@ -330,7 +331,7 @@ pub struct EncodedProfile {
}

impl TryFrom<ddprof_profiles::EncodedProfile> for EncodedProfile {
type Error = Box<dyn std::error::Error>;
type Error = Box<dyn Error>;

fn try_from(value: ddprof_profiles::EncodedProfile) -> Result<Self, Self::Error> {
let start = value.start.try_into()?;
Expand All @@ -340,37 +341,36 @@ impl TryFrom<ddprof_profiles::EncodedProfile> for EncodedProfile {
}
}

/// Destroys the `encoded_profile`
/// # Safety
/// Only safe on profiles created by `ddprof_ffi_Profile_serialize`.
#[no_mangle]
pub unsafe extern "C" fn ddprof_ffi_EncodedProfile_delete(
encoded_profile: Option<Box<EncodedProfile>>,
) {
std::mem::drop(encoded_profile)
#[repr(C)]
pub enum SerializeResult {
Ok(EncodedProfile),
Err(crate::Vec<u8>),
}

/// Serialize the aggregated profile. Be sure to check the return value and if
/// it's non-null then call `ddprof_ffi_EncodedProfile_delete` on it once
/// done with it.
/// result to free it.
/// Serialize the aggregated profile. Don't forget to clean up the result by
/// calling ddprof_ffi_SerializeResult_drop.
#[no_mangle]
#[must_use]
pub extern "C" fn ddprof_ffi_Profile_serialize(
profile: &ddprof_profiles::Profile,
) -> Option<Box<EncodedProfile>> {
match profile.serialize() {
Ok(encoded_profile) => {
let ffi = encoded_profile.try_into().ok()?;
Some(Box::new(ffi))
}
Err(e) => {
eprintln!("Failed to serialize profiles: {}", e);
None
}
) -> SerializeResult {
match || -> Result<EncodedProfile, Box<dyn Error>> { profile.serialize()?.try_into() }() {
Ok(ok) => SerializeResult::Ok(ok),
Err(err) => SerializeResult::Err(err.into()),
}
}

#[no_mangle]
pub unsafe extern "C" fn ddprof_ffi_SerializeResult_drop(result: SerializeResult) {
std::mem::drop(result)
}

#[must_use]
#[no_mangle]
pub unsafe extern "C" fn ddprof_ffi_Vec_u8_as_slice(vec: &crate::Vec<u8>) -> Slice<u8> {
vec.as_slice()
}

/// Resets all data in `profile` except the sample types and period. Returns
/// true if it successfully reset the profile and false otherwise. The profile
/// remains valid if false is returned.
Expand Down
62 changes: 29 additions & 33 deletions examples/ffi/exporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ extern "C" {
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>

static ddprof_ffi_Slice_c_char to_slice_c_char(const char *s) {
return (ddprof_ffi_Slice_c_char){.ptr = s, .len = strlen(s)};
Expand All @@ -14,25 +15,6 @@ struct Deleter {
void operator()(ddprof_ffi_Profile *object) {
ddprof_ffi_Profile_free(object);
}
void operator()(ddprof_ffi_ProfileExporterV3 *object) {
ddprof_ffi_ProfileExporterV3_delete(object);
}
void operator()(ddprof_ffi_EncodedProfile *object) {
ddprof_ffi_EncodedProfile_delete(object);
}
};

template <typename T> class Holder {
public:
explicit Holder(T *object) : _object(object) {}
~Holder() { Deleter{}(_object); }
Holder(const Holder &) = delete;
Holder &operator=(const Holder &) = delete;

operator T *() { return _object; }
T *operator->() { return _object; }

T *_object;
};

template <typename T> void print_error(const char *s, const T &err) {
Expand All @@ -53,18 +35,21 @@ int main(int argc, char *argv[]) {
const auto service = argv[1];

const ddprof_ffi_ValueType wall_time = {
.type_ = to_slice_c_char("wall-time"),
.unit = to_slice_c_char("nanoseconds"),
.type_ = DDPROF_FFI_CHARSLICE_C("wall-time"),
.unit = DDPROF_FFI_CHARSLICE_C("nanoseconds"),
};

const ddprof_ffi_Slice_value_type sample_types = {&wall_time, 1};
const ddprof_ffi_Period period = {wall_time, 60};
Holder<ddprof_ffi_Profile> profile{
std::unique_ptr<ddprof_ffi_Profile, Deleter> profile{
ddprof_ffi_Profile_new(sample_types, &period)};

ddprof_ffi_Line root_line = {
.function = {.name = to_slice_c_char("{main}"),
.filename = to_slice_c_char("/srv/example/index.php")},
.function =
{
.name = DDPROF_FFI_CHARSLICE_C("{main}"),
.filename = DDPROF_FFI_CHARSLICE_C("/srv/example/index.php"),
},
.line = 0,
};

Expand All @@ -76,18 +61,24 @@ int main(int argc, char *argv[]) {

int64_t value = 10;
const ddprof_ffi_Label label = {
.key = to_slice_c_char("language"),
.str = to_slice_c_char("php"),
.key = DDPROF_FFI_CHARSLICE_C("language"),
.str = DDPROF_FFI_CHARSLICE_C("php"),
};
ddprof_ffi_Sample sample = {
.locations = {&root_location, 1},
.values = {&value, 1},
.labels = {&label, 1},
};
ddprof_ffi_Profile_add(profile, sample);
ddprof_ffi_Profile_add(profile.get(), sample);

ddprof_ffi_SerializeResult serialize_result =
ddprof_ffi_Profile_serialize(profile.get());
if (serialize_result.tag == DDPROF_FFI_SERIALIZE_RESULT_ERR) {
print_error("Failed to serialize profile: ", serialize_result.err);
return 1;
}

Holder<ddprof_ffi_EncodedProfile> encoded_profile{
ddprof_ffi_Profile_serialize(profile)};
ddprof_ffi_EncodedProfile *encoded_profile = &serialize_result.ok;

ddprof_ffi_EndpointV3 endpoint = ddprof_ffi_EndpointV3_agentless(
DDPROF_FFI_CHARSLICE_C("datad0g.com"), to_slice_c_char(api_key));
Expand All @@ -106,15 +97,15 @@ int main(int argc, char *argv[]) {
if (exporter_new_result.tag ==
DDPROF_FFI_NEW_PROFILE_EXPORTER_V3_RESULT_ERR) {
print_error("Failed to create exporter: ", exporter_new_result.err);
ddprof_ffi_NewProfileExporterV3Result_drop(exporter_new_result);
return 1;
}

Holder<ddprof_ffi_ProfileExporterV3> exporter{exporter_new_result.ok};
auto exporter = exporter_new_result.ok;

ddprof_ffi_File files_[] = {{
.name = DDPROF_FFI_CHARSLICE_C("auto.pprof"),
.file = {.ptr = encoded_profile->buffer.ptr,
.len = encoded_profile->buffer.len},
.file = ddprof_ffi_Vec_u8_as_slice(&encoded_profile->buffer),
}};

ddprof_ffi_Slice_file files = {.ptr = files_,
Expand All @@ -126,12 +117,17 @@ int main(int argc, char *argv[]) {
exporter, encoded_profile->start, encoded_profile->end, files,
additional_tags, 10000);

int exit_code = 0;
ddprof_ffi_SendResult send_result =
ddprof_ffi_ProfileExporterV3_send(exporter, request);
if (send_result.tag == DDPROF_FFI_SEND_RESULT_FAILURE) {
print_error("Failed to send profile: ", send_result.failure);
return 1;
exit_code = 1;
} else {
printf("Response code: %d\n", send_result.http_response.code);
}

ddprof_ffi_NewProfileExporterV3Result_drop(exporter_new_result);
ddprof_ffi_SendResult_drop(send_result);
return exit_code;
}