Skip to content

Commit c582c9f

Browse files
authored
Allow synchronous sidecar flushes and reduce flush limit (#2689)
* Allow synchronous flushes with the sidecar enabled Signed-off-by: Bob Weinand <[email protected]> * Set the sidecar trace force flush limit to 1 MB by default Signed-off-by: Bob Weinand <[email protected]> * Increase size limit two 2 MB and rename config Signed-off-by: Bob Weinand <[email protected]> * Fix unrelated small crash in dd_untrace trace logs Signed-off-by: Bob Weinand <[email protected]> --------- Signed-off-by: Bob Weinand <[email protected]>
1 parent 7557b8a commit c582c9f

11 files changed

+96
-21
lines changed

components-rs/sidecar.h

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ ddog_MaybeError ddog_sidecar_connect(struct ddog_SidecarTransport **connection);
7070

7171
ddog_MaybeError ddog_sidecar_ping(struct ddog_SidecarTransport **transport);
7272

73+
ddog_MaybeError ddog_sidecar_flush_traces(struct ddog_SidecarTransport **transport);
74+
7375
struct ddog_InstanceId *ddog_sidecar_instanceId_build(ddog_CharSlice session_id,
7476
ddog_CharSlice runtime_id);
7577

ext/auto_flush.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ ZEND_RESULT_CODE ddtrace_flush_tracer(bool force_on_startup, bool collect_cycles
6666
.client_computed_top_level = false,
6767
.client_computed_stats = false,
6868
};
69-
ddog_MaybeError send_error = ddog_sidecar_send_trace_v04_shm(&ddtrace_sidecar, ddtrace_sidecar_instance_id, shm, written, &tags);
69+
size_t size_hint = written;
70+
zend_long n_requests = get_global_DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS();
71+
if (n_requests) {
72+
size_hint = MAX(get_global_DD_TRACE_BUFFER_SIZE() / n_requests, size_hint);
73+
}
74+
ddog_MaybeError send_error = ddog_sidecar_send_trace_v04_shm(&ddtrace_sidecar, ddtrace_sidecar_instance_id, shm, size_hint, &tags);
7075
do {
7176
if (send_error.tag == DDOG_OPTION_ERROR_SOME_ERROR) {
7277
// retry sending it directly through the socket as last resort. May block though with large traces.

ext/configuration.c

+32
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "ip_extraction.h"
66
#include "logging.h"
7+
#include "json/json.h"
78
#include <components/log/log.h>
89
#include <zai_string/string.h>
910

@@ -205,3 +206,34 @@ bool ddtrace_config_integration_enabled(ddtrace_integration_name integration_nam
205206

206207
return integration->is_enabled();
207208
}
209+
210+
void ddtrace_change_default_ini(ddtrace_config_id config_id, zai_str str) {
211+
zai_config_memoized_entry *memoized = &zai_config_memoized_entries[config_id];
212+
zend_ini_entry *entry = memoized->ini_entries[0];
213+
zend_string_release(entry->value);
214+
entry->value = zend_string_init(str.ptr, str.len, 1);
215+
if (entry->modified) {
216+
entry->modified = false;
217+
zend_string_release(entry->orig_value);
218+
}
219+
#if ZTS
220+
zend_ini_entry *runtime_entry = zend_hash_find_ptr(EG(ini_directives), entry->name);
221+
if (runtime_entry != entry) {
222+
zend_string_release(runtime_entry->value);
223+
runtime_entry->value = zend_string_copy(entry->value);
224+
if (runtime_entry->modified) {
225+
runtime_entry->modified = false;
226+
zend_string_release(runtime_entry->orig_value);
227+
}
228+
}
229+
#endif
230+
memoized->default_encoded_value = str;
231+
memoized->name_index = -1;
232+
233+
zval decoded;
234+
ZVAL_UNDEF(&decoded);
235+
if (zai_config_decode_value(str, memoized->type, memoized->parser, &decoded, 1)) {
236+
zai_json_dtor_pzval(&memoized->decoded_value);
237+
ZVAL_COPY_VALUE(&memoized->decoded_value, &decoded);
238+
}
239+
}

ext/configuration.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ enum ddtrace_sampling_rules_format {
4747
/* This should be at least an order of magnitude higher than the userland HTTP Transport default. */
4848
#define DD_TRACE_BGS_TIMEOUT_VAL 5000
4949

50+
#define DD_TRACE_AGENT_FLUSH_INTERVAL_VAL 1001
51+
5052
#define DD_INTEGRATION_ANALYTICS_ENABLED_DEFAULT false
5153
#define DD_INTEGRATION_ANALYTICS_SAMPLE_RATE_DEFAULT 1
5254

@@ -153,8 +155,9 @@ enum ddtrace_sampling_rules_format {
153155
.ini_change = zai_config_system_ini_change) \
154156
CONFIG(INT, DD_TRACE_BGS_TIMEOUT, DD_CFG_EXPSTR(DD_TRACE_BGS_TIMEOUT_VAL), \
155157
.ini_change = zai_config_system_ini_change) \
156-
CONFIG(INT, DD_TRACE_AGENT_FLUSH_INTERVAL, "5000", .ini_change = zai_config_system_ini_change) \
157-
CONFIG(INT, DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS, "10") \
158+
CONFIG(INT, DD_TRACE_AGENT_FLUSH_INTERVAL, DD_CFG_EXPSTR(DD_TRACE_AGENT_FLUSH_INTERVAL_VAL), \
159+
.ini_change = zai_config_system_ini_change) \
160+
CONFIG(INT, DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS, "0") \
158161
CONFIG(INT, DD_TRACE_SHUTDOWN_TIMEOUT, "5000", .ini_change = zai_config_system_ini_change) \
159162
CONFIG(BOOL, DD_TRACE_STARTUP_LOGS, "true") \
160163
CONFIG(BOOL, DD_TRACE_ONCE_LOGS, "true") \
@@ -171,6 +174,7 @@ enum ddtrace_sampling_rules_format {
171174
CONFIG(CUSTOM(STRING), DD_TRACE_CLIENT_IP_HEADER, "", .parser = ddtrace_parse_client_ip_header_config) \
172175
CONFIG(BOOL, DD_TRACE_FORKED_PROCESS, "true") \
173176
CONFIG(INT, DD_TRACE_HOOK_LIMIT, "100") \
177+
CONFIG(INT, DD_TRACE_BUFFER_SIZE, "2097152", .ini_change = zai_config_system_ini_change) \
174178
CONFIG(INT, DD_TRACE_AGENT_MAX_PAYLOAD_SIZE, "52428800", .ini_change = zai_config_system_ini_change) \
175179
CONFIG(INT, DD_TRACE_AGENT_STACK_INITIAL_SIZE, "131072", .ini_change = zai_config_system_ini_change) \
176180
CONFIG(INT, DD_TRACE_AGENT_STACK_BACKLOG, "12", .ini_change = zai_config_system_ini_change) \
@@ -252,4 +256,6 @@ static inline int ddtrace_quiet_zpp(void) {
252256
return PHP_DEBUG ? 0 : ZEND_PARSE_PARAMS_QUIET;
253257
}
254258

259+
void ddtrace_change_default_ini(ddtrace_config_id config_id, zai_str str);
260+
255261
#endif // DD_CONFIGURATION_H

ext/ddtrace.c

+38-10
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,8 @@ static PHP_MSHUTDOWN_FUNCTION(ddtrace) {
11861186
return SUCCESS;
11871187
}
11881188

1189+
static bool dd_rinit_once_done = false;
1190+
11891191
static void dd_rinit_once(void) {
11901192
/* The env vars are memoized on MINIT before the SAPI env vars are available.
11911193
* We use the first RINIT to bust the env var cache and use the SAPI env vars.
@@ -1197,9 +1199,19 @@ static void dd_rinit_once(void) {
11971199
#ifndef _WIN32
11981200
ddtrace_signals_first_rinit();
11991201
if (!get_global_DD_TRACE_SIDECAR_TRACE_SENDER()) {
1202+
if (get_global_DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS() == 0) {
1203+
// Set the default to 10 so that BGS flushes faster. With sidecar it's not needed generally.
1204+
ddtrace_change_default_ini(DDTRACE_CONFIG_DD_TRACE_AGENT_FLUSH_AFTER_N_REQUESTS, (zai_str) ZAI_STR_FROM_CSTR("10"));
1205+
}
1206+
if (get_DD_TRACE_AGENT_FLUSH_INTERVAL() == DD_TRACE_AGENT_FLUSH_INTERVAL_VAL) {
1207+
// Set the default to 5000 so that BGS does not flush too often. The sidecar can flush more often, but the BGS is per process. Keep it higher to avoid too much load on the agent.
1208+
ddtrace_change_default_ini(DDTRACE_CONFIG_DD_TRACE_AGENT_FLUSH_INTERVAL, (zai_str) ZAI_STR_FROM_CSTR("5000"));
1209+
}
12001210
ddtrace_coms_init_and_start_writer();
12011211
}
12021212
#endif
1213+
1214+
dd_rinit_once_done = true;
12031215
}
12041216

12051217
static pthread_once_t dd_rinit_once_control = PTHREAD_ONCE_INIT;
@@ -2143,6 +2155,22 @@ PHP_FUNCTION(dd_trace_internal_fn) {
21432155
ddog_CharSlice slice = ddog_sidecar_stats(&ddtrace_sidecar);
21442156
RETVAL_STRINGL(slice.ptr, slice.len);
21452157
free((void *) slice.ptr);
2158+
} else if (FUNCTION_NAME_MATCHES("synchronous_flush")) {
2159+
uint32_t timeout = 100;
2160+
if (params_count == 1) {
2161+
timeout = Z_LVAL_P(ZVAL_VARARG_PARAM(params, 0));
2162+
}
2163+
#ifndef _WIN32
2164+
if (!get_global_DD_TRACE_SIDECAR_TRACE_SENDER()) {
2165+
if (dd_rinit_once_done) {
2166+
ddtrace_coms_synchronous_flush(timeout);
2167+
}
2168+
} else
2169+
#endif
2170+
if (ddtrace_sidecar) {
2171+
ddog_sidecar_flush_traces(&ddtrace_sidecar);
2172+
}
2173+
RETVAL_TRUE;
21462174
#ifndef _WIN32
21472175
} else if (FUNCTION_NAME_MATCHES("init_and_start_writer")) {
21482176
RETVAL_BOOL(ddtrace_coms_init_and_start_writer());
@@ -2176,13 +2204,6 @@ PHP_FUNCTION(dd_trace_internal_fn) {
21762204
} else if (FUNCTION_NAME_MATCHES("test_msgpack_consumer")) {
21772205
ddtrace_coms_test_msgpack_consumer();
21782206
RETVAL_TRUE;
2179-
} else if (FUNCTION_NAME_MATCHES("synchronous_flush")) {
2180-
uint32_t timeout = 100;
2181-
if (params_count == 1) {
2182-
timeout = Z_LVAL_P(ZVAL_VARARG_PARAM(params, 0));
2183-
}
2184-
ddtrace_coms_synchronous_flush(timeout);
2185-
RETVAL_TRUE;
21862207
#endif
21872208
} else if (FUNCTION_NAME_MATCHES("test_logs")) {
21882209
ddog_logf(DDOG_LOG_WARN, false, "foo");
@@ -2244,9 +2265,9 @@ PHP_FUNCTION(dd_trace_close_all_spans_and_flush) {
22442265

22452266
/* {{{ proto void dd_trace_synchronous_flush(int) */
22462267
PHP_FUNCTION(dd_trace_synchronous_flush) {
2247-
zend_long timeout;
2268+
zend_long timeout = 100;
22482269

2249-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &timeout) == FAILURE) {
2270+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &timeout) == FAILURE) {
22502271
RETURN_THROWS();
22512272
}
22522273

@@ -2257,8 +2278,15 @@ PHP_FUNCTION(dd_trace_synchronous_flush) {
22572278
}
22582279

22592280
#ifndef _WIN32
2260-
ddtrace_coms_synchronous_flush(timeout);
2281+
if (!get_global_DD_TRACE_SIDECAR_TRACE_SENDER()) {
2282+
if (dd_rinit_once_done) {
2283+
ddtrace_coms_synchronous_flush(timeout);
2284+
}
2285+
} else
22612286
#endif
2287+
if (ddtrace_sidecar) {
2288+
ddog_sidecar_flush_traces(&ddtrace_sidecar);
2289+
}
22622290
RETURN_NULL();
22632291
}
22642292

ext/ddtrace.stub.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -1033,12 +1033,12 @@ function dd_trace_method(
10331033
* @param string|null $className In the case of a method, its respective class should be provided as well
10341034
* @return bool 'true' if the un-tracing process was successful, else 'false'
10351035
*/
1036-
function dd_untrace(string $functionName, string $className = null): bool {}
1036+
function dd_untrace(string $functionName, string|null $className = null): bool {}
10371037

10381038
/**
10391039
* Blocking-call synchronously flushing all spans to the agent
10401040
*
10411041
* @param int $timeout Timeout in milliseconds to wait for the flush to complete
10421042
*/
1043-
function dd_trace_synchronous_flush(int $timeout): void {}
1043+
function dd_trace_synchronous_flush(int $timeout = 100): void {}
10441044
}

ext/ddtrace_arginfo.h

+4-4
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: 3a83516da1c795bbe41abd106fcc3e069bf3d946 */
2+
* Stub hash: 190a99779c21033f0812df6365a7ebdd87057727 */
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)
@@ -264,11 +264,11 @@ ZEND_END_ARG_INFO()
264264

265265
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dd_untrace, 0, 1, _IS_BOOL, 0)
266266
ZEND_ARG_TYPE_INFO(0, functionName, IS_STRING, 0)
267-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, className, IS_STRING, 0, "null")
267+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, className, IS_STRING, 1, "null")
268268
ZEND_END_ARG_INFO()
269269

