Skip to content

Commit

Permalink
Provide a DogStatsD API (#2639)
Browse files Browse the repository at this point in the history
* Pass the dogstatsd URL to the sidecar

* Init the dogstatsd public API

* Add support for tags in dogstatsd functions

* Change the count value type from float to int

* Add tests

* Use proper Vec<Tag> instead of string serialization

* Add support for Distribution and histogram

* Fix compilation issues

* Add support for the 'Set' metric type

* Move ddtrace_dogstatsd_url function in a new file as dogstatsd_client.c is not compiled on windows

* Debug test

* Add global tags

* Fix handling of invalid tags

* Fix stubs

* Skip test failing because of a PHP bug on PHP 7.0/7.1

* Fix int type: we must support signed numbers
  • Loading branch information
iamluc committed May 27, 2024
1 parent a40f7af commit f246102
Show file tree
Hide file tree
Showing 17 changed files with 582 additions and 7 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

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

33 changes: 32 additions & 1 deletion components-rs/sidecar.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ bool ddog_sidecar_is_closed(ddog_SidecarTransport **transport);

ddog_MaybeError ddog_sidecar_session_set_config(ddog_SidecarTransport **transport,
ddog_CharSlice session_id,
const struct ddog_Endpoint *endpoint,
const struct ddog_Endpoint *agent_endpoint,
const struct ddog_Endpoint *dogstatsd_endpoint,
uint64_t flush_interval_milliseconds,
uintptr_t force_flush_size,
uintptr_t force_drop_size,
Expand All @@ -139,4 +140,34 @@ ddog_CharSlice ddog_sidecar_dump(ddog_SidecarTransport **transport);

ddog_CharSlice ddog_sidecar_stats(ddog_SidecarTransport **transport);

ddog_MaybeError ddog_sidecar_dogstatsd_count(ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
ddog_CharSlice metric,
int64_t value,
const struct ddog_Vec_Tag *tags);

ddog_MaybeError ddog_sidecar_dogstatsd_distribution(ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
ddog_CharSlice metric,
double value,
const struct ddog_Vec_Tag *tags);

ddog_MaybeError ddog_sidecar_dogstatsd_gauge(ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
ddog_CharSlice metric,
double value,
const struct ddog_Vec_Tag *tags);

ddog_MaybeError ddog_sidecar_dogstatsd_histogram(ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
ddog_CharSlice metric,
double value,
const struct ddog_Vec_Tag *tags);

ddog_MaybeError ddog_sidecar_dogstatsd_set(ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
ddog_CharSlice metric,
int64_t value,
const struct ddog_Vec_Tag *tags);

#endif /* DDOG_SIDECAR_H */
1 change: 1 addition & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ if test "$PHP_DDTRACE" != "no"; then
ext/configuration.c \
ext/ddshared.c \
ext/distributed_tracing_headers.c \
ext/dogstatsd.c \
ext/dogstatsd_client.c \
ext/engine_api.c \
ext/engine_hooks.c \
Expand Down
2 changes: 1 addition & 1 deletion config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if (PHP_DDTRACE != 'no') {

var version = PHP_VERSION * 100 + PHP_MINOR_VERSION;

var DDTRACE_EXT_SOURCES = "arrays.c auto_flush.c autoload_php_files.c compat_string.c configuration.c distributed_tracing_headers.c ddshared.c engine_api.c engine_hooks.c excluded_modules.c handlers_api.c handlers_curl" + (version < 800 ? "_php7" : "") + ".c handlers_exception.c handlers_internal.c handlers_pcntl.c ip_extraction.c logging.c memory_limit.c profiling.c random.c serializer.c sidecar.c span.c startup_logging.c telemetry.c user_request.c";
var DDTRACE_EXT_SOURCES = "arrays.c auto_flush.c autoload_php_files.c compat_string.c configuration.c distributed_tracing_headers.c ddshared.c dogstatsd.c engine_api.c engine_hooks.c excluded_modules.c handlers_api.c handlers_curl" + (version < 800 ? "_php7" : "") + ".c handlers_exception.c handlers_internal.c handlers_pcntl.c ip_extraction.c logging.c memory_limit.c profiling.c random.c serializer.c sidecar.c span.c startup_logging.c telemetry.c user_request.c";
if (version >= 800 && version < 802) {
DDTRACE_EXT_SOURCES += " weakrefs.c";
}
Expand Down
2 changes: 0 additions & 2 deletions ext/auto_flush.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ DDTRACE_PUBLIC void ddtrace_close_all_spans_and_flush()
ddtrace_flush_tracer(true, true);
}

#define HOST_V6_FORMAT_STR "http://[%s]:%u"
#define HOST_V4_FORMAT_STR "http://%s:%u"
#define DEFAULT_UDS_PATH "/var/run/datadog/apm.socket"

char *ddtrace_agent_url(void) {
Expand Down
85 changes: 85 additions & 0 deletions ext/ddtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,91 @@ PHP_FUNCTION(DDTrace_Internal_handle_fork) {
dd_internal_handle_fork();
}

PHP_FUNCTION(DDTrace_dogstatsd_count) {
zend_string *metric;
zend_long value;
zval *tags = NULL;

ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(metric)
Z_PARAM_LONG(value)
Z_PARAM_OPTIONAL
Z_PARAM_ARRAY(tags)
ZEND_PARSE_PARAMETERS_END();

ddtrace_sidecar_dogstatsd_count(metric, value, tags);

RETURN_NULL();
}

PHP_FUNCTION(DDTrace_dogstatsd_distribution) {
zend_string *metric;
double value;
zval *tags = NULL;

ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(metric)
Z_PARAM_DOUBLE(value)
Z_PARAM_OPTIONAL
Z_PARAM_ARRAY(tags)
ZEND_PARSE_PARAMETERS_END();

ddtrace_sidecar_dogstatsd_distribution(metric, value, tags);

RETURN_NULL();
}

PHP_FUNCTION(DDTrace_dogstatsd_gauge) {
zend_string *metric;
double value;
zval *tags = NULL;

ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(metric)
Z_PARAM_DOUBLE(value)
Z_PARAM_OPTIONAL
Z_PARAM_ARRAY(tags)
ZEND_PARSE_PARAMETERS_END();

ddtrace_sidecar_dogstatsd_gauge(metric, value, tags);

RETURN_NULL();
}

PHP_FUNCTION(DDTrace_dogstatsd_histogram) {
zend_string *metric;
double value;
zval *tags = NULL;

ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(metric)
Z_PARAM_DOUBLE(value)
Z_PARAM_OPTIONAL
Z_PARAM_ARRAY(tags)
ZEND_PARSE_PARAMETERS_END();

ddtrace_sidecar_dogstatsd_histogram(metric, value, tags);

RETURN_NULL();
}

PHP_FUNCTION(DDTrace_dogstatsd_set) {
zend_string *metric;
zend_long value;
zval *tags = NULL;

ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(metric)
Z_PARAM_LONG(value)
Z_PARAM_OPTIONAL
Z_PARAM_ARRAY(tags)
ZEND_PARSE_PARAMETERS_END();

ddtrace_sidecar_dogstatsd_set(metric, value, tags);

RETURN_NULL();
}

PHP_FUNCTION(dd_trace_send_traces_via_thread) {
char *payload = NULL;
ddtrace_zpplong_t num_traces = 0;
Expand Down
3 changes: 3 additions & 0 deletions ext/ddtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,7 @@ extern TSRM_TLS void *ATTR_TLS_GLOBAL_DYNAMIC TSRMLS_CACHE;

#include "random.h"

#define HOST_V6_FORMAT_STR "http://[%s]:%u"
#define HOST_V4_FORMAT_STR "http://%s:%u"

#endif // DDTRACE_H
45 changes: 45 additions & 0 deletions ext/ddtrace.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,51 @@ function flush(): void {}
* @param list{\CurlHandle, SpanData}[] $array An array which will be populated with curl handles and spans.
*/
function curl_multi_exec_get_request_spans(&$array): void {}

/**
* Update a DogStatsD counter
*
* @param string $metric The metric name
* @param int $value The metric value
* @param array $tags A list of tags associated to the metric
*/
function dogstatsd_count(string $metric, int $value, array $tags = []): void {}

/**
* Update a DogStatsD distribution
*
* @param string $metric The metric name
* @param float $value The metric value
* @param array $tags A list of tags associated to the metric
*/
function dogstatsd_distribution(string $metric, float $value, array $tags = []): void {}

/**
* Update a DogStatsD gauge
*
* @param string $metric The metric name
* @param float $value The metric value
* @param array $tags A list of tags associated to the metric
*/
function dogstatsd_gauge(string $metric, float $value, array $tags = []): void {}

/**
* Update a DogStatsD histogram
*
* @param string $metric The metric name
* @param float $value The metric value
* @param array $tags A list of tags associated to the metric
*/
function dogstatsd_histogram(string $metric, float $value, array $tags = []): void {}

/**
* Update a DogStatsD set
*
* @param string $metric The metric name
* @param int $value The metric value
* @param array $tags A list of tags associated to the metric
*/
function dogstatsd_set(string $metric, int $value, array $tags = []): void {}
}

namespace DDTrace\System {
Expand Down
30 changes: 29 additions & 1 deletion ext/ddtrace_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: cbd454866b5b3f34bee057c9a35d7807c6e718ca */
* Stub hash: 3a83516da1c795bbe41abd106fcc3e069bf3d946 */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_trace_method, 0, 3, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, className, IS_STRING, 0)
Expand Down Expand Up @@ -128,6 +128,24 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_curl_multi_exec_get_requ
ZEND_ARG_INFO(1, array)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_dogstatsd_count, 0, 2, IS_VOID, 0)
ZEND_ARG_TYPE_INFO(0, metric, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, value, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tags, IS_ARRAY, 0, "[]")
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_dogstatsd_distribution, 0, 2, IS_VOID, 0)
ZEND_ARG_TYPE_INFO(0, metric, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, value, IS_DOUBLE, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tags, IS_ARRAY, 0, "[]")
ZEND_END_ARG_INFO()

#define arginfo_DDTrace_dogstatsd_gauge arginfo_DDTrace_dogstatsd_distribution

#define arginfo_DDTrace_dogstatsd_histogram arginfo_DDTrace_dogstatsd_distribution

#define arginfo_DDTrace_dogstatsd_set arginfo_DDTrace_dogstatsd_count

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_System_container_id, 0, 0, IS_STRING, 1)
ZEND_END_ARG_INFO()

