Skip to content

Commit cbf2266

Browse files
authored
[loader] Add injection information to phpinfo output for the SSI loader (#3271)
* Add injection information to phpinfo output for the SSI loader * Fixes * Fix test
1 parent e06d45d commit cbf2266

File tree

8 files changed

+364
-75
lines changed

8 files changed

+364
-75
lines changed

loader/compat_php.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,28 +161,28 @@ static void ddloader_php_70_71_zend_error_cb(int type, const char *error_filenam
161161
UNUSED(type);
162162
UNUSED(error_filename);
163163
UNUSED(error_lineno);
164-
ddloader_logv(WARN, format, args);
164+
ddloader_logv(NULL, WARN, format, args);
165165
}
166166

167167
static void ddloader_php_72_73_74_zend_error_cb(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args) {
168168
UNUSED(type);
169169
UNUSED(error_filename);
170170
UNUSED(error_lineno);
171-
ddloader_logv(WARN, format, args);
171+
ddloader_logv(NULL, WARN, format, args);
172172
}
173173

174174
static void ddloader_php_80_error_zend_error_cb(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message) {
175175
UNUSED(type);
176176
UNUSED(error_filename);
177177
UNUSED(error_lineno);
178-
LOG(WARN, "Error while registering the module: %s", ZSTR_VAL(message));
178+
LOG(NULL, WARN, "Error while registering the module: %s", ZSTR_VAL(message));
179179
}
180180

181181
static void ddloader_php_error_zend_error_cb(int type, zend_string *error_filename, const uint32_t error_lineno, zend_string *message) {
182182
UNUSED(type);
183183
UNUSED(error_filename);
184184
UNUSED(error_lineno);
185-
LOG(WARN, "Error while registering the module: %s)", ZSTR_VAL(message));
185+
LOG(NULL, WARN, "Error while registering the module: %s)", ZSTR_VAL(message));
186186
}
187187

188188
void (*old_zend_error_cb)(void);

loader/config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ if test "$PHP_DD_LIBRARY_LOADER" != "no"; then
1818
dnl In case of no dependencies
1919
AC_DEFINE(HAVE_DD_LIBRARY_LOADER, 1, [ Have dd_library_loader support ])
2020

21-
PHP_NEW_EXTENSION(dd_library_loader, dd_library_loader.c compat_php.c, $ext_shared, , , , yes)
21+
PHP_NEW_EXTENSION(dd_library_loader, dd_library_loader.c dd_library_loader_module.c compat_php.c, $ext_shared, , , , yes)
2222
fi

loader/dd_library_loader.c

Lines changed: 109 additions & 57 deletions
Large diffs are not rendered by default.

loader/dd_library_loader_module.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include <php.h>
2+
#include <zend_extensions.h>
3+
#include <php_ini.h>
4+
#include <php_main.h>
5+
#include <php_version.h>
6+
#include <ext/standard/info.h>
7+
8+
#include "php_dd_library_loader.h"
9+
10+
extern injected_ext ddloader_injected_ext_config[];
11+
12+
static void ddloader_info_function(zend_module_entry *module) {
13+
UNUSED(module);
14+
15+
php_info_print_table_start();
16+
php_info_print_table_header(2, "", "Datadog Library Loader");
17+
php_info_print_table_row(2, "Version", PHP_DD_LIBRARY_LOADER_VERSION);
18+
php_info_print_table_row(2, "Author", "Datadog");
19+
php_info_print_table_end();
20+
21+
for (unsigned int i = 0; i < EXT_COUNT; ++i) {
22+
php_info_print_table_start();
23+
php_info_print_table_header(2, "", ddloader_injected_ext_config[i].ext_name);
24+
php_info_print_table_row(2, "Version", ddloader_injected_ext_config[i].version);
25+
php_info_print_table_row(2, "Injection success", ddloader_injected_ext_config[i].injection_success ? "true" : "false");
26+
php_info_print_table_row(2, "Injection error", ddloader_injected_ext_config[i].injection_error ? ddloader_injected_ext_config[i].injection_error : "");
27+
php_info_print_table_row(2, "Extra config", ddloader_injected_ext_config[i].extra_config);
28+
php_info_print_table_row(2, "Logs", ddloader_injected_ext_config[i].logs);
29+
php_info_print_table_end();
30+
}
31+
}
32+
33+
zend_module_entry dd_library_loader_mod = {
34+
STANDARD_MODULE_HEADER,
35+
"dd_library_loader_mod",
36+
NULL, // functions
37+
NULL, // MINIT
38+
NULL, // MSHUTDOWN
39+
NULL, // RINIT
40+
NULL, // RSHUTDOWN
41+
ddloader_info_function, // MINFO
42+
PHP_DD_LIBRARY_LOADER_VERSION, // version
43+
STANDARD_MODULE_PROPERTIES
44+
};

loader/php_dd_library_loader.h

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ typedef enum {
1515
ERROR,
1616
} log_level;
1717

18-
#define LOG(level, format, ...) ddloader_logf(level, format, ##__VA_ARGS__);
19-
20-
void ddloader_logv(log_level level, const char *format, va_list va);
21-
void ddloader_logf(log_level level, const char *format, ...);
18+
#define LOG(config, level, format, ...) ddloader_logf(config, level, format, ##__VA_ARGS__);
2219

2320
typedef enum {
2421
REASON_START,
@@ -29,31 +26,52 @@ typedef enum {
2926
REASON_COMPLETE,
3027
} telemetry_reason;
3128

29+
typedef enum {
30+
EXT_DDTRACE,
31+
EXT_DATADOG_PROFILING,
32+
EXT_DDAPPSEC,
33+
34+
EXT_COUNT,
35+
} dd_injected_ext;
36+
3237
#define TELEMETRY(reason, config, error, format, ...) ddloader_telemetryf(reason, config, error, format, ##__VA_ARGS__);
3338

3439
#define DECLARE_INJECTED_EXT(name, dir, min_version, _pre_load_hook, _pre_minit_hook, deps) \
3540
{ \
3641
.ext_name = name, .ext_dir = dir, .ext_min_version = min_version, .tmp_name = name "_injected", .tmp_deps = deps, \
3742
.pre_load_hook = _pre_load_hook, .pre_minit_hook = _pre_minit_hook, \
3843
.orig_module_startup_func = NULL, .orig_module_deps = NULL, .orig_module_functions = NULL, \
39-
.module_number = -1, .version = NULL \
44+
.module_number = -1, .version = NULL, \
45+
.injection_success = false, .injection_error = NULL, .extra_config = {0}, .logs = {0} \
4046
}
4147

48+
#define MAX_EXTRA_CONFIG_SIZE 1024
49+
#define MAX_LOGS_SIZE 2048
50+
4251
typedef struct _injected_ext {
4352
const char *ext_name;
4453
const char *ext_dir;
4554
unsigned int ext_min_version;
4655

4756
const char *tmp_name;
4857
const zend_module_dep *tmp_deps;
49-
char *(*pre_load_hook)(void);
50-
void (*pre_minit_hook)(void);
58+
char *(*pre_load_hook)(struct _injected_ext *config);
59+
void (*pre_minit_hook)(struct _injected_ext *config);
5160

5261
zend_result (*orig_module_startup_func)(INIT_FUNC_ARGS);
5362
const zend_module_dep *orig_module_deps;
5463
const zend_function_entry *orig_module_functions;
5564
int module_number;
5665
char *version;
66+
67+
// phpinfo data
68+
bool injection_success;
69+
const char *injection_error;
70+
char extra_config[MAX_EXTRA_CONFIG_SIZE];
71+
char logs[MAX_LOGS_SIZE];
5772
} injected_ext;
5873

74+
void ddloader_logv(injected_ext *config, log_level level, const char *format, va_list va);
75+
void ddloader_logf(injected_ext *config, log_level level, const char *format, ...);
76+
5977
#endif /* PHP_DD_LIBRARY_LOADER_H */

loader/tests/functional/fixtures/opcache_jit.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@ function boolstr($bool) {
88

99
if (!extension_loaded('Zend OPcache')) {
1010
echo "OPcache is not loaded\n";
11-
return;
11+
goto end;
1212
}
1313

1414
$status = opcache_get_status();
1515
if ($status === false) {
1616
echo "OPcache is disabled\n";
17-
return;
17+
goto end;
1818
}
1919

2020
echo "opcache_enabled: ".boolstr($status['opcache_enabled'])."\n";
2121
echo "jit.enabled: ".boolstr($status['jit']['enabled'])."\n";
2222
echo "jit.on: ".boolstr($status['jit']['on'])."\n";
2323
echo "jit.buffer_size: ".$status['jit']['buffer_size']."\n";
24+
25+
end:
26+
phpinfo();

loader/tests/functional/test_incompatibility_jit.php

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,24 @@
2121
ddtrace.disable: NO
2222
OPcache is disabled
2323
EOT
24-
],
24+
],
25+
"must_match" => [<<<EOT
26+
%A
27+
dd_library_loader_mod
28+
29+
=> Datadog Library Loader
30+
Version => %s
31+
Author => Datadog
32+
33+
=> ddtrace
34+
Version => %s
35+
Injection success => true
36+
Injection error =>
37+
Extra config => datadog.trace.sources_path=%s/trace/src
38+
39+
%A
40+
EOT
41+
],
2542
],
2643
// OPcache enabled, but not JIT
2744
[
@@ -34,7 +51,24 @@
3451
jit.on: NO
3552
jit.buffer_size: 0
3653
EOT
37-
],
54+
],
55+
"must_match" => [<<<EOT
56+
%A
57+
dd_library_loader_mod
58+
59+
=> Datadog Library Loader
60+
Version => %s
61+
Author => Datadog
62+
63+
=> ddtrace
64+
Version => %s
65+
Injection success => true
66+
Injection error =>
67+
Extra config => datadog.trace.sources_path=%s/trace/src
68+
69+
%A
70+
EOT
71+
],
3872
],
3973
// JIT enabled
4074
[
@@ -49,7 +83,27 @@
4983
jit.on: YES
5084
jit.buffer_size: 33554416
5185
EOT
52-
],
86+
],
87+
"must_match" => [<<<EOT
88+
%A
89+
dd_library_loader_mod
90+
91+
=> Datadog Library Loader
92+
Version => %s
93+
Author => Datadog
94+
95+
=> ddtrace
96+
Version => %s
97+
Injection success => true
98+
Injection error =>
99+
Extra config => datadog.trace.sources_path=%s/trace/src
100+
ddtrace.disable=1
101+
102+
%A
103+
OPcache JIT is enabled and may cause instability. ddtrace will be disabled unless the environment DD_INJECT_FORCE is set to '1', 'true', 'yes' or 'on'
104+
%A
105+
EOT
106+
],
53107
],
54108
// JIT enabled + force injection
55109
[
@@ -64,10 +118,32 @@
64118
jit.enabled: YES
65119
jit.on: YES
66120
jit.buffer_size: 33554416
121+
EOT
122+
,
123+
<<<EOT
67124
[ddtrace] [debug] Notifying profiler of finished local root span.
68125
[ddtrace] [span] Encoding span
69126
EOT
70-
],
127+
],
128+
"must_match" => [<<<EOT
129+
%A
130+
dd_library_loader_mod
131+
132+
=> Datadog Library Loader
133+
Version => %s
134+
Author => Datadog
135+
136+
=> ddtrace
137+
Version => %s
138+
Injection success => true
139+
Injection error =>
140+
Extra config => datadog.trace.sources_path=%s/trace/src
141+
142+
%A
143+
OPcache JIT is enabled and may cause instability. Ignoring as DD_INJECT_FORCE is enabled
144+
%A
145+
EOT
146+
],
71147
],
72148
];
73149
foreach ($tests as $data) {
@@ -83,4 +159,8 @@
83159
foreach ($data['must_not_contain'] as $str) {
84160
assertNotContains($output, $str);
85161
}
162+
163+
foreach ($data['must_match'] as $pattern) {
164+
assertMatchesFormat($output, $pattern);
165+
}
86166
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
require_once __DIR__."/includes/autoload.php";
4+
skip_if_php5();
5+
6+
$output = runCLI('-i', true);
7+
8+
if ('7.0' === php_minor_version()) {
9+
assertMatchesFormat($output, <<<EOT
10+
%A
11+
dd_library_loader_mod
12+
13+
=> Datadog Library Loader
14+
Version => %s
15+
Author => Datadog
16+
17+
=> ddtrace
18+
Version => %s
19+
Injection success => true
20+
Injection error =>
21+
Extra config => datadog.trace.sources_path=%s/trace/src
22+
23+
Logs => Found extension file: %s
24+
%A
25+
Application instrumentation bootstrapping complete ('ddtrace')
26+
%A
27+
28+
=> datadog-profiling
29+
Version =>
30+
Injection success => false
31+
Injection error => Incompatible runtime
32+
Extra config =>
33+
Logs => Aborting application instrumentation due to an incompatible runtime
34+
'datadog-profiling' extension is not supported on this PHP version
35+
%A
36+
37+
=> ddappsec
38+
Version => %s
39+
Injection success => true
40+
Injection error =>
41+
Extra config => datadog.appsec.helper_path=%s
42+
43+
Logs => Found extension file: %s
44+
%A
45+
Application instrumentation bootstrapping complete ('ddappsec')
46+
%A
47+
EOT
48+
);
49+
} else {
50+
assertMatchesFormat($output, <<<EOT
51+
%A
52+
dd_library_loader_mod
53+
54+
=> Datadog Library Loader
55+
Version => %s
56+
Author => Datadog
57+
58+
=> ddtrace
59+
Version => %s
60+
Injection success => true
61+
Injection error =>
62+
Extra config => datadog.trace.sources_path=%s/trace/src
63+
64+
Logs => Found extension file: %s
65+
%A
66+
Application instrumentation bootstrapping complete ('ddtrace')
67+
%A
68+
69+
=> datadog-profiling
70+
Version => %s
71+
Injection success => true
72+
Injection error =>
73+
Extra config => datadog.profiling.enabled=0
74+
75+
Logs => Found extension file: %s
76+
%A
77+
Application instrumentation bootstrapping complete ('datadog-profiling')
78+
%A
79+
80+
=> ddappsec
81+
Version => %s
82+
Injection success => true
83+
Injection error =>
84+
Extra config => datadog.appsec.helper_path=%s
85+
86+
Logs => Found extension file: %s
87+
%A
88+
Application instrumentation bootstrapping complete ('ddappsec')
89+
%A
90+
EOT
91+
);
92+
}

0 commit comments

Comments
 (0)