Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
810806d
feat: otel context sharing
morrisonlevi Jun 10, 2026
95d1ced
Merge remote-tracking branch 'origin/master' into levi/otel-thread-co…
morrisonlevi Jun 15, 2026
2f7bcf4
Read OTEL thread context directly in profiler
morrisonlevi Jun 15, 2026
4a9ff50
update libdatadog
cataphract Jun 19, 2026
10c0b74
Also publish otel context
cataphract Jun 19, 2026
d4848f1
demo of otel thread context reader
cataphract Jun 19, 2026
9fb7e50
Support otel thread local context
morrisonlevi Jun 15, 2026
4905f86
Merge branch 'glopes/otel-thr-ctx-metadata' of github.com:DataDog/dd-…
cataphract Jun 23, 2026
ab53138
Add tests for otel ctx/thread local
cataphract Jun 23, 2026
563d22b
Merge remote-tracking branch 'origin/master' into levi/otel-thread-co…
cataphract Jun 23, 2026
e995d2e
build fixes
cataphract Jun 23, 2026
0913661
misc fixes/improvements
cataphract Jun 24, 2026
7b3dc40
Improve logging during appsec tel int tests
cataphract Jun 24, 2026
58ac8c3
Merge branch 'master' into levi/otel-thread-context
morrisonlevi Jun 24, 2026
d0dd590
refactor based on discussion
morrisonlevi Jun 24, 2026
f288f5a
refactor: implement discussion from slack
morrisonlevi Jun 24, 2026
733970a
fix -DDD_APPSEC_DDTRACE_ALT=ON build
cataphract Jun 24, 2026
89d9511
Implement PHP tracer-owned OTel thread-context storage
cataphract Jun 25, 2026
ac5adaf
partial eager init OTel thread-context; fixes for service/env/version…
cataphract Jun 25, 2026
5adb764
Update libdatadog to a version incl otel proc ctx read
cataphract Jun 25, 2026
7f5b393
address review comments, fix stack-use-after-return
cataphract Jun 29, 2026
5bec63b
upd libdatdog ref
cataphract Jun 29, 2026
7b3e832
Merge remote-tracking branch 'origin/master' into levi/otel-thread-co…
cataphract Jun 29, 2026
4f9c1c3
refactor(profiling): simplify otel context FFI
morrisonlevi Jun 30, 2026
96c3b0e
Merge branch 'master' into levi/otel-thread-context
morrisonlevi Jun 30, 2026
110757e
chore(libdatadog): update otel thread context branch
morrisonlevi Jun 30, 2026
b091ea2
refactor: realign after meeting with Bob and Ivo
morrisonlevi Jul 3, 2026
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
32 changes: 26 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 21 additions & 8 deletions appsec/cmake/ddtrace.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include(ExternalProject)
include(CheckCCompilerFlag)

