-
Notifications
You must be signed in to change notification settings - Fork 182
Expand file tree
/
Copy pathdatadog.h
More file actions
510 lines (394 loc) · 23.2 KB
/
Copy pathdatadog.h
File metadata and controls
510 lines (394 loc) · 23.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
struct _zend_string;
#ifndef DDTRACE_PHP_H
#define DDTRACE_PHP_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "common.h"
#include "telemetry.h"
#include "sidecar.h"
extern ddog_Uuid datadog_runtime_id;
extern ddog_Uuid datadog_session_id;
extern uint8_t datadog_formatted_session_id[36];
extern uint8_t datadog_formatted_root_session_id[36];
extern uint8_t datadog_formatted_parent_session_id[36];
extern void (*ddog_log_callback)(ddog_CharSlice);
extern ddog_VecRemoteConfigProduct DATADOG_REMOTE_CONFIG_PRODUCTS;
extern ddog_VecRemoteConfigCapabilities DATADOG_REMOTE_CONFIG_CAPABILITIES;
extern const uint8_t *DDOG_PHP_FUNCTION;
/**
* # Safety
* Must be called from a single-threaded context, such as MINIT or first rinit.
*/
void datadog_generate_runtime_id(void);
/**
* # Safety
* Must be called from a single-threaded context, such as MINIT.
*/
void datadog_generate_session_id(void);
void datadog_format_runtime_id(uint8_t (*buf)[36]);
ddog_CharSlice ddtrace_get_container_id(void);
void ddtrace_set_container_cgroup_path(ddog_CharSlice path);
char *ddtrace_strip_invalid_utf8(const char *input, uintptr_t *len);
void ddtrace_drop_rust_string(char *input, uintptr_t len);
struct ddog_Endpoint *datadog_parse_agent_url(ddog_CharSlice url);
struct ddog_Endpoint *datadog_otel_metrics_endpoint_from_url(ddog_CharSlice url);
struct ddog_Endpoint *datadog_otel_metrics_endpoint_from_agent_url(ddog_CharSlice url);
/**
* Initialize crashtracking, selecting the receiver strategy for this process:
* - Linux, sidecar host (`master_pid == getpid()`): the in-process thread-mode sidecar can't
* serve its own crash, so spawn a fork+exec subprocess receiver (like the standalone daemon),
* resolving frames there since a crashing process can't reliably symbolize itself.
* - Linux, worker/collector: connect to the sidecar IPC socket and upgrade it to a crashtracker
* receiver on crash (`SOCK_SEQPACKET` + `enter_crashtracker_receiver`), streaming the report
* over that single socket and resolving frames in-process.
* - other unix (macOS): no sidecar upgrade; the default connector reaches the socket path.
*
* `master_pid` is the thread-mode master listener PID (0 if none): it keys the IPC socket and, on
* Linux, distinguishes the host from a worker.
*
* # Safety
* `endpoint` must point to a valid `Endpoint`; `metadata`'s borrowed strings/tags must outlive the
* call (they are copied into owned storage before it returns).
*/
ddog_MaybeError datadog_crashtracker_init(const struct ddog_Endpoint *endpoint,
ddog_crasht_Metadata metadata,
int32_t master_pid);
ddog_Configurator *ddog_library_configurator_new_dummy(bool debug_logs, ddog_CharSlice language);
int posix_spawn_file_actions_addchdir_np(void *file_actions, const char *path);
uint64_t dd_fnv1a_64(const uint8_t *data, uintptr_t len);
const char *ddog_normalize_process_tag_value(ddog_CharSlice tag_value);
void ddog_free_normalized_tag_value(const char *ptr);
/**
* Read all agent /info data in one SHM read and apply env, container-hash and concentrator
* config atomically.
*
* Fills `env_out` with the agent's `config.default_env` (zero-length slice if absent).
* Fills `container_hash_out` with `container_tags_hash` (zero-length slice if absent).
* Both slices borrow from the reader's cached info — valid until the next `reader.read()`.
*
* Concentrator config (peer tags, span kinds, trace filters) is applied only when the
* SHM has changed since the last read (`changed == true`). Calling this once at RINIT
* ensures the config is always applied before the first span is processed, so the
* per-span `ddog_apply_agent_info_concentrator_config` can safely rely on `changed` alone.
*
* # Safety
* `reader` must be a valid pointer to an `AgentInfoReader`.
*/
void ddog_apply_agent_info(struct ddog_AgentInfoReader *reader,
ddog_CharSlice *env_out,
ddog_CharSlice *container_hash_out);
/**
* Serialize the current cached agent info as a JSON string.
* Returns NULL if no info has been read yet.
* The returned pointer must be freed with `ddog_agent_info_json_free`.
*/
char *ddog_agent_info_as_json(struct ddog_AgentInfoReader *reader);
void ddog_agent_info_json_free(char *ptr);
/**
* Returns true when the agent /info `endpoints` list advertises `endpoint`
* (e.g. `/v1.0/traces`). Returns false when no info has been received yet, so the
* caller safely treats "agent info unknown" as "endpoint not advertised".
*
* # Safety
* `reader` must be a valid pointer to an `AgentInfoReader`.
*/
bool ddog_agent_info_has_endpoint(struct ddog_AgentInfoReader *reader, ddog_CharSlice endpoint);
/**
* Apply concentrator config changes from the agent /info SHM.
*
* Cheap no-op when the SHM has not changed (`changed == false`). Only applies when
* new data has arrived mid-request — `ddog_apply_agent_info` at RINIT guarantees the
* initial configuration is already in place, so `changed` alone is sufficient here.
*
* # Safety
* `reader` must be a valid pointer to an `AgentInfoReader`.
*/
void ddog_apply_agent_info_concentrator_config(struct ddog_AgentInfoReader *reader);
bool ddog_ffe_load_config(ddog_CharSlice json);
bool ddog_ffe_has_config(void);
uint64_t ddog_ffe_config_version(void);
struct ddog_FfeResult ddog_ffe_evaluate(ddog_CharSlice flag_key,
int32_t expected_type,
ddog_CharSlice targeting_key,
const struct ddog_FfeAttribute *attributes,
uintptr_t attributes_count);
bool ddog_shall_log(enum ddog_Log category);
void ddog_set_error_log_level(bool once);
void ddog_set_log_level(ddog_CharSlice level, bool once);
void ddog_log(enum ddog_Log category, bool once, ddog_CharSlice msg);
void ddog_reset_logger(void);
uint32_t ddog_get_logs_count(ddog_CharSlice level);
void ddog_init_remote_config(struct ddog_RemoteConfigFlags flags);
struct ddog_RemoteConfigState *ddog_init_remote_config_state(const struct ddog_Endpoint *endpoint,
bool di_enabled);
uint64_t ddog_remote_config_current_generation(const struct ddog_RemoteConfigState *remote_config);
const char *ddog_remote_config_get_path(const struct ddog_RemoteConfigState *remote_config);
bool ddog_process_remote_configs(struct ddog_RemoteConfigState *remote_config);
/**
* Returns all loaded remote config entries as a JSON object:
* { "config_id": "content_summary", ... }
* For live debugger entries the value is the probe ID (or "service_config").
* For dynamic config entries the value is "apm_tracing".
* The returned pointer must be freed with `ddog_remote_config_loaded_configs_free`.
*/
char *ddog_remote_config_get_loaded_configs(const struct ddog_RemoteConfigState *remote_config);
void ddog_remote_config_loaded_configs_free(char *ptr);
bool ddog_type_can_be_instrumented(const struct ddog_RemoteConfigState *remote_config,
ddog_CharSlice typename_);
bool ddog_global_log_probe_limiter_inc(const struct ddog_RemoteConfigState *remote_config);
struct ddog_Vec_CChar *ddog_CharSlice_to_owned(ddog_CharSlice str);
bool ddog_remote_configs_service_env_change(struct ddog_RemoteConfigState *remote_config,
ddog_CharSlice service,
ddog_CharSlice env,
ddog_CharSlice version,
const struct ddog_Vec_Tag *tags,
const struct ddog_Vec_Tag *process_tags);
bool ddog_remote_config_alter_dynamic_config(struct ddog_RemoteConfigState *remote_config,
ddog_CharSlice config,
ddog_OwnedZendString new_value);
void ddog_setup_remote_config(ddog_DynamicConfigUpdate update_config,
const struct ddog_LiveDebuggerSetup *setup);
/**
* Enable or disable dynamic instrumentation.
* When disabling: all installed probe hooks are removed (but kept in `active` for reinstallation).
* When enabling: all probes in `active` that have no installed hook are (re-)installed.
*/
void ddog_set_dynamic_instrumentation_enabled(struct ddog_RemoteConfigState *remote_config,
bool enabled);
void ddog_rshutdown_remote_config(struct ddog_RemoteConfigState *remote_config);
void ddog_shutdown_remote_config(struct ddog_RemoteConfigState*);
/**
* Free the FFI-owned allocations in a `Probe` (the `tags` vec and the nested
* span-decoration / log allocations) by consuming it; borrowed `CharSlice`s are
* left untouched. Called from `dd_probe_dtor` when a probe is uninstalled.
*/
void ddog_drop_probe(struct ddog_Probe);
void ddog_log_debugger_data(const struct ddog_Vec_DebuggerPayload *payloads);
void ddog_log_debugger_datum(const struct ddog_DebuggerPayload *payload);
ddog_MaybeError ddog_send_debugger_diagnostics(const struct ddog_RemoteConfigState *remote_config_state,
struct ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
ddog_QueueId queue_id,
const struct ddog_Probe *probe,
uint64_t timestamp);
void ddog_sidecar_enable_appsec(ddog_CharSlice shared_lib_path,
ddog_CharSlice socket_file_path,
ddog_CharSlice lock_file_path,
ddog_CharSlice log_file_path,
ddog_CharSlice log_level);
ddog_MaybeError ddog_sidecar_connect_php(struct ddog_SidecarTransport **connection,
const char *error_path,
ddog_CharSlice log_level,
bool enable_telemetry,
void (*on_reconnect)(struct ddog_SidecarTransport*),
const struct ddog_Endpoint *crashtracker_endpoint,
uint64_t backpressure_bytes,
uint64_t backpressure_queue);
void datadog_sidecar_reconnect(struct ddog_SidecarTransport **transport,
struct ddog_SidecarTransport *(*factory)(void));
bool ddog_shm_limiter_inc(const struct ddog_MaybeShmLimiter *limiter, uint32_t limit);
bool ddog_exception_hash_limiter_inc(struct ddog_SidecarTransport *connection,
uint64_t hash,
uint32_t granularity_seconds);
/**
* Returns true once the agent /info has been received and applied.
* Used by the PHP extension to skip stats computation until the concentrator
* has been properly initialised with peer-tag keys and span kinds.
*/
bool ddog_is_agent_info_ready(void);
/**
* Returns true when the agent supports client-side stats computation:
* agent info has been received, `client_drop_p0s` is true, and the reported
* agent version is >= 7.65.0.
*/
bool ddog_agent_has_stats_computation(void);
/**
* Look up (or lazily create) the concentrator for `(env, version, service)` and invoke
* `callback` with a shared reference to it while holding the global read lock.
*
* The callback is **always** invoked — even before the sidecar has created the backing SHM.
* When the SHM is not yet available a *virtual* concentrator is used: peer-tag keys and
* span-kinds come from `DESIRED_CONFIG` so eligibility and peer-tag extraction still work
* correctly. The C callback should call `ddog_span_concentrator_has_shm` to decide whether to
* write to the SHM (real concentrator) or store the stats for the IPC path (virtual).
*
* A virtual concentrator is always considered stale so it will be transparently upgraded to a
* real one on the next call once the sidecar has created the SHM.
*
* Returns `true` after the callback returns, `false` only on an internal locking error.
*
* # Safety
* `env`, `version`, and `service` must be valid `CharSlice`s. `callback` must be a valid
* function pointer. `userdata` is forwarded to `callback` as-is.
*/
bool ddog_span_concentrator_with(ddog_CharSlice env,
ddog_CharSlice version,
ddog_CharSlice service,
void (*callback)(const struct ddog_SpanConcentrator*, void*),
void *userdata);
/**
* Returns `true` when the concentrator is backed by a real SHM and
* `ddog_span_concentrator_add_php_span` will actually persist data.
* Returns `false` for virtual concentrators (SHM not yet available) — the C callback should
* store the stats for the IPC fallback path in that case.
*/
bool ddog_span_concentrator_has_shm(const struct ddog_SpanConcentrator *c);
/**
* Return a pointer to the concentrator's peer-tag-key array and write the count to `*out_count`.
*
* The returned pointer is valid for the lifetime of the guard passed to this call.
* May return null when there are no peer tag keys.
*/
const ddog_CharSlice *ddog_span_concentrator_peer_tag_keys(const struct ddog_SpanConcentrator *c,
uintptr_t *out_count);
/**
* Add a PHP span to the concentrator for stats computation.
*
* Fast eligibility pre-check: returns true if a span with these attributes would be accepted
* by `ddog_span_concentrator_add_php_span`.
*
* Call this before constructing the full `PhpSpanStats`. If it returns false, skip the span
* entirely. If it returns true, fill the remaining fields and call `add_php_span`.
*/
bool ddog_span_concentrator_is_eligible(const struct ddog_SpanConcentrator *c,
bool has_top_level,
bool is_measured,
ddog_CharSlice span_kind,
bool is_partial_snapshot);
/**
* Write a PHP span to the concentrator's backing SHM.
*
* Only valid when `ddog_span_concentrator_has_shm` returns `true`. For virtual concentrators
* (no SHM) the caller should use the IPC path instead.
*
* All `CharSlice` fields in `span` (and in the `peer_tags` array it points to) must remain valid
* for the duration of this call.
*
* # Safety
* `span` must point to a valid `PhpSpanStats`. The concentrator must have a backing SHM
* (`ddog_span_concentrator_has_shm` returns `true`).
*/
void ddog_span_concentrator_add_php_span(const struct ddog_SpanConcentrator *c,
const struct ddog_PhpSpanStats *span);
/**
* IPC fallback: send a PHP span directly to the sidecar's SHM concentrator for (env, version).
*
* Called when the SHM is not yet available. The sidecar processes IPC messages sequentially,
* and `set_universal_service_tags` is always sent before this message, so the concentrator
* is guaranteed to exist when the sidecar handles this call. The sidecar resolves the service
* dimension from the session's `DD_SERVICE` config.
*
* # Safety
* All pointers must be valid.
*/
void ddog_sidecar_add_php_span_to_concentrator(struct ddog_SidecarTransport **transport,
ddog_CharSlice env,
ddog_CharSlice version,
const struct ddog_PhpSpanStats *span);
bool ddtrace_detect_composer_installed_json(struct ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
const ddog_QueueId *queue_id,
ddog_CharSlice path);
struct ddog_SidecarActionsBuffer *ddog_sidecar_telemetry_buffer_alloc(void);
void ddog_sidecar_telemetry_buffer_drop(struct ddog_SidecarActionsBuffer*);
void ddog_sidecar_telemetry_addIntegration_buffer(struct ddog_SidecarActionsBuffer *buffer,
ddog_CharSlice integration_name,
ddog_CharSlice integration_version,
bool integration_enabled);
void ddog_sidecar_telemetry_addDependency_buffer(struct ddog_SidecarActionsBuffer *buffer,
ddog_CharSlice dependency_name,
ddog_CharSlice dependency_version);
/**
* Enqueues an endpoint into a telemetry actions buffer (to be sent via ddog_sidecar_telemetry_buffer_flush).
*/
void ddog_sidecar_telemetry_addEndpoint_buffer(struct ddog_SidecarActionsBuffer *buffer,
enum ddog_Method method,
ddog_CharSlice path,
ddog_CharSlice operation_name,
ddog_CharSlice resource_name);
void ddog_sidecar_telemetry_enqueueConfig_buffer(struct ddog_SidecarActionsBuffer *buffer,
ddog_CharSlice config_key,
ddog_CharSlice config_value,
enum ddog_ConfigurationOrigin origin,
ddog_CharSlice config_id);
ddog_MaybeError ddog_sidecar_telemetry_buffer_flush(struct ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
const ddog_QueueId *queue_id,
struct ddog_SidecarActionsBuffer *buffer);
ddog_MaybeError ddog_sidecar_telemetry_register_metric(struct ddog_SidecarTransport **transport,
ddog_CharSlice metric_name,
enum ddog_MetricType metric_type,
enum ddog_MetricNamespace namespace_);
void ddog_sidecar_telemetry_add_span_metric_point_buffer(struct ddog_SidecarActionsBuffer *buffer,
ddog_CharSlice metric_name,
double metric_value,
ddog_CharSlice tags);
void ddog_sidecar_telemetry_add_integration_log_buffer(enum ddog_Log category,
struct ddog_SidecarActionsBuffer *buffer,
ddog_CharSlice log);
ddog_ShmCacheMap *ddog_sidecar_telemetry_cache_new(void);
void ddog_sidecar_telemetry_cache_drop(ddog_ShmCacheMap*);
bool ddog_sidecar_telemetry_config_sent(ddog_ShmCacheMap *cache,
ddog_CharSlice service,
ddog_CharSlice env);
ddog_MaybeError ddog_sidecar_telemetry_filter_flush(struct ddog_SidecarTransport **transport,
const struct ddog_InstanceId *instance_id,
const ddog_QueueId *queue_id,
struct ddog_SidecarActionsBuffer *buffer,
ddog_ShmCacheMap *cache,
ddog_CharSlice service,
ddog_CharSlice env);
bool ddog_sidecar_telemetry_are_endpoints_collected(ddog_ShmCacheMap *cache,
ddog_CharSlice service,
ddog_CharSlice env);
/**
* Check whether the trace rooted at `resource` / `root_span` passes all configured trace
* filters (filter_tags, filter_tags_regex, ignore_resources from agent /info).
*
* Returns `true` to include in the pipeline, `false` to drop the entire trace (no sending,
* no stats). Filters are evaluated against the root span — the decision applies uniformly
* to all spans of the trace.
*
* * **When configured**: `filter_tags` and `filter_tags_regex` entries — one
* `lookup_fn` call per filter entry.
* * **Fast path**: returns `true` immediately when no filters are configured.
*/
bool ddog_check_stats_trace_filter(ddog_CharSlice resource,
const void *root_span,
ddog_RootTagLookupFn lookup_fn);
void ddog_init_span_func(void (*free_func)(ddog_OwnedZendString),
void (*addref_func)(struct _zend_string*),
ddog_OwnedZendString (*init_func)(ddog_CharSlice));
void ddog_set_span_service_zstr(ddog_SpanBytes *ptr, struct _zend_string *str);
void ddog_set_span_name_zstr(ddog_SpanBytes *ptr, struct _zend_string *str);
void ddog_set_span_resource_zstr(ddog_SpanBytes *ptr, struct _zend_string *str);
void ddog_set_span_type_zstr(ddog_SpanBytes *ptr, struct _zend_string *str);
void ddog_add_span_meta_zstr(ddog_SpanBytes *ptr,
struct _zend_string *key,
struct _zend_string *val);
void ddog_add_CharSlice_span_meta_zstr(ddog_SpanBytes *ptr,
ddog_CharSlice key,
struct _zend_string *val);
void ddog_add_zstr_span_meta_str(ddog_SpanBytes *ptr, struct _zend_string *key, const char *val);
void ddog_add_str_span_meta_str(ddog_SpanBytes *ptr, const char *key, const char *val);
void ddog_add_str_span_meta_zstr(ddog_SpanBytes *ptr, const char *key, struct _zend_string *val);
void ddog_add_str_span_meta_CharSlice(ddog_SpanBytes *ptr, const char *key, ddog_CharSlice val);
void ddog_del_span_meta_zstr(ddog_SpanBytes *ptr, struct _zend_string *key);
void ddog_del_span_meta_str(ddog_SpanBytes *ptr, const char *key);
bool ddog_has_span_meta_zstr(ddog_SpanBytes *ptr, struct _zend_string *key);
bool ddog_has_span_meta_str(ddog_SpanBytes *ptr, const char *key);
ddog_CharSlice ddog_get_span_meta_str(ddog_SpanBytes *span, const char *key);
void ddog_add_span_metrics_zstr(ddog_SpanBytes *ptr, struct _zend_string *key, double val);
bool ddog_has_span_metrics_zstr(ddog_SpanBytes *ptr, struct _zend_string *key);
void ddog_del_span_metrics_zstr(ddog_SpanBytes *ptr, struct _zend_string *key);
void ddog_add_span_metrics_str(ddog_SpanBytes *ptr, const char *key, double val);
bool ddog_get_span_metrics_str(ddog_SpanBytes *ptr, const char *key, double *result);
void ddog_del_span_metrics_str(ddog_SpanBytes *ptr, const char *key);
void ddog_add_span_meta_struct_zstr(ddog_SpanBytes *ptr,
struct _zend_string *key,
struct _zend_string *val);
void ddog_add_zstr_span_meta_struct_CharSlice(ddog_SpanBytes *ptr,
struct _zend_string *key,
ddog_CharSlice val);
#endif /* DDTRACE_PHP_H */