Skip to content

Commit f246102

Browse files
authored
Provide a DogStatsD API (#2639)
* 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
1 parent a40f7af commit f246102

17 files changed

Lines changed: 582 additions & 7 deletions

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components-rs/sidecar.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ bool ddog_sidecar_is_closed(ddog_SidecarTransport **transport);
118118

119119
ddog_MaybeError ddog_sidecar_session_set_config(ddog_SidecarTransport **transport,
120120
ddog_CharSlice session_id,
121-
const struct ddog_Endpoint *endpoint,
121+
const struct ddog_Endpoint *agent_endpoint,
122+
const struct ddog_Endpoint *dogstatsd_endpoint,
122123
uint64_t flush_interval_milliseconds,
123124
uintptr_t force_flush_size,
124125
uintptr_t force_drop_size,
@@ -139,4 +140,34 @@ ddog_CharSlice ddog_sidecar_dump(ddog_SidecarTransport **transport);
139140

140141
ddog_CharSlice ddog_sidecar_stats(ddog_SidecarTransport **transport);
141142

143+
ddog_MaybeError ddog_sidecar_dogstatsd_count(ddog_SidecarTransport **transport,
144+
const struct ddog_InstanceId *instance_id,
145+
ddog_CharSlice metric,
146+
int64_t value,
147+
const struct ddog_Vec_Tag *tags);
148+
149+
ddog_MaybeError ddog_sidecar_dogstatsd_distribution(ddog_SidecarTransport **transport,
150+
const struct ddog_InstanceId *instance_id,
151+
ddog_CharSlice metric,
152+
double value,
153+
const struct ddog_Vec_Tag *tags);
154+
155+
ddog_MaybeError ddog_sidecar_dogstatsd_gauge(ddog_SidecarTransport **transport,
156+
const struct ddog_InstanceId *instance_id,
157+
ddog_CharSlice metric,
158+
double value,
159+
const struct ddog_Vec_Tag *tags);
160+
161+
ddog_MaybeError ddog_sidecar_dogstatsd_histogram(ddog_SidecarTransport **transport,
162+
const struct ddog_InstanceId *instance_id,
163+
ddog_CharSlice metric,
164+
double value,
165+
const struct ddog_Vec_Tag *tags);
166+
167+
ddog_MaybeError ddog_sidecar_dogstatsd_set(ddog_SidecarTransport **transport,
168+
const struct ddog_InstanceId *instance_id,
169+
ddog_CharSlice metric,
170+
int64_t value,
171+
const struct ddog_Vec_Tag *tags);
172+
142173
#endif /* DDOG_SIDECAR_H */

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ if test "$PHP_DDTRACE" != "no"; then
144144
ext/configuration.c \
145145
ext/ddshared.c \
146146
ext/distributed_tracing_headers.c \
147+
ext/dogstatsd.c \
147148
ext/dogstatsd_client.c \
148149
ext/engine_api.c \
149150
ext/engine_hooks.c \

config.w32

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ if (PHP_DDTRACE != 'no') {
1515

1616
var version = PHP_VERSION * 100 + PHP_MINOR_VERSION;
1717

18-
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";
18+
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";
1919
if (version >= 800 && version < 802) {
2020
DDTRACE_EXT_SOURCES += " weakrefs.c";
2121
}

ext/auto_flush.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,6 @@ DDTRACE_PUBLIC void ddtrace_close_all_spans_and_flush()
140140
ddtrace_flush_tracer(true, true);
141141
}
142142

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

147145
char *ddtrace_agent_url(void) {

ext/ddtrace.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,91 @@ PHP_FUNCTION(DDTrace_Internal_handle_fork) {
19631963
dd_internal_handle_fork();
19641964
}
19651965

1966+
PHP_FUNCTION(DDTrace_dogstatsd_count) {
1967+
zend_string *metric;
1968+
zend_long value;
1969+
zval *tags = NULL;
1970+
1971+
ZEND_PARSE_PARAMETERS_START(2, 3)
1972+
Z_PARAM_STR(metric)
1973+
Z_PARAM_LONG(value)
1974+
Z_PARAM_OPTIONAL
1975+
Z_PARAM_ARRAY(tags)
1976+
ZEND_PARSE_PARAMETERS_END();
1977+
1978+
ddtrace_sidecar_dogstatsd_count(metric, value, tags);
1979+
1980+
RETURN_NULL();
1981+
}
1982+
1983+
PHP_FUNCTION(DDTrace_dogstatsd_distribution) {
1984+
zend_string *metric;
1985+
double value;
1986+
zval *tags = NULL;
1987+
1988+
ZEND_PARSE_PARAMETERS_START(2, 3)
1989+
Z_PARAM_STR(metric)
1990+
Z_PARAM_DOUBLE(value)
1991+
Z_PARAM_OPTIONAL
1992+
Z_PARAM_ARRAY(tags)
1993+
ZEND_PARSE_PARAMETERS_END();
1994+
1995+
ddtrace_sidecar_dogstatsd_distribution(metric, value, tags);
1996+
1997+
RETURN_NULL();
1998+
}
1999+
2000+
PHP_FUNCTION(DDTrace_dogstatsd_gauge) {
2001+
zend_string *metric;
2002+
double value;
2003+
zval *tags = NULL;
2004+
2005+
ZEND_PARSE_PARAMETERS_START(2, 3)
2006+
Z_PARAM_STR(metric)
2007+
Z_PARAM_DOUBLE(value)
2008+
Z_PARAM_OPTIONAL
2009+
Z_PARAM_ARRAY(tags)
2010+
ZEND_PARSE_PARAMETERS_END();
2011+
2012+
ddtrace_sidecar_dogstatsd_gauge(metric, value, tags);
2013+
2014+
RETURN_NULL();
2015+
}
2016+
2017+
PHP_FUNCTION(DDTrace_dogstatsd_histogram) {
2018+
zend_string *metric;
2019+
double value;
2020+
zval *tags = NULL;
2021+
2022+
ZEND_PARSE_PARAMETERS_START(2, 3)
2023+
Z_PARAM_STR(metric)
2024+
Z_PARAM_DOUBLE(value)
2025+
Z_PARAM_OPTIONAL
2026+
Z_PARAM_ARRAY(tags)
2027+
ZEND_PARSE_PARAMETERS_END();
2028+
2029+
ddtrace_sidecar_dogstatsd_histogram(metric, value, tags);
2030+
2031+
RETURN_NULL();
2032+
}
2033+
2034+
PHP_FUNCTION(DDTrace_dogstatsd_set) {
2035+
zend_string *metric;
2036+
zend_long value;
2037+
zval *tags = NULL;
2038+
2039+
ZEND_PARSE_PARAMETERS_START(2, 3)
2040+
Z_PARAM_STR(metric)
2041+
Z_PARAM_LONG(value)
2042+
Z_PARAM_OPTIONAL
2043+
Z_PARAM_ARRAY(tags)
2044+
ZEND_PARSE_PARAMETERS_END();
2045+
2046+
ddtrace_sidecar_dogstatsd_set(metric, value, tags);
2047+
2048+
RETURN_NULL();
2049+
}
2050+
19662051
PHP_FUNCTION(dd_trace_send_traces_via_thread) {
19672052
char *payload = NULL;
19682053
ddtrace_zpplong_t num_traces = 0;

ext/ddtrace.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,7 @@ extern TSRM_TLS void *ATTR_TLS_GLOBAL_DYNAMIC TSRMLS_CACHE;
159159

160160
#include "random.h"
161161

162+
#define HOST_V6_FORMAT_STR "http://[%s]:%u"
163+
#define HOST_V4_FORMAT_STR "http://%s:%u"
164+
162165
#endif // DDTRACE_H

ext/ddtrace.stub.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,51 @@ function flush(): void {}
632632
* @param list{\CurlHandle, SpanData}[] $array An array which will be populated with curl handles and spans.
633633
*/
634634
function curl_multi_exec_get_request_spans(&$array): void {}
635+
636+
/**
637+
* Update a DogStatsD counter
638+
*
639+
* @param string $metric The metric name
640+
* @param int $value The metric value
641+
* @param array $tags A list of tags associated to the metric
642+
*/
643+
function dogstatsd_count(string $metric, int $value, array $tags = []): void {}
644+
645+
/**
646+
* Update a DogStatsD distribution
647+
*
648+
* @param string $metric The metric name
649+
* @param float $value The metric value
650+
* @param array $tags A list of tags associated to the metric
651+
*/
652+
function dogstatsd_distribution(string $metric, float $value, array $tags = []): void {}
653+
654+
/**
655+
* Update a DogStatsD gauge
656+
*
657+
* @param string $metric The metric name
658+
* @param float $value The metric value
659+
* @param array $tags A list of tags associated to the metric
660+
*/
661+
function dogstatsd_gauge(string $metric, float $value, array $tags = []): void {}
662+
663+
/**
664+
* Update a DogStatsD histogram
665+
*
666+
* @param string $metric The metric name
667+
* @param float $value The metric value
668+
* @param array $tags A list of tags associated to the metric
669+
*/
670+
function dogstatsd_histogram(string $metric, float $value, array $tags = []): void {}
671+
672+
/**
673+
* Update a DogStatsD set
674+
*
675+
* @param string $metric The metric name
676+
* @param int $value The metric value
677+
* @param array $tags A list of tags associated to the metric
678+
*/
679+
function dogstatsd_set(string $metric, int $value, array $tags = []): void {}
635680
}
636681

637682
namespace DDTrace\System {

ext/ddtrace_arginfo.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: cbd454866b5b3f34bee057c9a35d7807c6e718ca */
2+
* Stub hash: 3a83516da1c795bbe41abd106fcc3e069bf3d946 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_trace_method, 0, 3, _IS_BOOL, 0)
55
ZEND_ARG_TYPE_INFO(0, className, IS_STRING, 0)
@@ -128,6 +128,24 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_curl_multi_exec_get_requ
128128
ZEND_ARG_INFO(1, array)
129129
ZEND_END_ARG_INFO()
130130

131+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_dogstatsd_count, 0, 2, IS_VOID, 0)
132+
ZEND_ARG_TYPE_INFO(0, metric, IS_STRING, 0)
133+
ZEND_ARG_TYPE_INFO(0, value, IS_LONG, 0)
134+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tags, IS_ARRAY, 0, "[]")
135+
ZEND_END_ARG_INFO()
136+
137+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_dogstatsd_distribution, 0, 2, IS_VOID, 0)
138+
ZEND_ARG_TYPE_INFO(0, metric, IS_STRING, 0)
139+
ZEND_ARG_TYPE_INFO(0, value, IS_DOUBLE, 0)
140+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tags, IS_ARRAY, 0, "[]")
141+
ZEND_END_ARG_INFO()
142+
143+
#define arginfo_DDTrace_dogstatsd_gauge arginfo_DDTrace_dogstatsd_distribution
144+
145+
#define arginfo_DDTrace_dogstatsd_histogram arginfo_DDTrace_dogstatsd_distribution
146+
147+
#define arginfo_DDTrace_dogstatsd_set arginfo_DDTrace_dogstatsd_count
148+
131149
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_DDTrace_System_container_id, 0, 0, IS_STRING, 1)
132150
ZEND_END_ARG_INFO()
133151