270-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dd_trace_synchronous_flush, 0, 1, IS_VOID, 0)
271-
ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0)
270+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dd_trace_synchronous_flush, 0, 0, IS_VOID, 0)
271+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeout, IS_LONG, 0, "100")
272272
ZEND_END_ARG_INFO()
273273

274274
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DDTrace_SpanLink_jsonSerialize, 0, 0, IS_MIXED, 0)

ext/hook/uhook_legacy.c

+1
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ PHP_FUNCTION(dd_untrace) {
433433
LOG(HOOK_TRACE, "Removing all hook functions installed by hook&trace_%s at %s:%d on %s %s%s%s",
434434
class_name ? "method" : "function",
435435
zend_get_executed_filename(), zend_get_executed_lineno(),
436+
class_name ? "method" : "function",
436437
class_name ? ZSTR_VAL(class_name) : "",
437438
class_name ? "::" : "",
438439
ZSTR_VAL(method_name));

ext/sidecar.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ ddog_SidecarTransport *dd_sidecar_connection_factory(void) {
7070
ddog_CharSlice session_id = (ddog_CharSlice) {.ptr = (char *) dd_sidecar_formatted_session_id, .len = sizeof(dd_sidecar_formatted_session_id)};
7171
ddog_sidecar_session_set_config(&sidecar_transport, session_id, ddtrace_endpoint, dogstatsd_endpoint,
7272
get_global_DD_TRACE_AGENT_FLUSH_INTERVAL(),
73-
get_global_DD_TRACE_AGENT_MAX_PAYLOAD_SIZE() * get_DD_TRACE_BETA_HIGH_MEMORY_PRESSURE_PERCENT() / 100,
73+
get_global_DD_TRACE_BUFFER_SIZE(),
7474
get_global_DD_TRACE_AGENT_STACK_BACKLOG() * get_global_DD_TRACE_AGENT_MAX_PAYLOAD_SIZE(),
7575
get_global_DD_TRACE_DEBUG() ? DDOG_CHARSLICE_C("debug") : dd_zend_string_to_CharSlice(get_global_DD_TRACE_LOG_LEVEL()),
7676
(ddog_CharSlice){ .ptr = logpath, .len = strlen(logpath) });

package.xml

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ This changeset is on top of 1.0.0beta1.
9696
- Link libpthread into the spawn_worker trampoline Datadog/libdatadog#452
9797
- Make use of the sidecar thread safe #2671
9898
- Send a correct size hint to the sidecar trace flusher #2686
99+
- Allow synchronous sidecar flushes and reduce flush limit #2689
99100
100101
### Internal
101102
- Update to maintain compatibility with libdatadog #2634, #2661

0 commit comments

Comments
 (0)