Skip to content
Open
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
11 changes: 8 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ project(

option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(BUILD_STATIC_LIBS "Build static libraries" ON)
option(DD_TRACE_BUILD_C_BINDING "Build C binding" OFF)

if (WIN32)
option(DD_TRACE_STATIC_CRT "Build dd-trace-cpp with static CRT with MSVC" OFF)
Expand Down Expand Up @@ -104,6 +105,10 @@ if (DD_TRACE_BUILD_TOOLS)
add_subdirectory(tools/config-inversion)
endif ()

if (DD_TRACE_BUILD_C_BINDING)
add_subdirectory(binding/c)
endif ()

add_library(dd-trace-cpp-objects OBJECT)
add_library(dd-trace-cpp::obj ALIAS dd-trace-cpp-objects)

Expand Down Expand Up @@ -294,11 +299,11 @@ if (BUILD_SHARED_LIBS)
)

install(
TARGETS dd-trace-cpp-shared
TARGETS dd-trace-cpp-shared
EXPORT dd-trace-cpp-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif ()

Expand Down Expand Up @@ -350,7 +355,7 @@ if (BUILD_STATIC_LIBS)
EXPORT dd-trace-cpp-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif ()

Expand Down
2 changes: 1 addition & 1 deletion bin/check-format
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh

find include/ src/ examples/ test/ -type f \( -name '*.h' -o -name '*.cpp' \) -print0 | \
find binding/ examples/ fuzz/ include/ src/ test/ -type f \( -name '*.h' -o -name '*.cpp' \) -print0 | \
xargs -0 clang-format-14 --style=file --dry-run -Werror
2 changes: 1 addition & 1 deletion bin/format
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ formatter=clang-format-$version
formatter_options="--style=file -i $*"

find_sources() {
find include/ src/ examples/ test/ fuzz/ -type f \( -name '*.h' -o -name '*.cpp' \) "$@"
find binding/ examples/ fuzz/ include/ src/ test/ -type f \( -name '*.h' -o -name '*.cpp' \) "$@"
}

# If the correct version of clang-format is installed, then use it and quit.
Expand Down
66 changes: 66 additions & 0 deletions binding/c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
add_library(dd_trace_c)
add_library(dd-trace-cpp::c_binding ALIAS dd_trace_c)

target_compile_definitions(dd_trace_c PRIVATE DD_TRACE_C_BUILDING)

target_sources(dd_trace_c
PRIVATE
$<TARGET_OBJECTS:dd-trace-cpp::obj>
src/tracer.cpp
)

if (DD_TRACE_TRANSPORT STREQUAL "curl")
target_sources(dd_trace_c
PRIVATE
${CMAKE_SOURCE_DIR}/src/datadog/curl.cpp
${CMAKE_SOURCE_DIR}/src/datadog/default_http_client_curl.cpp
)

target_link_libraries(dd_trace_c
PRIVATE
CURL::libcurl_shared
)
else ()
target_sources(dd_trace_c
PRIVATE
${CMAKE_SOURCE_DIR}/src/datadog/default_http_client_null.cpp
)
endif ()

target_include_directories(dd_trace_c
PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_SOURCE_DIR}/src
)

target_link_libraries(dd_trace_c
PRIVATE
dd-trace-cpp::obj
dd-trace-cpp::specs
)

install(TARGETS dd_trace_c
EXPORT dd-trace-cpp-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/datadog
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

if (DD_TRACE_BUILD_TESTING)
target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test/test_c_binding.cpp
)

target_include_directories(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
)

target_link_libraries(tests PRIVATE dd_trace_c)
endif ()
17 changes: 17 additions & 0 deletions binding/c/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# C Binding for dd-trace-cpp

A C binding interface on the C++ tracing library for
integration from C-based projects.

## Building

```sh
cmake -B build -DDD_TRACE_BUILD_C_BINDING=ON -DDD_TRACE_BUILD_TESTING=ON
cmake --build build -j
```

## Running Tests

```sh
./build/binding/c/test_c_binding
```
204 changes: 204 additions & 0 deletions binding/c/include/datadog/c/tracer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
#pragma once

#include <stddef.h>

#if defined(_WIN32)
#if defined(DD_TRACE_C_BUILDING)
#define DD_TRACE_C_API __declspec(dllexport)
#else
#define DD_TRACE_C_API __declspec(dllimport)
#endif
#elif defined(__GNUC__) || defined(__clang__)
#define DD_TRACE_C_API __attribute__((visibility("default")))
#else
#define DD_TRACE_C_API
#endif