@@ -302,6 +320,11 @@ ZEND_FUNCTION(DDTrace_current_context);
302320
ZEND_FUNCTION(DDTrace_set_distributed_tracing_context);
303321
ZEND_FUNCTION(DDTrace_flush);
304322
ZEND_FUNCTION(DDTrace_curl_multi_exec_get_request_spans);
323+
ZEND_FUNCTION(DDTrace_dogstatsd_count);
324+
ZEND_FUNCTION(DDTrace_dogstatsd_distribution);
325+
ZEND_FUNCTION(DDTrace_dogstatsd_gauge);
326+
ZEND_FUNCTION(DDTrace_dogstatsd_histogram);
327+
ZEND_FUNCTION(DDTrace_dogstatsd_set);
305328
ZEND_FUNCTION(DDTrace_System_container_id);
306329
ZEND_FUNCTION(DDTrace_Config_integration_analytics_enabled);
307330
ZEND_FUNCTION(DDTrace_Config_integration_analytics_sample_rate);
@@ -377,6 +400,11 @@ static const zend_function_entry ext_functions[] = {
377400
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)
378401
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "flush"), zif_DDTrace_flush, arginfo_DDTrace_flush, 0, NULL, NULL)
379402
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)
403+
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_count"), zif_DDTrace_dogstatsd_count, arginfo_DDTrace_dogstatsd_count, 0, NULL, NULL)
404+
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_distribution"), zif_DDTrace_dogstatsd_distribution, arginfo_DDTrace_dogstatsd_distribution, 0, NULL, NULL)
405+
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_gauge"), zif_DDTrace_dogstatsd_gauge, arginfo_DDTrace_dogstatsd_gauge, 0, NULL, NULL)
406+
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_histogram"), zif_DDTrace_dogstatsd_histogram, arginfo_DDTrace_dogstatsd_histogram, 0, NULL, NULL)
407+
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace", "dogstatsd_set"), zif_DDTrace_dogstatsd_set, arginfo_DDTrace_dogstatsd_set, 0, NULL, NULL)
380408
ZEND_RAW_FENTRY(ZEND_NS_NAME("DDTrace\\System", "container_id"), zif_DDTrace_System_container_id, arginfo_DDTrace_System_container_id, 0, NULL, NULL)
381409
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)
382410
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)

