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

Collect 'logs_created' internal metric #2604

Merged
merged 8 commits into from
Apr 12, 2024
Merged
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
28 changes: 14 additions & 14 deletions components-rs/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,20 @@ typedef enum ddog_Log {
DDOG_LOG_HOOK_TRACE = (5 | (4 << 4)),
} ddog_Log;

typedef enum ddog_MetricNamespace {
DDOG_METRIC_NAMESPACE_TRACERS,
DDOG_METRIC_NAMESPACE_PROFILERS,
DDOG_METRIC_NAMESPACE_RUM,
DDOG_METRIC_NAMESPACE_APPSEC,
DDOG_METRIC_NAMESPACE_IDE_PLUGINS,
DDOG_METRIC_NAMESPACE_LIVE_DEBUGGER,
DDOG_METRIC_NAMESPACE_IAST,
DDOG_METRIC_NAMESPACE_GENERAL,
DDOG_METRIC_NAMESPACE_TELEMETRY,
DDOG_METRIC_NAMESPACE_APM,
DDOG_METRIC_NAMESPACE_SIDECAR,
} ddog_MetricNamespace;

typedef struct ddog_BlockingTransport_SidecarInterfaceResponse__SidecarInterfaceRequest ddog_BlockingTransport_SidecarInterfaceResponse__SidecarInterfaceRequest;

typedef struct ddog_InstanceId ddog_InstanceId;
Expand Down Expand Up @@ -176,20 +190,6 @@ typedef enum ddog_LogLevel {
DDOG_LOG_LEVEL_DEBUG,
} ddog_LogLevel;

typedef enum ddog_MetricNamespace {
DDOG_METRIC_NAMESPACE_TRACERS,
DDOG_METRIC_NAMESPACE_PROFILERS,
DDOG_METRIC_NAMESPACE_RUM,
DDOG_METRIC_NAMESPACE_APPSEC,
DDOG_METRIC_NAMESPACE_IDE_PLUGINS,
DDOG_METRIC_NAMESPACE_LIVE_DEBUGGER,
DDOG_METRIC_NAMESPACE_IAST,
DDOG_METRIC_NAMESPACE_GENERAL,
DDOG_METRIC_NAMESPACE_TELEMETRY,
DDOG_METRIC_NAMESPACE_APM,
DDOG_METRIC_NAMESPACE_SIDECAR,
} ddog_MetricNamespace;

typedef enum ddog_MetricType {
DDOG_METRIC_TYPE_GAUGE,
DDOG_METRIC_TYPE_COUNT,
Expand Down
9 changes: 6 additions & 3 deletions components-rs/ddtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ void ddog_set_log_level(ddog_CharSlice level, bool once);

void ddog_log(enum ddog_Log category, bool once, ddog_CharSlice msg);

void ddog_reset_log_once(void);
void ddog_reset_logger(void);

uint32_t ddog_get_logs_count(ddog_CharSlice level);

bool ddtrace_detect_composer_installed_json(ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
Expand Down Expand Up @@ -172,12 +174,13 @@ ddog_MaybeError ddog_sidecar_telemetry_buffer_flush(ddog_SidecarTransport **tran
struct ddog_SidecarActionsBuffer *buffer);

void ddog_sidecar_telemetry_register_metric_buffer(struct ddog_SidecarActionsBuffer *buffer,
ddog_CharSlice metric_name);
ddog_CharSlice metric_name,
enum ddog_MetricNamespace namespace_);

void ddog_sidecar_telemetry_add_span_metric_point_buffer(struct ddog_SidecarActionsBuffer *buffer,
ddog_CharSlice metric_name,
double metric_value,
ddog_CharSlice integration_name);
ddog_CharSlice tags);

