Skip to content
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
4 changes: 4 additions & 0 deletions components-rs/ddtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,8 @@ void ddog_add_zstr_span_meta_struct_CharSlice(ddog_SpanBytes *ptr,
struct _zend_string *key,
ddog_CharSlice val);

const char *ddog_normalize_process_tag_value(ddog_CharSlice val);

void ddog_free_normalized_tag_value(const char* normalized_val);

#endif /* DDTRACE_PHP_H */
51 changes: 51 additions & 0 deletions components-rs/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,54 @@ pub unsafe extern "C" fn posix_spawn_file_actions_addchdir_np(
-libc::ENOSYS
}
}

const MAX_TAG_VALUE_LENGTH: usize = 100;

#[no_mangle]
pub extern "C" fn ddog_normalize_process_tag_value(
tag_value: CharSlice,
) -> *const c_char {
let value = tag_value.to_utf8_lossy();

let mut out = String::new();
let mut prev_underscore = false;
let mut started = false;
for c in value.chars().take(MAX_TAG_VALUE_LENGTH) {
if c.is_alphanumeric() || matches!(c, '/' | '.' | '-') {
for lc in c.to_lowercase() {
out.push(lc);
}
started = true;
prev_underscore = false;
} else {
if started && !prev_underscore {
out.push('_');
prev_underscore = true;
}
}
}

// trim trailing underscores
if out.ends_with('_') {
out.pop();
}

match std::ffi::CString::new(out) {
Ok(c_string) => {
let out_ptr = c_string.as_ptr();
std::mem::forget(c_string);
out_ptr
}
Err(_) => std::ptr::null(),
}
}