ext/dogstatsd.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "dogstatsd.h"
2+
3+
#include "configuration.h"
4+
#include "ddtrace.h"
5+
6+
ZEND_EXTERN_MODULE_GLOBALS(ddtrace);
7+
8+
#define DEFAULT_UDS_PATH "/var/run/datadog/dsd.socket"
9+
10+
char *ddtrace_dogstatsd_url(void) {
11+
zend_string *url = get_DD_DOGSTATSD_URL();
12+
if (ZSTR_LEN(url) > 0) {
13+
return zend_strndup(ZSTR_VAL(url), ZSTR_LEN(url) + 1);
14+
}
15+
16+
zend_string *hostname = get_global_DD_AGENT_HOST();
17+
if (ZSTR_LEN(hostname) > 7 && strncmp(ZSTR_VAL(hostname), "unix://", 7) == 0) {
18+
return zend_strndup(ZSTR_VAL(hostname), ZSTR_LEN(hostname));
19+
}
20+
21+
if (ZSTR_LEN(hostname) > 0) {
22+
bool isIPv6 = memchr(ZSTR_VAL(hostname), ':', ZSTR_LEN(hostname));
23+
24+
int port = atoi(ZSTR_VAL(get_DD_DOGSTATSD_PORT()));
25+
if (port <= 0 || port > 65535) {
26+
port = 8125;
27+
}
28+
char *formatted_url;
29+
asprintf(&formatted_url, isIPv6 ? HOST_V6_FORMAT_STR : HOST_V4_FORMAT_STR, ZSTR_VAL(hostname), (uint32_t)port);
30+
return formatted_url;
31+
}
32+
33+
if (access(DEFAULT_UDS_PATH, F_OK) == SUCCESS) {
34+
return zend_strndup(ZEND_STRL("unix://" DEFAULT_UDS_PATH));
35+
}
36+
37+
int64_t port = get_global_DD_TRACE_AGENT_PORT();
38+
if (port <= 0 || port > 65535) {
39+
port = 8125;
40+
}
41+
char *formatted_url;
42+
asprintf(&formatted_url, HOST_V4_FORMAT_STR, "localhost", (uint32_t)port);
43+
return formatted_url;
44+
}

0 commit comments

Comments
 (0)