set(CARGO_BUILD_CMD "cargo build")
set(CARGO_BUILD_ENV "") # Initialize to empty
Expand Down Expand Up @@ -34,9 +35,11 @@ add_custom_target(ddtrace_exports
elseif(APPLE)
set(EXPORTS_FILE "${CMAKE_BINARY_DIR}/datadog_exports.sym")
add_custom_target(ddtrace_exports
COMMAND sed "s/^/_/" "${CMAKE_SOURCE_DIR}/../datadog.sym" > "${EXPORTS_FILE}"
# otel_thread_ctx_v1 is a Linux-only TLS symbol.
COMMAND bash -c "grep -v ^otel_thread_ctx_v1$ '${CMAKE_SOURCE_DIR}'/../datadog.sym | sed 's/^/_/' > '${EXPORTS_FILE}'"
BYPRODUCTS ${EXPORTS_FILE}
DEPENDS ${CMAKE_SOURCE_DIR}/../datadog.sym
VERBATIM
)
endif()

Expand Down Expand Up @@ -92,6 +95,8 @@ file(GLOB_RECURSE FILES_DDTRACE
CONFIGURE_DEPENDS
"${CMAKE_SOURCE_DIR}/../ext/*.c"
"${CMAKE_SOURCE_DIR}/../ext/**/*.c"
"${CMAKE_SOURCE_DIR}/../tracer/*.c"
"${CMAKE_SOURCE_DIR}/../tracer/**/*.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/*.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/**/*.c"
)
Expand All @@ -103,28 +108,28 @@ list(APPEND FILES_DDTRACE
"${CMAKE_SOURCE_DIR}/../components/string_view/string_view.c"
)
if (PhpConfig_VERNUM GREATER_EQUAL 80000)
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../ext/handlers_curl_php7.c"
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../tracer/handlers_curl_php7.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/interceptor/php7/interceptor.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/interceptor/php7/resolver.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/sandbox/php7/sandbox.c")
else() # PHP 7
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../ext/handlers_curl.c"
"${CMAKE_SOURCE_DIR}/../ext/hook/uhook_attributes.c"
"${CMAKE_SOURCE_DIR}/../ext/hook/uhook_otel.c"
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../tracer/handlers_curl.c"
"${CMAKE_SOURCE_DIR}/../tracer/hook/uhook_attributes.c"
"${CMAKE_SOURCE_DIR}/../tracer/hook/uhook_otel.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/interceptor/php8/interceptor.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/interceptor/php8/resolver.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/interceptor/php8/resolver_pre-8_2.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/jit_utils/jit_blacklist.c"
"${CMAKE_SOURCE_DIR}/../zend_abstract_interface/sandbox/php8/sandbox.c")
endif()
if (PhpConfig_VERNUM LESS 80200)
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../ext/weakrefs.c")
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../tracer/weakrefs.c")
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../zend_abstract_interface/interceptor/php8/resolver.c")
else() # PHP 8.2+
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../zend_abstract_interface/interceptor/php8/resolver_pre-8_2.c")
endif()
if (PhpConfig_VERNUM LESS 80100)
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../ext/handlers_fiber.c")
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../tracer/handlers_fiber.c")
endif()
list(REMOVE_ITEM FILES_DDTRACE "${CMAKE_SOURCE_DIR}/../ext/crashtracking_windows.c")