#[no_mangle]
pub extern "C" fn ddog_free_normalized_tag_value(ptr: *const c_char) {
if ptr.is_null() {
return;
}
unsafe {
drop(std::ffi::CString::from_raw(ptr as *mut c_char));
}
}
1 change: 1 addition & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ if test "$PHP_DDTRACE" != "no"; then
ext/memory_limit.c \
ext/otel_config.c \
ext/priority_sampling/priority_sampling.c \
ext/process_tags.c \
ext/profiling.c \
ext/random.c \
ext/remote_config.c \
Expand Down
1 change: 1 addition & 0 deletions config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ if (PHP_DDTRACE != 'no') {
DDTRACE_EXT_SOURCES += " logging.c";
DDTRACE_EXT_SOURCES += " memory_limit.c";
DDTRACE_EXT_SOURCES += " otel_config.c";
DDTRACE_EXT_SOURCES += " process_tags.c";
DDTRACE_EXT_SOURCES += " profiling.c";
DDTRACE_EXT_SOURCES += " random.c";
DDTRACE_EXT_SOURCES += " remote_config.c";
Expand Down
1 change: 1 addition & 0 deletions ext/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ enum ddtrace_sampling_rules_format {
CONFIG(INT, DD_CODE_ORIGIN_MAX_USER_FRAMES, "8") \
CONFIG(BOOL, DD_TRACE_RESOURCE_RENAMING_ENABLED, "false") \
CONFIG(BOOL, DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT, "false") \
CONFIG(BOOL, DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED, "false") \
DD_INTEGRATIONS

#ifndef _WIN32
Expand Down
27 changes: 27 additions & 0 deletions ext/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#include "limiter/limiter.h"
#include "standalone_limiter.h"
#include "priority_sampling/priority_sampling.h"
#include "process_tags.h"
#include "random.h"
#include "autoload_php_files.h"
#include "remote_config.h"
Expand Down Expand Up @@ -1615,6 +1616,7 @@ static PHP_MSHUTDOWN_FUNCTION(ddtrace) {
ddtrace_sidecar_shutdown();

ddtrace_live_debugger_mshutdown();
ddtrace_process_tags_mshutdown();

#if PHP_VERSION_ID >= 80000 && PHP_VERSION_ID < 80100
// See dd_register_span_data_ce for explanation
Expand All @@ -1637,6 +1639,11 @@ static void dd_rinit_once(void) {
*/
ddtrace_startup_logging_first_rinit();

// Collect process tags now that script path is available
if (get_global_DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED()) {
ddtrace_process_tags_first_rinit();
}

// Uses config, cannot run earlier
#ifndef _WIN32
ddtrace_signals_first_rinit();
Expand Down Expand Up @@ -2610,6 +2617,26 @@ PHP_FUNCTION(DDTrace_Testing_trigger_error) {
}
}

PHP_FUNCTION(DDTrace_Testing_normalize_tag_value) {
ddtrace_string value;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &value.ptr, &value.len) != SUCCESS) {
RETURN_EMPTY_STRING();
}

const char* normalized = ddog_normalize_process_tag_value((ddog_CharSlice){
.ptr = value.ptr,
.len = value.len
});

if (normalized) {
zend_string *result = zend_string_init(normalized, strlen(normalized), 0);
ddog_free_normalized_tag_value(normalized);
RETURN_STR(result);
} else {
RETURN_EMPTY_STRING();
}
}

PHP_FUNCTION(DDTrace_Internal_add_span_flag) {
zend_object *span;
zend_long flag;
Expand Down
43 changes: 25 additions & 18 deletions ext/ddtrace.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,13 @@ function trigger_error(string $message, int $errorType): void {}
* Emits an asm event
*/
function emit_asm_event(): void {}
/**
* Normalizes a process tag value
*
* @param string $value The tag value to normalize
* @return string The normalized tag value
*/
function normalize_tag_value(string $value): string {}
}

namespace DDTrace\Internal {
Expand Down Expand Up @@ -939,24 +946,24 @@ function handle_fork(): void {}

namespace datadog\appsec\v2 {
/**
* Track a user login success event.
*
* @param string $login is the data used by the user to authenticate
* @param string|array $user when string, it represents the user id. When array it represents the user information.
* The array should at least contain the following keys:
* - id: string, Unique identifier of the user. Should be the same id and format used on set_user
* @param array $metadata User metadata added to the root span
*/
function track_user_login_success(string $login, string|array|null $user = null, array $metadata = []): void {}

/**
* Track a user login failure event.
*
* @param string $login is the data used by the user to authenticate
* @param bool $exists Whether the user exists in the system
* @param array $metadata User metadata added to the root span
*/
function track_user_login_failure(string $login, bool $exists, array $metadata = []): void {}
* Track a user login success event.
*
* @param string $login is the data used by the user to authenticate
* @param string|array $user when string, it represents the user id. When array it represents the user information.
* The array should at least contain the following keys:
* - id: string, Unique identifier of the user. Should be the same id and format used on set_user
* @param array $metadata User metadata added to the root span
*/
function track_user_login_success(string $login, string|array|null $user = null, array $metadata = []): void {}

/**
* Track a user login failure event.
*
* @param string $login is the data used by the user to authenticate
* @param bool $exists Whether the user exists in the system
* @param array $metadata User metadata added to the root span
*/
function track_user_login_failure(string $login, bool $exists, array $metadata = []): void {}
}

namespace {
Expand Down
6 changes: 6 additions & 0 deletions ext/ddtrace_arginfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ ZEND_END_ARG_INFO()

#define arginfo_DDTrace_Testing_emit_asm_event arginfo_DDTrace_flush

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Testing_normalize_tag_value, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_Internal_add_span_flag, 0, 2, IS_VOID, 0)
ZEND_ARG_OBJ_INFO(0, span, DDTrace\\SpanData, 0)
ZEND_ARG_TYPE_INFO(0, flag, IS_LONG, 0)
Expand Down Expand Up @@ -383,6 +387,7 @@ ZEND_FUNCTION(DDTrace_UserRequest_notify_commit);
ZEND_FUNCTION(DDTrace_UserRequest_set_blocking_function);
ZEND_FUNCTION(DDTrace_Testing_trigger_error);
ZEND_FUNCTION(DDTrace_Testing_emit_asm_event);
ZEND_FUNCTION(DDTrace_Testing_normalize_tag_value);
ZEND_FUNCTION(DDTrace_Internal_add_span_flag);
ZEND_FUNCTION(DDTrace_Internal_handle_fork);
ZEND_FUNCTION(datadog_appsec_v2_track_user_login_success);
Expand Down Expand Up @@ -473,6 +478,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\UserRequest", "set_blocking_function"), zif_DDTrace_UserRequest_set_blocking_function, arginfo_DDTrace_UserRequest_set_blocking_function, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Testing", "trigger_error"), zif_DDTrace_Testing_trigger_error, arginfo_DDTrace_Testing_trigger_error, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Testing", "emit_asm_event"), zif_DDTrace_Testing_emit_asm_event, arginfo_DDTrace_Testing_emit_asm_event, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Testing", "normalize_tag_value"), zif_DDTrace_Testing_normalize_tag_value, arginfo_DDTrace_Testing_normalize_tag_value, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "add_span_flag"), zif_DDTrace_Internal_add_span_flag, arginfo_DDTrace_Internal_add_span_flag, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Internal", "handle_fork"), zif_DDTrace_Internal_handle_fork, arginfo_DDTrace_Internal_handle_fork, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("datadog\\appsec\\v2", "track_user_login_success"), zif_datadog_appsec_v2_track_user_login_success, arginfo_datadog_appsec_v2_track_user_login_success, 0, NULL, NULL)
Expand Down
Loading
Loading