#if defined(__cplusplus)
extern "C" {
#endif

// Callback used during trace context extraction. The tracer calls this
// function for each propagation header it needs to read (e.g. "x-datadog-*").
//
// @param key Header name to look up
// @return Header value, or NULL if the header is not present.
// The returned pointer must remain valid until
// dd_tracer_extract_or_create_span returns.
typedef const char* (*dd_context_read_callback)(const char* key);

// Callback used during trace context injection. The tracer calls this
// function for each propagation header it needs to write.
//
// @param key Header name to set
// @param value Header value to set
typedef void (*dd_context_write_callback)(const char* key, const char* value);

typedef enum {
DD_OPT_SERVICE_NAME = 0,
DD_OPT_ENV = 1,
DD_OPT_VERSION = 2,
DD_OPT_AGENT_URL = 3,
DD_OPT_INTEGRATION_NAME = 4,
DD_OPT_INTEGRATION_VERSION = 5
} dd_tracer_option;

// Options for creating a span. Unset fields default to NULL.
typedef struct {
const char* name;
const char* resource;
const char* service;
} dd_span_options_t;

// Error details populated on failure. Caller provides the struct,
// callee fills it in. Pass NULL to ignore errors.
typedef struct {
int code;
char message[256];
} dd_error_t;

typedef struct dd_conf_s dd_conf_t;
typedef struct dd_tracer_s dd_tracer_t;
typedef struct dd_span_s dd_span_t;

// Creates a tracer configuration instance.
//
// @return Configuration handle, or NULL on allocation failure
DD_TRACE_C_API dd_conf_t* dd_tracer_conf_new(void);

// Release a tracer configuration. Safe to call with NULL.
//
// @param handle Configuration handle to release
DD_TRACE_C_API void dd_tracer_conf_free(dd_conf_t* handle);

// Set or update a configuration field. No-op if handle is NULL.
//
// @param handle Configuration handle
// @param option Configuration option
// @param value Configuration value (interpretation depends on option)
DD_TRACE_C_API void dd_tracer_conf_set(dd_conf_t* handle,
dd_tracer_option option, void* value);

// Creates a tracer instance. The configuration handle may be freed with
// dd_tracer_conf_free after this call returns.
//
// @param conf_handle Configuration handle (not modified)
// @param error Optional error output (may be NULL)
//
// @return Tracer handle, or NULL on error
DD_TRACE_C_API dd_tracer_t* dd_tracer_new(const dd_conf_t* conf_handle,
dd_error_t* error);

// Release a tracer instance. Safe to call with NULL.
//
// @param tracer_handle Tracer handle to release
DD_TRACE_C_API void dd_tracer_free(dd_tracer_t* tracer_handle);

// Create a span using a Tracer.
//
// @param tracer_handle Tracer handle
// @param options Span options (name must not be NULL)
//
// @return Span handle, or NULL on error
DD_TRACE_C_API dd_span_t* dd_tracer_create_span(
dd_tracer_t* tracer_handle, const dd_span_options_t* options);

// Extract trace context from incoming headers, or create a new root span
// if extraction fails. Never returns an error span; on extraction failure
// a fresh root span is created.
//
// @param tracer_handle Tracer handle
// @param on_context_read Callback invoked to read propagation headers
// @param options Span options (name must not be NULL)
//
// @return Span handle, or NULL if arguments are invalid
DD_TRACE_C_API dd_span_t* dd_tracer_extract_or_create_span(
dd_tracer_t* tracer_handle, dd_context_read_callback on_context_read,
const dd_span_options_t* options);

// Release a span instance. Safe to call with NULL.
// If the span has not been finished with dd_span_finish, it is
// automatically finished (its end time is recorded) before being freed.
//
// @param span_handle Span handle
DD_TRACE_C_API void dd_span_free(dd_span_t* span_handle);

// Set a tag (key-value pair) on a span. No-op if any argument is NULL.
//
// @param span_handle Span handle
// @param key Tag key
// @param value Tag value
DD_TRACE_C_API void dd_span_set_tag(dd_span_t* span_handle, const char* key,
const char* value);

// Mark a span as erroneous. No-op if span_handle is NULL.
//
// @param span_handle Span handle
// @param error_value Non-zero to mark as error, zero to clear
DD_TRACE_C_API void dd_span_set_error(dd_span_t* span_handle, int error_value);

// Set an error message on a span. No-op if any argument is NULL.
//
// @param span_handle Span handle
// @param error_message Error message string
DD_TRACE_C_API void dd_span_set_error_message(dd_span_t* span_handle,
const char* error_message);

// Inject trace context into outgoing headers via callback.
// No-op if any argument is NULL.
//
// @param span_handle Span handle
// @param on_context_write Callback invoked per propagation header
DD_TRACE_C_API void dd_span_inject(dd_span_t* span_handle,
dd_context_write_callback on_context_write);

// Create a child span. Returns NULL if any required argument is NULL.
//
// @param span_handle Parent span handle
// @param options Span options (name must not be NULL)
//
// @return Child span handle, or NULL
DD_TRACE_C_API dd_span_t* dd_span_create_child(
dd_span_t* span_handle, const dd_span_options_t* options);

// Finish a span by recording its end time. No-op if span_handle is NULL.
// After finishing, the span should be freed with dd_span_free.
//
// @param span_handle Span handle
DD_TRACE_C_API void dd_span_finish(dd_span_t* span_handle);

// Get the trace ID as a zero-padded hex string.
//
// @param span_handle Span handle
// @param buffer Output buffer (at least 33 bytes for 128-bit IDs)
// @param buffer_size Size of the buffer
// @return Number of characters written, or -1 on error
DD_TRACE_C_API int dd_span_get_trace_id(dd_span_t* span_handle, char* buffer,
size_t buffer_size);

// Get the span ID as a zero-padded hex string.
//
// @param span_handle Span handle
// @param buffer Output buffer (at least 17 bytes)
// @param buffer_size Size of the buffer
// @return Number of characters written (16), or -1 on error
DD_TRACE_C_API int dd_span_get_span_id(dd_span_t* span_handle, char* buffer,
size_t buffer_size);

// Set the resource name on a span. No-op if any argument is NULL.
//
// @param span_handle Span handle
// @param resource Resource name
DD_TRACE_C_API void dd_span_set_resource(dd_span_t* span_handle,
const char* resource);

// Set the service name on a span. No-op if any argument is NULL.
//
// @param span_handle Span handle
// @param service Service name
DD_TRACE_C_API void dd_span_set_service(dd_span_t* span_handle,
const char* service);

#if defined(__cplusplus)
}
#endif
Loading
Loading