Skip to content
Draft
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
5 changes: 2 additions & 3 deletions cmake/Findlibdatadog.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
# License Version 2.0. This product includes software developed at Datadog
# (https://www.datadoghq.com/). Copyright 2021-Present Datadog, Inc.

# libdatadog : common profiler imported libraries
# https://github.com/DataDog/libdatadog/releases/tag/v7.0.0
# libdatadog : common profiler imported libraries https://github.com/DataDog/libdatadog/releases
set(TAG_LIBDATADOG
"v19.1.0"
"v26.0.0"
CACHE STRING "libdatadog github tag")

set(Datadog_ROOT ${VENDOR_PATH}/libdatadog-${TAG_LIBDATADOG})
Expand Down
3 changes: 2 additions & 1 deletion include/pprof/ddprof_pprof.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ struct DDProfValuePack {
uint64_t timestamp;
};

DDRes pprof_create_profile(DDProfPProf *pprof, DDProfContext &ctx);
DDRes pprof_create_profile(DDProfPProf *pprof, DDProfContext &ctx,
const ddog_prof_ProfilesDictionaryHandle *dict);

/**
* Aggregate to the existing profile the provided unwinding output.
Expand Down
1 change: 0 additions & 1 deletion include/symbol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class Symbol {
public:
Symbol() : _lineno(0) {}

// Warning : Generates some string copies (these are not rvalues)
Symbol(std::string symname, std::string demangled_name, uint32_t lineno,
std::string srcpath)
: _symname(std::move(symname)),
Expand Down
26 changes: 24 additions & 2 deletions include/symbol_hdr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,30 @@
#include "runtime_symbol_lookup.hpp"

#include <cstdlib>
#include <memory>

// Forward declarations for libdatadog types (must be at global scope)
struct ddog_prof_ProfilesDictionary;
using ddog_prof_ProfilesDictionaryHandle = ddog_prof_ProfilesDictionary *;

namespace ddprof {

struct ProfilesDictionaryDeleter {
void operator()(ddog_prof_ProfilesDictionaryHandle *handle) const;
};

using ProfilesDictionaryPtr =
std::unique_ptr<ddog_prof_ProfilesDictionaryHandle,
ProfilesDictionaryDeleter>;

struct SymbolHdr {
explicit SymbolHdr(std::string_view path_to_proc = "")
: _runtime_symbol_lookup(path_to_proc) {}
explicit SymbolHdr(std::string_view path_to_proc = "");
~SymbolHdr() = default;

SymbolHdr(const SymbolHdr &) = delete;
SymbolHdr &operator=(const SymbolHdr &) = delete;
SymbolHdr(SymbolHdr &&) noexcept = default;
SymbolHdr &operator=(SymbolHdr &&) noexcept = default;
void display_stats() const { _dso_symbol_lookup.stats_display(); }
void cycle() { _runtime_symbol_lookup.cycle(); }

Expand All @@ -44,6 +63,9 @@ struct SymbolHdr {

// The mapping table
MapInfoTable _mapinfo_table;

// String interning dictionary (persists across profile exports)
ProfilesDictionaryPtr _profiles_dictionary;
};

} // namespace ddprof
1 change: 0 additions & 1 deletion src/ddog_profiling_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ std::string_view get_or_insert_demangled_sym(

void write_function(const Symbol &symbol, ddog_prof_Function *ffi_func) {
ffi_func->name = to_CharSlice(symbol._demangled_name);
// We can also send symbol._symname if useful
ffi_func->system_name = {.ptr = nullptr, .len = 0};
ffi_func->filename = to_CharSlice(symbol._srcpath);
}
Expand Down
8 changes: 6 additions & 2 deletions src/ddprof_worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -710,8 +710,12 @@ DDRes ddprof_worker_init(DDProfContext &ctx,
DDRES_CHECK_FWD(
ddprof_exporter_new(ctx.worker_ctx.user_tags, ctx.worker_ctx.exp[1]));

DDRES_CHECK_FWD(pprof_create_profile(ctx.worker_ctx.pprof[0], ctx));
DDRES_CHECK_FWD(pprof_create_profile(ctx.worker_ctx.pprof[1], ctx));
DDRES_CHECK_FWD(pprof_create_profile(
ctx.worker_ctx.pprof[0], ctx,
ctx.worker_ctx.us->symbol_hdr._profiles_dictionary.get()));
DDRES_CHECK_FWD(pprof_create_profile(
ctx.worker_ctx.pprof[1], ctx,
ctx.worker_ctx.us->symbol_hdr._profiles_dictionary.get()));
DDRES_CHECK_FWD(worker_init_stats(&ctx.worker_ctx));
}
CatchExcept2DDRes();
Expand Down
81 changes: 27 additions & 54 deletions src/exporter/ddprof_exporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,10 @@ DDRes ddprof_exporter_new(const UserTags *user_tags, DDProfExporter *exporter) {
ddog_CharSlice const base_url = to_CharSlice(exporter->_url);
ddog_prof_Endpoint endpoint;
if (exporter->_agent) {
endpoint = ddog_prof_Endpoint_agent(base_url);
endpoint = ddog_prof_Endpoint_agent(base_url, k_timeout_ms);
} else {
ddog_CharSlice const api_key = to_CharSlice(exporter->_input.api_key);
endpoint = ddog_prof_Endpoint_agentless(base_url, api_key);
endpoint = ddog_prof_Endpoint_agentless(base_url, api_key, k_timeout_ms);
}

ddog_prof_ProfileExporter_Result res_exporter = ddog_prof_Exporter_new(
Expand All @@ -283,14 +283,6 @@ DDRes ddprof_exporter_new(const UserTags *user_tags, DDProfExporter *exporter) {
static_cast<int>(res_exporter.err.message.len),
res_exporter.err.message.ptr);
}
auto result =
ddog_prof_Exporter_set_timeout(&exporter->_exporter, k_timeout_ms);
if (result.tag == DDOG_VOID_RESULT_ERR) {
defer { ddog_Error_drop(&result.err); };
DDRES_RETURN_ERROR_LOG(DD_WHAT_EXPORTER, "Failure setting timeout - %.*s",
static_cast<int>(result.err.message.len),
result.err.message.ptr);
}
return {};
}

Expand Down Expand Up @@ -335,53 +327,34 @@ DDRes ddprof_exporter_export(ddog_prof_Profile *profile,

LG_NTC("[EXPORTER] Export buffer of size %lu", buffer->len);

// clang-format off
ddog_prof_Request_Result res_request =
ddog_prof_Exporter_Request_build(&exporter->_exporter,
encoded_profile,
ddog_prof_Exporter_Slice_File_empty(), // files_to_compress_and_export
ddog_prof_Exporter_Slice_File_empty(), // already compressed
&ffi_additional_tags, // optional tags
nullptr, // internal_metadata_json
nullptr // optional_info_json
);
// clang-format on

if (res_request.tag == DDOG_PROF_REQUEST_RESULT_OK_HANDLE_REQUEST) {
ddog_prof_Request request = res_request.ok;

// dropping the request is not useful if we have a send
// however the send will replace the request by null when it takes
// ownership
defer { ddog_prof_Exporter_Request_drop(&request); };

ddog_prof_Result_HttpStatus result =
ddog_prof_Exporter_send(&exporter->_exporter, &request, nullptr);

if (result.tag == DDOG_PROF_RESULT_HTTP_STATUS_ERR_HTTP_STATUS) {
defer { ddog_Error_drop(&result.err); };
LG_WRN("Failure to establish connection, check url %s",
exporter->_url.c_str());
LG_WRN("Failure to send profiles (%.*s)", (int)result.err.message.len,
result.err.message.ptr);
// Free error buffer (prefer this API to the free API)
if (exporter->_nb_consecutive_errors++ >=
k_max_nb_consecutive_errors_allowed) {
// this will shut down profiler
res = ddres_error(DD_WHAT_EXPORTER);
} else {
res = ddres_warn(DD_WHAT_EXPORTER);
}
ddog_prof_Result_HttpStatus result = ddog_prof_Exporter_send_blocking(
&exporter->_exporter, encoded_profile,
ddog_prof_Exporter_Slice_File_empty(), // files_to_compress_and_export
&ffi_additional_tags, // optional_additional_tags
nullptr, // optional_process_tags
nullptr, // optional_internal_metadata_json
nullptr, // optional_info_json
nullptr // cancellation_token
);

if (result.tag == DDOG_PROF_RESULT_HTTP_STATUS_ERR_HTTP_STATUS) {
defer { ddog_Error_drop(&result.err); };
LG_WRN("Failure to establish connection, check url %s",
exporter->_url.c_str());
LG_WRN("Failure to send profiles (%.*s)", (int)result.err.message.len,
result.err.message.ptr);
// Free error buffer (prefer this API to the free API)
if (exporter->_nb_consecutive_errors++ >=
k_max_nb_consecutive_errors_allowed) {
// this will shut down profiler
res = ddres_error(DD_WHAT_EXPORTER);
} else {
// success establishing connection
exporter->_nb_consecutive_errors = 0;
res = check_send_response_code(result.ok.code);
res = ddres_warn(DD_WHAT_EXPORTER);
}
} else {
defer { ddog_Error_drop(&res_request.err); };
LG_ERR("[EXPORTER] Failure to build request: %s",
res_request.err.message.ptr);
res = ddres_error(DD_WHAT_EXPORTER);
// success establishing connection
exporter->_nb_consecutive_errors = 0;
res = check_send_response_code(result.ok.code);
}
}
return res;
Expand Down
16 changes: 9 additions & 7 deletions src/pprof/ddprof_pprof.cc
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,8 @@ DDRes process_symbolization(

} // namespace

DDRes pprof_create_profile(DDProfPProf *pprof, DDProfContext &ctx) {
DDRes pprof_create_profile(DDProfPProf *pprof, DDProfContext &ctx,
const ddog_prof_ProfilesDictionaryHandle *dict) {
size_t const num_watchers = ctx.watchers.size();

ActiveIdsResult active_ids = {};
Expand Down Expand Up @@ -463,15 +464,16 @@ DDRes pprof_create_profile(DDProfPProf *pprof, DDProfContext &ctx) {
.value = default_period,
};
}
auto prof_res = ddog_prof_Profile_new(
sample_types,

ddog_prof_Status status = ddog_prof_Profile_with_dictionary(
&pprof->_profile, dict, sample_types,
pprof_values.get_num_sample_type_ids() > 0 ? &period : nullptr);

if (prof_res.tag != DDOG_PROF_PROFILE_NEW_RESULT_OK) {
ddog_Error_drop(&prof_res.err);
DDRES_RETURN_ERROR_LOG(DD_WHAT_PPROF, "Unable to create new profile");
if (status.err != nullptr) {
defer { ddog_prof_Status_drop(&status); };
DDRES_RETURN_ERROR_LOG(DD_WHAT_PPROF, "Unable to create new profile: %s",
status.err);
}
pprof->_profile = prof_res.ok;

// Add relevant tags
{
Expand Down
4 changes: 4 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ add_unit_test(
../src/ddog_profiling_utils.cc
../src/ddprof_cmdline_watcher.cc
../src/pprof/ddprof_pprof.cc
../src/symbol_hdr.cc
../src/symbolizer.cc
../src/demangler/demangler.cc
../src/perf_watcher.cc
Expand All @@ -209,6 +210,7 @@ add_unit_test(
../src/exporter/ddprof_exporter.cc
../src/pprof/ddprof_pprof.cc
../src/perf_watcher.cc
../src/symbol_hdr.cc
../src/symbolizer.cc
../src/demangler/demangler.cc
../src/tags.cc
Expand Down Expand Up @@ -266,6 +268,7 @@ add_unit_test(
../src/mapinfo_lookup.cc
../src/procutils.cc
../src/runtime_symbol_lookup.cc
../src/symbol_hdr.cc
../src/symbol_map.cc
../src/signal_helper.cc
../src/statsd.cc
Expand Down Expand Up @@ -313,6 +316,7 @@ set(ALLOCATION_TRACKER_UT_SRCS
../src/mapinfo_lookup.cc
../src/procutils.cc
../src/runtime_symbol_lookup.cc
../src/symbol_hdr.cc
../src/symbol_map.cc
../src/signal_helper.cc
../src/statsd.cc
Expand Down
3 changes: 2 additions & 1 deletion test/ddprof_exporter-ut.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ TEST(DDProfExporter, simple) {
fill_unwind_symbols(table, mapinfo_table, mock_output);
DDProfContext ctx = {};
ctx.watchers.push_back(*ewatcher_from_str("sCPU"));
res = pprof_create_profile(&pprofs, ctx);
res = pprof_create_profile(&pprofs, ctx,
symbol_hdr._profiles_dictionary.get());
EXPECT_TRUE(IsDDResOK(res));
res = pprof_aggregate(&mock_output, symbol_hdr, {1000, 1, 0},
&ctx.watchers[0], file_infos, false, kSumPos,
Expand Down
14 changes: 9 additions & 5 deletions test/ddprof_pprof-ut.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ TEST(DDProfPProf, init_profiles) {
DDProfPProf pprof;
DDProfContext ctx = {};
ctx.watchers.push_back(*ewatcher_from_str("sCPU"));
DDRes res = pprof_create_profile(&pprof, ctx);
ddog_prof_ProfilesDictionaryHandle dict;
ddog_prof_ProfilesDictionary_new(&dict);
DDRes res = pprof_create_profile(&pprof, ctx, &dict);
EXPECT_TRUE(IsDDResOK(res));
res = pprof_free_profile(&pprof);
EXPECT_TRUE(IsDDResOK(res));
ddog_prof_ProfilesDictionary_drop(&dict);
}

void test_pprof(DDProfPProf *pprofs) {
Expand All @@ -47,8 +50,7 @@ void test_pprof(DDProfPProf *pprofs) {

EXPECT_TRUE(buffer->ptr);

// Test that we are generating content
EXPECT_TRUE(buffer->len > 500);
EXPECT_TRUE(buffer->len > 100);

ddog_prof_EncodedProfile_drop(&serialized_result.ok);
}
Expand All @@ -66,7 +68,8 @@ TEST(DDProfPProf, aggregate) {

bool ok = watchers_from_str("sCPU", ctx.watchers);
EXPECT_TRUE(ok);
DDRes res = pprof_create_profile(&pprof, ctx);
DDRes res = pprof_create_profile(&pprof, ctx,
symbol_hdr._profiles_dictionary.get());
EXPECT_TRUE(ctx.watchers[0].pprof_indices[kSumPos].pprof_index != -1);
EXPECT_TRUE(ctx.watchers[0].pprof_indices[kSumPos].pprof_count_index != -1);
res = pprof_aggregate(&mock_output, symbol_hdr, {1000, 1, 0},
Expand Down Expand Up @@ -102,7 +105,8 @@ TEST(DDProfPProf, just_live) {
log_watcher(&(ctx.watchers[0]), 0);
log_watcher(&(ctx.watchers[1]), 1);

DDRes res = pprof_create_profile(&pprof, ctx);
DDRes res = pprof_create_profile(&pprof, ctx,
symbol_hdr._profiles_dictionary.get());
EXPECT_TRUE(IsDDResOK(res));
EXPECT_TRUE(ctx.watchers[0].pprof_indices[kSumPos].pprof_index == -1);
EXPECT_TRUE(ctx.watchers[0].pprof_indices[kSumPos].pprof_count_index == -1);
Expand Down
12 changes: 6 additions & 6 deletions tools/libdatadog_checksums.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
7c69a37cb335260610b61ae956192a6dbd104d05a8278c8ff894dbfebc2efd53 libdatadog-aarch64-alpine-linux-musl.tar.gz
b992a11b90ec5927646a0c96b74fe9fcd63e7e471307e74a670ddf42fc10eaf9 libdatadog-aarch64-apple-darwin.tar.gz
606b23f4de7defacd5d4a381816f8d7bfe26112c97fcdf21ec2eb998a6c5fbbd libdatadog-aarch64-unknown-linux-gnu.tar.gz
2008886021ddee573c0d539626d1d58d41e2a7dbc8deca22b3662da52de6f4d9 libdatadog-x86_64-alpine-linux-musl.tar.gz
6a12ef60fd7b00544343c2b6761ef801ad2e1237075711bd16dfb7247464bc43 libdatadog-x86_64-apple-darwin.tar.gz
4e5b05515ab180aec0819608aa5d277ff710055819654147a9d69caea27a0dbc libdatadog-x86_64-unknown-linux-gnu.tar.gz
38b83da2781f20f004d278c077b071441f40671de2e0adf72f7e14e37b10db15 libdatadog-x86_64-apple-darwin.tar.gz
1420ba4970ff9158aec4bd8a80d139abe8c19cfd71ae31c6c518f8a2ad1416b8 libdatadog-aarch64-apple-darwin.tar.gz
1778bed8bb4ec5a63af792ed6d7b0acd2564e5c7633d9b65d7c715e7f8635743 libdatadog-x86_64-unknown-linux-gnu.tar.gz
c90bd4959026f7fddb9012036fdc5b1e49bdf57d716cb429cdde291af6108740 libdatadog-aarch64-alpine-linux-musl.tar.gz
c67ada4359cd6a806adafcb44043bc8fb0dffd463e3aa328856496e2883142ac libdatadog-aarch64-unknown-linux-gnu.tar.gz
394b13591400b36d90755bc9851be047e6d31813347ed9d0e2638355cc9617d4 libdatadog-x86_64-alpine-linux-musl.tar.gz