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

Sanchda/add metrics #236

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Style fixups
  • Loading branch information
sanchda committed Nov 30, 2022
commit 559eceeda1711db7a379ac91b650d6692b33ec6e
2 changes: 1 addition & 1 deletion include/ddprof_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#include "ddprof_defs.hpp"
#include "ddprof_worker_context.hpp"
#include "exporter_input.hpp"
#include "perf_watcher.hpp"
#include "metric_aggregator.hpp"
#include "perf_watcher.hpp"

#include <sched.h>

Expand Down
12 changes: 6 additions & 6 deletions include/metric_aggregator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "ddres.hpp"
#include "statsd.hpp"

struct MetricAggregator{
struct MetricAggregator {
std::string base_path = "profiler.native.";
std::string sockpath = "/var/run/datadog-agent/statsd.sock";
std::unordered_map<std::string, uint64_t> values;
Expand All @@ -25,9 +25,7 @@ struct MetricAggregator{
values[safe_str] = values[safe_str] + val;
}

void clear() {
values.clear();
}
void clear() { values.clear(); }

bool send() {
PRINT_NFO("Preparing to send metrics");
Expand All @@ -41,10 +39,12 @@ struct MetricAggregator{
for (const auto &pair : values) {
std::string metric_name = base_path + pair.first;
void *coerced_val = (void *)&pair.second;
if (IsDDResNotOK(statsd_send(fd, metric_name.c_str(), coerced_val, STAT_GAUGE))) {
if (IsDDResNotOK(
statsd_send(fd, metric_name.c_str(), coerced_val, STAT_GAUGE))) {
LG_ERR("Could not send metric %s on fd %d", metric_name.c_str(), fd);
} else {
PRINT_NFO("Sent metric %s of value %lu", metric_name.c_str(), pair.second);
PRINT_NFO("Sent metric %s of value %lu", metric_name.c_str(),
pair.second);
}
}
statsd_close(fd);
Expand Down
3 changes: 2 additions & 1 deletion include/perf_watcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,6 @@ int sample_type_id_to_count_sample_type_id(int idx);

// Other helper functions
uint64_t perf_event_default_sample_type();
unsigned int tracepoint_id_from_event(const char *eventname, const char*groupname);
unsigned int tracepoint_id_from_event(const char *eventname,
const char *groupname);
const char *get_tracefs_root();
45 changes: 25 additions & 20 deletions src/ddprof_worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,16 @@ static DDRes worker_update_stats(ProcStatus *procstat, const DsoHdr *dso_hdr,
return ddres_init();
}

void ddprof_metric_aggregate(DDProfContext *ctx, PerfWatcher *watcher, uint64_t val) {
void ddprof_metric_aggregate(DDProfContext *ctx, PerfWatcher *watcher,
uint64_t val) {
// Fallthrough sequence to figure out what we call this thing
const char *metric_name = "unnameable_metric";
if (!watcher->tracepoint_label.empty())
metric_name = watcher->tracepoint_label.c_str();
else if (!watcher->desc.empty())
metric_name = watcher->desc.c_str();

ctx->metrics.add(metric_name, val);
ctx->metrics.add(metric_name, val);
}

/************************* perf_event_open() helpers **************************/
Expand Down Expand Up @@ -253,20 +254,22 @@ DDRes ddprof_pr_sample(DDProfContext *ctx, perf_event_sample *sample,
DDRes res = unwindstate__unwind(us);

/* This test is not 100% accurate:
* Linux kernel does not take into account stack start (ie. end address since
* stack grows down) when capturing the stack, it starts from SP register and
* only limits the range with the requested size and user space end (cf.
* Linux kernel does not take into account stack start (ie. end address
* since stack grows down) when capturing the stack, it starts from SP
* register and only limits the range with the requested size and user space
* end (cf.
* https://elixir.bootlin.com/linux/v5.19.3/source/kernel/events/core.c#L6582).
* Then it tries to copy this range, and stops when it encounters a non-mapped
* address
* Then it tries to copy this range, and stops when it encounters a
* non-mapped address
* (https://elixir.bootlin.com/linux/v5.19.3/source/kernel/events/core.c#L6660).
* This works well for main thread since [stack] is at the top of the process
* user address space (and there is a gap between [vvar] and [stack]), but
* for threads, stack can be allocated anywhere on the heap and if address
* space below allocated stack is mapped, then kernel will happily copy the
* whole range up to the requested sample stack size, therefore always
* returning samples with `dyn_size` equals to the requested sample stack
* size, even if the end of captured stack is not actually part of the stack.
* This works well for main thread since [stack] is at the top of the
* process user address space (and there is a gap between [vvar] and
* [stack]), but for threads, stack can be allocated anywhere on the heap
* and if address space below allocated stack is mapped, then kernel will
* happily copy the whole range up to the requested sample stack size,
* therefore always returning samples with `dyn_size` equals to the
* requested sample stack size, even if the end of captured stack is not
* actually part of the stack.
*
* That's why we consider the stack as truncated in input only if it is also
* detected as incomplete during unwinding.
Expand All @@ -275,20 +278,22 @@ DDRes ddprof_pr_sample(DDProfContext *ctx, perf_event_sample *sample,
us->output.is_incomplete) {
ddprof_stats_add(STATS_UNWIND_TRUNCATED_INPUT, 1, nullptr);
}

DDRES_CHECK_FWD(
ddprof_stats_add(STATS_UNWIND_AVG_TIME, unwind_ticks - ticks0, NULL));

// Aggregate if unwinding went well (todo : fatal error propagation)
if (!IsDDResFatal(res) && EventConfMode::kCallgraph <= watcher->output_mode) {
if (!IsDDResFatal(res) &&
EventConfMode::kCallgraph <= watcher->output_mode) {
#ifndef DDPROF_NATIVE_LIB
// in lib mode we don't aggregate (protect to avoid link failures)
int i_export = ctx->worker_ctx.i_current_pprof;
DDProfPProf *pprof = ctx->worker_ctx.pprof[i_export];
DDRES_CHECK_FWD(pprof_aggregate(&us->output, &us->symbol_hdr, sample_val, 1,
watcher, pprof));
DDRES_CHECK_FWD(pprof_aggregate(&us->output, &us->symbol_hdr, sample_val,
1, watcher, pprof));
if (ctx->params.show_samples) {
ddprof_print_sample(us->output, us->symbol_hdr, sample->period, *watcher);
ddprof_print_sample(us->output, us->symbol_hdr, sample->period,
*watcher);
}
#else
// Call the user's stack handler
Expand Down
14 changes: 5 additions & 9 deletions src/perf_watcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
#include "perf.hpp"

#include <fcntl.h>
#include <unistd.h>
#include <stddef.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define BASE_STYPES \
(PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER | PERF_SAMPLE_TID | \
Expand Down Expand Up @@ -110,11 +110,9 @@ bool watcher_has_tracepoint(const PerfWatcher *watcher) {
}

const char *get_tracefs_root() {
static const char* tracepoint_root = NULL;
static const char *tracepoint_root = NULL;
constexpr std::array<std::string_view, 2> candidate_paths = {
"/sys/kernel/tracing/events/",
"/sys/kernel/debug/tracing/events"
};
"/sys/kernel/tracing/events/", "/sys/kernel/debug/tracing/events"};

if (!tracepoint_root) {
struct stat sa;
Expand All @@ -141,9 +139,8 @@ unsigned int tracepoint_id_from_event(const char *eventname,
return 0;
}
char *buf_copy = buf;
size_t pathsz =
snprintf(path, sizeof(path), "%s/%s/%s/id",
tracefs_root, groupname, eventname);
size_t pathsz = snprintf(path, sizeof(path), "%s/%s/%s/id", tracefs_root,
groupname, eventname);
if (pathsz >= sizeof(path))
return 0;
int fd = open(path, O_RDONLY);
Expand All @@ -164,4 +161,3 @@ unsigned int tracepoint_id_from_event(const char *eventname,

return trace_id;
}