Expand Down Expand Up @@ -302,6 +320,11 @@ ZEND_FUNCTION(DDTrace_current_context);
ZEND_FUNCTION(DDTrace_set_distributed_tracing_context);
ZEND_FUNCTION(DDTrace_flush);
ZEND_FUNCTION(DDTrace_curl_multi_exec_get_request_spans);
ZEND_FUNCTION(DDTrace_dogstatsd_count);
ZEND_FUNCTION(DDTrace_dogstatsd_distribution);
ZEND_FUNCTION(DDTrace_dogstatsd_gauge);
ZEND_FUNCTION(DDTrace_dogstatsd_histogram);
ZEND_FUNCTION(DDTrace_dogstatsd_set);
ZEND_FUNCTION(DDTrace_System_container_id);
ZEND_FUNCTION(DDTrace_Config_integration_analytics_enabled);
ZEND_FUNCTION(DDTrace_Config_integration_analytics_sample_rate);
Expand Down Expand Up @@ -377,6 +400,11 @@ static const zend_function_entry ext_functions[] = {
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "set_distributed_tracing_context"), zif_DDTrace_set_distributed_tracing_context, arginfo_DDTrace_set_distributed_tracing_context, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "flush"), zif_DDTrace_flush, arginfo_DDTrace_flush, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "curl_multi_exec_get_request_spans"), zif_DDTrace_curl_multi_exec_get_request_spans, arginfo_DDTrace_curl_multi_exec_get_request_spans, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_count"), zif_DDTrace_dogstatsd_count, arginfo_DDTrace_dogstatsd_count, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_distribution"), zif_DDTrace_dogstatsd_distribution, arginfo_DDTrace_dogstatsd_distribution, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_gauge"), zif_DDTrace_dogstatsd_gauge, arginfo_DDTrace_dogstatsd_gauge, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_histogram"), zif_DDTrace_dogstatsd_histogram, arginfo_DDTrace_dogstatsd_histogram, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_set"), zif_DDTrace_dogstatsd_set, arginfo_DDTrace_dogstatsd_set, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\System", "container_id"), zif_DDTrace_System_container_id, arginfo_DDTrace_System_container_id, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Config", "integration_analytics_enabled"), zif_DDTrace_Config_integration_analytics_enabled, arginfo_DDTrace_Config_integration_analytics_enabled, 0, NULL, NULL)
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\Config", "integration_analytics_sample_rate"), zif_DDTrace_Config_integration_analytics_sample_rate, arginfo_DDTrace_Config_integration_analytics_sample_rate, 0, NULL, NULL)
Expand Down
44 changes: 44 additions & 0 deletions ext/dogstatsd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "dogstatsd.h"