Expand Down Expand Up @@ -162,7 +167,13 @@ endif()
if(CURL_DEFINITIONS)
target_compile_definitions(ddtrace PRIVATE ${CURL_DEFINITIONS})
endif()
target_compile_definitions(ddtrace PRIVATE ZEND_ENABLE_STATIC_TSRMLS_CACHE=1 COMPILE_DL_DDTRACE=1)
target_compile_definitions(ddtrace PRIVATE ZEND_ENABLE_STATIC_TSRMLS_CACHE=1 COMPILE_DL_DDTRACE=1 DDTRACE)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$")
check_c_compiler_flag("-mtls-dialect=gnu2" DDTRACE_HAS_GNU2_TLS_DIALECT)
if(DDTRACE_HAS_GNU2_TLS_DIALECT)
target_compile_options(ddtrace PRIVATE -mtls-dialect=gnu2)
endif()
endif()
target_include_directories(ddtrace PRIVATE
${CURL_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/..
Expand All @@ -171,6 +182,8 @@ target_include_directories(ddtrace PRIVATE
${CMAKE_SOURCE_DIR}/../ext
${CMAKE_SOURCE_DIR}/../ext/vendor
${CMAKE_SOURCE_DIR}/../ext/vendor/mt19937
${CMAKE_SOURCE_DIR}/../tracer
${CMAKE_SOURCE_DIR}/../tracer/vendor
${CMAKE_BINARY_DIR}/gen_ddtrace
)
add_dependencies(ddtrace ddtrace_exports update_version_h)
Expand Down
29 changes: 29 additions & 0 deletions appsec/src/extension/ddappsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <pthread.h>
#include <stdatomic.h>
Expand Down Expand Up @@ -55,6 +56,7 @@ static atomic_int _thread_count;
static void _check_enabled(void);
#ifdef TESTING
static void _register_testing_objects(void);
volatile int ddappsec_debugger_wait_continue;
#endif

static PHP_MINIT_FUNCTION(ddappsec);
Expand Down Expand Up @@ -481,6 +483,32 @@ static PHP_FUNCTION(datadog_appsec_testing_stop_for_debugger)
RETURN_TRUE;
}

static PHP_FUNCTION(datadog_appsec_testing_wait_for_debugger)
{
if (zend_parse_parameters_none() == FAILURE) {
RETURN_FALSE;
}
ddappsec_debugger_wait_continue = 0;

int fd = open(
"/tmp/pid", O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0600); // NOLINT
if (fd < 0) {
RETURN_FALSE;
}
char pid[sizeof("-2147483648")] = "";
sprintf(pid, "%" PRIi32, (int32_t)getpid()); // NOLINT
ATTR_UNUSED ssize_t unused_ = write(fd, pid, strlen(pid));
close(fd);

while (!ddappsec_debugger_wait_continue) {
usleep(10000); // NOLINT
}
ddappsec_debugger_wait_continue = 0;
unlink("/tmp/pid"); // NOLINT

RETURN_TRUE;
}

static PHP_FUNCTION(datadog_appsec_testing_request_exec)
{
zend_array *data = NULL;
Expand Down Expand Up @@ -632,6 +660,7 @@ static const zend_function_entry testing_request_control_functions[] = {
ZEND_RAW_FENTRY(DD_TESTING_NS "rinit", PHP_FN(datadog_appsec_testing_rinit), void_ret_bool_arginfo, 0, NULL, NULL)
ZEND_RAW_FENTRY(DD_TESTING_NS "rshutdown", PHP_FN(datadog_appsec_testing_rshutdown), void_ret_bool_arginfo, 0, NULL, NULL)
ZEND_RAW_FENTRY(DD_TESTING_NS "request_exec", PHP_FN(datadog_appsec_testing_request_exec), request_exec_arginfo, 0, NULL, NULL)
ZEND_RAW_FENTRY(DD_TESTING_NS "wait_for_debugger", PHP_FN(datadog_appsec_testing_wait_for_debugger), void_ret_bool_arginfo, 0, NULL, NULL)
PHP_FE_END
};
static const zend_function_entry testing_functions[] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class TelemetryHandler implements Handler {
ctx.bodyInputStream().withCloseable {
message = readTelemetryMessage(it)
}
log.debug("Read telemetry message: ${message['request_type']}")
log.debug("Read telemetry message: ${describeTelemetryMessage(message)}")
} catch (AssertionError e) {
log.error("Error reading traces: $e.message")
error = e
Expand Down Expand Up @@ -52,6 +52,48 @@ class TelemetryHandler implements Handler {
jsonSlurper.parse(is)
}

private static String describeTelemetryMessage(Object message) {
def application = message['application'] ?: [:]
def requestType = message['request_type']
def payload = message['payload']
def details = [
"request_type=${requestType}",
"seq_id=${message['seq_id']}",
"service=${application['service_name']}",
"runtime_id=${application['runtime_id']}",
]
def payloadSummary = describeTelemetryPayload(requestType, payload)
if (payloadSummary) {
details << "payload=${payloadSummary}"
}
details.join(', ')
}

private static String describeTelemetryPayload(String requestType, Object payload) {
if (requestType == 'message-batch' && payload instanceof List) {
return payload.collect { describeTelemetryPayload(it['request_type'], it['payload']) }
.findAll { it }
.join('; ')
}

if (!(payload instanceof Map)) {
return null
}

def fields = []
if (payload['integrations'] instanceof List) {
fields << "integrations=${payload['integrations'].collect { it['name'] }}"
}
if (payload['dependencies'] instanceof List) {
fields << "dependencies=${payload['dependencies'].size()}"
}
if (payload['configuration'] instanceof List) {
fields << "configuration=${payload['configuration'].size()}"
}

return "${requestType}{${fields.join(', ')}}"
}

List<Object> drain(long timeoutInMs) {
synchronized (capturedTelemetryMessages) {
if (!savedError && capturedTelemetryMessages.isEmpty()) {
Expand Down
Loading
Loading