ddog_MaybeError ddog_sidecar_connect_php(ddog_SidecarTransport **connection,
const char *error_path,
Expand Down
27 changes: 25 additions & 2 deletions components-rs/log.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::cell::RefCell;
use std::collections::BTreeSet;
use std::collections::{BTreeSet, HashMap};
use std::ffi::c_char;
use std::fmt::Debug;
use std::str::FromStr;
use tracing::Level;
use tracing_core::{Event, Field, LevelFilter, Subscriber};
use tracing_subscriber::EnvFilter;
Expand Down Expand Up @@ -39,6 +40,7 @@ pub static mut ddog_log_callback: Option<extern "C" fn(CharSlice)> = None;
std::thread_local! {
static LOGGED_MSGS: RefCell<BTreeSet<String>> = RefCell::default();
static TRACING_GUARDS: RefCell<Option<tracing_core::dispatcher::DefaultGuard>> = RefCell::default();
static COUNTERS: RefCell<HashMap<Level, u32>> = RefCell::default();
}

macro_rules! with_target {
Expand Down Expand Up @@ -144,6 +146,12 @@ impl<S, N> FormatEvent<S, N> for LogFormatter
} else {
fmt_msg(event, &msg, "")
};

COUNTERS.with(|counter| {
let mut counter = counter.borrow_mut();
*counter.entry(event.metadata().level().to_owned()).or_default() += 1;
});

cb(unsafe { CharSlice::from_raw_parts(msg.as_ptr() as *const c_char, msg.len() - 1) });
}
}
Expand Down Expand Up @@ -182,9 +190,24 @@ pub unsafe extern "C" fn ddog_log(category: Log, once: bool, msg: CharSlice) {
}