#include "configuration.h"
#include "ddtrace.h"

ZEND_EXTERN_MODULE_GLOBALS(ddtrace);

#define DEFAULT_UDS_PATH "/var/run/datadog/dsd.socket"

char *ddtrace_dogstatsd_url(void) {
zend_string *url = get_DD_DOGSTATSD_URL();
if (ZSTR_LEN(url) > 0) {
return zend_strndup(ZSTR_VAL(url), ZSTR_LEN(url) + 1);
}

zend_string *hostname = get_global_DD_AGENT_HOST();
if (ZSTR_LEN(hostname) > 7 && strncmp(ZSTR_VAL(hostname), "unix://", 7) == 0) {
return zend_strndup(ZSTR_VAL(hostname), ZSTR_LEN(hostname));
}

if (ZSTR_LEN(hostname) > 0) {
bool isIPv6 = memchr(ZSTR_VAL(hostname), ':', ZSTR_LEN(hostname));

int port = atoi(ZSTR_VAL(get_DD_DOGSTATSD_PORT()));
if (port <= 0 || port > 65535) {
port = 8125;
}
char *formatted_url;
asprintf(&formatted_url, isIPv6 ? HOST_V6_FORMAT_STR : HOST_V4_FORMAT_STR, ZSTR_VAL(hostname), (uint32_t)port);
return formatted_url;
}

if (access(DEFAULT_UDS_PATH, F_OK) == SUCCESS) {
return zend_strndup(ZEND_STRL("unix://" DEFAULT_UDS_PATH));
}

int64_t port = get_global_DD_TRACE_AGENT_PORT();
if (port <= 0 || port > 65535) {
port = 8125;
}
char *formatted_url;
asprintf(&formatted_url, HOST_V4_FORMAT_STR, "localhost", (uint32_t)port);
return formatted_url;
}
6 changes: 6 additions & 0 deletions ext/dogstatsd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef DDTRACE_DOGSTATSD_H
#define DDTRACE_DOGSTATSD_H

char *ddtrace_dogstatsd_url(void);

#endif // DDTRACE_DOGSTATSD_H

0 comments on commit f246102

Please sign in to comment.