#[no_mangle]
pub extern "C" fn ddog_reset_log_once() {
pub extern "C" fn ddog_reset_logger() {
LOGGED_MSGS.with(|logged| {
let mut logged = logged.borrow_mut();
logged.clear();
});

COUNTERS.with(|counter| {
let mut counter = counter.borrow_mut();
counter.clear();
});
}

#[no_mangle]
pub extern "C" fn ddog_get_logs_count(level: CharSlice) -> u32 {
return COUNTERS.with(|counter| {
let level = Level::from_str(&level.to_utf8_lossy()).unwrap();

let mut counter = counter.borrow_mut();
*counter.entry(level).or_default()
});
}
15 changes: 7 additions & 8 deletions components-rs/telemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use datadog_sidecar::interface::blocking::SidecarTransport;
use datadog_sidecar::interface::{blocking, InstanceId, QueueId, SidecarAction};
use ddcommon_ffi::slice::AsBytes;
use ddcommon_ffi::CharSlice;
use ddcommon::tag::Tag;
use ddcommon::tag::parse_tags;
use ddtelemetry::data;
use ddtelemetry::data::metrics::MetricNamespace;
use ddtelemetry::data::{Dependency, Integration};
use ddtelemetry::metrics::MetricContext;
use ddtelemetry::worker::TelemetryActions;
Expand Down Expand Up @@ -134,14 +135,15 @@ pub extern "C" fn ddog_sidecar_telemetry_buffer_flush(
pub unsafe extern "C" fn ddog_sidecar_telemetry_register_metric_buffer(
buffer: &mut SidecarActionsBuffer,
metric_name: CharSlice,
namespace: MetricNamespace,
) {

buffer.buffer.push(SidecarAction::RegisterTelemetryMetric(MetricContext {
name: metric_name.to_utf8_lossy().into_owned(),
namespace: data::metrics::MetricNamespace::Tracers,
namespace,
metric_type: data::metrics::MetricType::Count,
tags: Vec::default(),
common: false,
common: true,
}));
}

Expand All @@ -150,12 +152,9 @@ pub unsafe extern "C" fn ddog_sidecar_telemetry_add_span_metric_point_buffer(
buffer: &mut SidecarActionsBuffer,
metric_name: CharSlice,
metric_value: f64,
integration_name: CharSlice,
tags: CharSlice,
) {
let mut tags: Vec<Tag> = Vec::default();
if integration_name.len() > 0 {
tags.push(Tag::new("integration_name", integration_name.to_utf8_lossy().into_owned()).unwrap())
}
let (tags, _) = parse_tags(&tags.to_utf8_lossy());

buffer.buffer.push(SidecarAction::AddTelemetryMetricPoint((
metric_name.to_utf8_lossy().into_owned(),
Expand Down
7 changes: 6 additions & 1 deletion ext/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ static void dd_activate_once(void) {
static pthread_once_t dd_activate_once_control = PTHREAD_ONCE_INIT;

static void ddtrace_activate(void) {
ddog_reset_log_once();
ddog_reset_logger();

zai_hook_rinit();
zai_interceptor_activate();
Expand Down Expand Up @@ -2045,6 +2045,11 @@ PHP_FUNCTION(dd_trace_internal_fn) {
ddtrace_coms_synchronous_flush(timeout);
RETVAL_TRUE;
#endif
} else if (FUNCTION_NAME_MATCHES("test_logs")) {
ddog_logf(DDOG_LOG_WARN, false, "foo");
ddog_logf(DDOG_LOG_WARN, false, "bar");
ddog_logf(DDOG_LOG_ERROR, false, "Boum");
RETVAL_TRUE;
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions ext/sidecar.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ static inline ddog_CharSlice dd_zend_string_to_CharSlice(zend_string *str) {
return (ddog_CharSlice){ .len = str->len, .ptr = str->val };
}

static inline ddog_CharSlice dd_zai_string_to_CharSlice(zai_string str) {
return (ddog_CharSlice){ .len = str.len, .ptr = str.ptr };
}

static inline bool ddtrace_ffi_try(const char *msg, ddog_Option_VecU8 maybe_error) {
if (maybe_error.tag == DDOG_OPTION_VEC_U8_SOME_VEC_U8) {
LOG(ERROR, "%s: %.*s", msg, (int) maybe_error.some.len, maybe_error.some.ptr);
Expand Down
25 changes: 23 additions & 2 deletions ext/telemetry.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,34 @@ void ddtrace_telemetry_finalize(void) {

// Telemetry metrics
ddog_CharSlice metric_name = DDOG_CHARSLICE_C("spans_created");
ddog_sidecar_telemetry_register_metric_buffer(buffer, metric_name);
ddog_sidecar_telemetry_register_metric_buffer(buffer, metric_name, DDOG_METRIC_NAMESPACE_TRACERS);
zend_string *integration_name;
zval *metric_value;
ZEND_HASH_FOREACH_STR_KEY_VAL(&DDTRACE_G(telemetry_spans_created_per_integration), integration_name, metric_value) {
ddog_sidecar_telemetry_add_span_metric_point_buffer(buffer, metric_name, Z_DVAL_P(metric_value), dd_zend_string_to_CharSlice(integration_name));
zai_string tags = zai_string_concat3((zai_str)ZAI_STRL("integration_name:"), (zai_str)ZAI_STR_FROM_ZSTR(integration_name), (zai_str)ZAI_STRING_EMPTY);
ddog_sidecar_telemetry_add_span_metric_point_buffer(buffer, metric_name, Z_DVAL_P(metric_value), dd_zai_string_to_CharSlice(tags));
zai_string_destroy(&tags);
} ZEND_HASH_FOREACH_END();

metric_name = DDOG_CHARSLICE_C("logs_created");
ddog_sidecar_telemetry_register_metric_buffer(buffer, metric_name, DDOG_METRIC_NAMESPACE_GENERAL);
static struct {
ddog_CharSlice level;
ddog_CharSlice tags;
} log_levels[] = {
{DDOG_CHARSLICE_C_BARE("trace"), DDOG_CHARSLICE_C_BARE("level:trace")},
{DDOG_CHARSLICE_C_BARE("debug"), DDOG_CHARSLICE_C_BARE("level:debug")},
{DDOG_CHARSLICE_C_BARE("info"), DDOG_CHARSLICE_C_BARE("level:info")},
{DDOG_CHARSLICE_C_BARE("warn"), DDOG_CHARSLICE_C_BARE("level:warn")},
{DDOG_CHARSLICE_C_BARE("error"), DDOG_CHARSLICE_C_BARE("level:error")},
};
uint32_t count;
for (size_t i = 0; i < sizeof(log_levels) / sizeof(log_levels[0]); ++i) {
if ((count = ddog_get_logs_count(log_levels[i].level)) > 0) {
ddog_sidecar_telemetry_add_span_metric_point_buffer(buffer, metric_name, (double)count, log_levels[i].tags);
}
}

ddog_sidecar_telemetry_buffer_flush(&ddtrace_sidecar, ddtrace_sidecar_instance_id, &DDTRACE_G(telemetry_queue_id), buffer);

ddog_CharSlice service_name = DDOG_CHARSLICE_C_BARE("unnamed-php-service");
Expand Down
38 changes: 20 additions & 18 deletions tests/Integrations/Custom/Autoloaded/InstrumentationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ public function testInstrumentation()
$this->resetRequestDumper();

$this->call(GetSpec::create("autoloaded", "/simple"));
$response = $this->retrieveDumpedData();
if (!$response) {
$this->fail("Go no response from request-dumper");
}
$response = $this->retrieveDumpedData(function ($request) {
return (strpos($request["uri"] ?? "", "/telemetry/") === 0)
&& (strpos($request["body"] ?? "", "generate-metrics") !== false)
;
}, true);

$this->assertCount(4, $response);
$this->assertGreaterThanOrEqual(3, $response);
$payloads = $this->readTelemetryPayloads($response);

$isMetric = function (array $payload) {
Expand All @@ -78,19 +79,20 @@ public function testInstrumentation()
// Not asserting app-closing, this is not expected to happen until shutdown

$this->assertCount(1, $metrics);
$this->assertEquals("generate-metrics", $metrics[0]["request_type"]);
$this->assertEquals("tracers", $metrics[0]["payload"]["series"][0]["namespace"]);
$this->assertEquals("spans_created", $metrics[0]["payload"]["series"][0]["metric"]);
$this->assertEquals(["integration_name:datadog"], $metrics[0]["payload"]["series"][0]["tags"]);
$series = array_values(array_filter($metrics[0]["payload"]["series"], function ($p) { return $p['metric'] === 'spans_created'; }));
$this->assertEquals("tracers", $series[0]["namespace"]);
$this->assertEquals("spans_created", $series[0]["metric"]);
$this->assertEquals(["integration_name:datadog"], $series[0]["tags"]);

$this->call(GetSpec::create("autoloaded", "/pdo"));

$response = $this->retrieveDumpedData();
if (!$response) {
$this->fail("Go no response from request-dumper");
}
$response = $this->retrieveDumpedData(function ($request) {
return (strpos($request["uri"] ?? "", "/telemetry/") === 0)
&& (strpos($request["body"] ?? "", "generate-metrics") !== false)
;
}, true);

$this->assertCount(4, $response);
$this->assertGreaterThanOrEqual(3, $response);
$payloads = $this->readTelemetryPayloads($response);

$metrics = array_values(array_filter($payloads, $isMetric));
Expand Down Expand Up @@ -124,9 +126,9 @@ public function testInstrumentation()
], $payloads[2]["payload"]["integrations"]);

$this->assertCount(1, $metrics);
$this->assertEquals("generate-metrics", $metrics[0]["request_type"]);
$this->assertEquals("tracers", $metrics[0]["payload"]["series"][0]["namespace"]);
$this->assertEquals("spans_created", $metrics[0]["payload"]["series"][0]["metric"]);
$this->assertEquals(["integration_name:pdo"], $metrics[0]["payload"]["series"][0]["tags"]);
$series = array_values(array_filter($metrics[0]["payload"]["series"], function ($p) { return $p['metric'] === 'spans_created'; }));
$this->assertEquals("tracers", $series[0]["namespace"]);
$this->assertEquals("spans_created", $series[0]["metric"]);
$this->assertEquals(["integration_name:pdo"], $series[0]["tags"]);
}
}
Loading
Loading