-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathphp_apm.h
375 lines (330 loc) · 11.6 KB
/
php_apm.h
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
/*
+----------------------------------------------------------------------+
| APM stands for Alternative PHP Monitor |
+----------------------------------------------------------------------+
| Copyright (c) 2008-2014 Davide Mendolia, Patrick Allaert |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Patrick Allaert <patrickallaert@php.net> |
+----------------------------------------------------------------------+
*/
#ifndef PHP_APM_H
#define PHP_APM_H
#define PHP_APM_VERSION "2.1.2"
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "php.h"
#include "zend_errors.h"
#if PHP_VERSION_ID >= 70000
# include "zend_smart_str.h"
#else
# include "ext/standard/php_smart_str.h"
#endif
#ifndef E_EXCEPTION
# define E_EXCEPTION (1<<15L)
#endif
#ifdef APM_DRIVER_SQLITE3
#include <sqlite3.h>
#endif
#ifdef APM_DRIVER_MYSQL
#include <mysql/mysql.h>
#endif
#ifdef PHP_WIN32
#define PHP_APM_API __declspec(dllexport)
#else
#define PHP_APM_API
#endif
#include "TSRM.h"
#define APM_E_ALL (E_ALL | E_STRICT)
#define APM_EVENT_ERROR 1
#define APM_EVENT_EXCEPTION 2
#define PROCESS_EVENT_ARGS int type, char * error_filename, uint error_lineno, char * msg, char * trace TSRMLS_DC
typedef struct apm_event {
int event_type;
int type;
char * error_filename;
uint error_lineno;
char * msg;
char * trace;
} apm_event;
typedef struct apm_event_entry {
apm_event event;
struct apm_event_entry *next;
} apm_event_entry;
typedef struct apm_driver {
void (* process_event)(PROCESS_EVENT_ARGS);
void (* process_stats)(TSRMLS_D);
int (* minit)(int TSRMLS_DC);
int (* rinit)(TSRMLS_D);
int (* mshutdown)(SHUTDOWN_FUNC_ARGS);
int (* rshutdown)(TSRMLS_D);
zend_bool (* is_enabled)(TSRMLS_D);
zend_bool (* want_event)(int, int, char * TSRMLS_DC);
zend_bool (* want_stats)(TSRMLS_D);
int (* error_reporting)(TSRMLS_D);
zend_bool is_request_created;
} apm_driver;
typedef struct apm_driver_entry {
apm_driver driver;
struct apm_driver_entry *next;
} apm_driver_entry;
#if PHP_VERSION_ID >= 70000
# define RD_DEF(var) zval *var; zend_bool var##_found;
#else
# define RD_DEF(var) zval **var; zend_bool var##_found;
#endif
typedef struct apm_request_data {
RD_DEF(uri);
RD_DEF(host);
RD_DEF(ip);
RD_DEF(referer);
RD_DEF(ts);
RD_DEF(script);
RD_DEF(method);
zend_bool initialized, cookies_found, post_vars_found;
smart_str cookies, post_vars;
} apm_request_data;
#ifdef ZTS
#define APM_GLOBAL(driver, v) TSRMG(apm_globals_id, zend_apm_globals *, driver##_##v)
#else
#define APM_GLOBAL(driver, v) (apm_globals.driver##_##v)
#endif
#if PHP_VERSION_ID >= 70000
# define apm_error_reporting_new_value (new_value && new_value->val) ? atoi(new_value->val)
#else
# define apm_error_reporting_new_value new_value ? atoi(new_value)
#endif
#define APM_DRIVER_CREATE(name) \
void apm_driver_##name##_process_event(PROCESS_EVENT_ARGS); \
void apm_driver_##name##_process_stats(TSRMLS_D); \
int apm_driver_##name##_minit(int TSRMLS_DC); \
int apm_driver_##name##_rinit(TSRMLS_D); \
int apm_driver_##name##_mshutdown(); \
int apm_driver_##name##_rshutdown(TSRMLS_D); \
PHP_INI_MH(OnUpdateAPM##name##ErrorReporting) \
{ \
APM_GLOBAL(name, error_reporting) = (apm_error_reporting_new_value : APM_E_##name); \
return SUCCESS; \
} \
zend_bool apm_driver_##name##_is_enabled(TSRMLS_D) \
{ \
return APM_GLOBAL(name, enabled); \
} \
int apm_driver_##name##_error_reporting(TSRMLS_D) \
{ \
return APM_GLOBAL(name, error_reporting); \
} \
zend_bool apm_driver_##name##_want_event(int event_type, int error_level, char *msg TSRMLS_DC) \
{ \
return \
APM_GLOBAL(name, enabled) \
&& ( \
(event_type == APM_EVENT_EXCEPTION && APM_GLOBAL(name, exception_mode) == 2) \
|| \
(event_type == APM_EVENT_ERROR && ((APM_GLOBAL(name, exception_mode) == 1) || (strncmp(msg, "Uncaught exception", 18) != 0)) && (error_level & APM_GLOBAL(name, error_reporting))) \
) \
&& ( \
!APM_G(currently_silenced) || APM_GLOBAL(name, process_silenced_events) \
) \
; \
} \
zend_bool apm_driver_##name##_want_stats(TSRMLS_D) \
{ \
return \
APM_GLOBAL(name, enabled) \
&& ( \
APM_GLOBAL(name, stats_enabled)\
) \
; \
} \
apm_driver_entry * apm_driver_##name##_create() \
{ \
apm_driver_entry * driver_entry; \
driver_entry = (apm_driver_entry *) malloc(sizeof(apm_driver_entry)); \
driver_entry->driver.process_event = apm_driver_##name##_process_event; \
driver_entry->driver.minit = apm_driver_##name##_minit; \
driver_entry->driver.rinit = apm_driver_##name##_rinit; \
driver_entry->driver.mshutdown = apm_driver_##name##_mshutdown; \
driver_entry->driver.rshutdown = apm_driver_##name##_rshutdown; \
driver_entry->driver.process_stats = apm_driver_##name##_process_stats; \
driver_entry->driver.is_enabled = apm_driver_##name##_is_enabled; \
driver_entry->driver.error_reporting = apm_driver_##name##_error_reporting; \
driver_entry->driver.want_event = apm_driver_##name##_want_event; \
driver_entry->driver.want_stats = apm_driver_##name##_want_stats; \
driver_entry->driver.is_request_created = 0; \
driver_entry->next = NULL; \
return driver_entry; \
}
PHP_MINIT_FUNCTION(apm);
PHP_MSHUTDOWN_FUNCTION(apm);
PHP_RINIT_FUNCTION(apm);
PHP_RSHUTDOWN_FUNCTION(apm);
PHP_MINFO_FUNCTION(apm);
#ifdef APM_DEBUGFILE
#define APM_INIT_DEBUG APM_G(debugfile) = fopen(APM_DEBUGFILE, "a+");
#define APM_DEBUG(...) if (APM_G(debugfile)) { fprintf(APM_G(debugfile), __VA_ARGS__); fflush(APM_G(debugfile)); }
#define APM_SHUTDOWN_DEBUG if (APM_G(debugfile)) { fclose(APM_G(debugfile)); APM_G(debugfile) = NULL; }
#else
#define APM_INIT_DEBUG
#define APM_DEBUG(...)
#define APM_SHUTDOWN_DEBUG
#endif
/* Extension globals */
ZEND_BEGIN_MODULE_GLOBALS(apm)
/* Boolean controlling whether the extension is globally active or not */
zend_bool enabled;
/* Application identifier, helps identifying which application is being monitored */
char *application_id;
/* Boolean controlling whether the event monitoring is active or not */
zend_bool event_enabled;
/* Boolean controlling whether the stacktrace should be generated or not */
zend_bool store_stacktrace;
/* Boolean controlling whether the ip should be generated or not */
zend_bool store_ip;
/* Boolean controlling whether the cookies should be generated or not */
zend_bool store_cookies;
/* Boolean controlling whether the POST variables should be generated or not */
zend_bool store_post;
/* Time (in ms) before a request is considered for stats */
long stats_duration_threshold;
/* User CPU time usage (in ms) before a request is considered for stats */
long stats_user_cpu_threshold;
/* System CPU time usage (in ms) before a request is considered for stats */
long stats_sys_cpu_threshold;
/* Maximum recursion depth used when dumping a variable */
long dump_max_depth;
/* Determines whether we're currently silenced */
zend_bool currently_silenced;
apm_driver_entry *drivers;
smart_str *buffer;
/* Structure used to store request data */
apm_request_data request_data;
float duration;
long mem_peak_usage;
#ifdef HAVE_GETRUSAGE
float user_cpu;
float sys_cpu;
#endif
#ifdef APM_DEBUGFILE
FILE * debugfile;
#endif
#ifdef APM_DRIVER_SQLITE3
/* Boolean controlling whether the driver is active or not */
zend_bool sqlite3_enabled;
/* Boolean controlling the collection of stats */
zend_bool sqlite3_stats_enabled;
/* Control which exceptions to collect (0: none exceptions collected, 1: collect uncaught exceptions (default), 2: collect ALL exceptions) */
long sqlite3_exception_mode;
/* driver error reporting */
int sqlite3_error_reporting;
/* Path to the SQLite database file */
char *sqlite3_db_path;
/* The actual db file */
char sqlite3_db_file[MAXPATHLEN];
/* DB handle */
sqlite3 *sqlite3_event_db;
/* Max timeout to wait for storing the event in the DB */
long sqlite3_timeout;
/* Request ID */
sqlite3_int64 sqlite3_request_id;
/* Boolean to ensure request content is only inserted once */
zend_bool sqlite3_is_request_created;
/* Option to process silenced events */
zend_bool sqlite3_process_silenced_events;
#endif
#ifdef APM_DRIVER_MYSQL
/* Boolean controlling whether the driver is active or not */
zend_bool mysql_enabled;
/* Boolean controlling the collection of stats */
zend_bool mysql_stats_enabled;
/* Control which exceptions to collect (0: none exceptions collected, 1: collect uncaught exceptions (default), 2: collect ALL exceptions) */
long mysql_exception_mode;
/* driver error reporting */
int mysql_error_reporting;
/* MySQL host */
char *mysql_db_host;
/* MySQL port */
unsigned int mysql_db_port;
/* MySQL user */
char *mysql_db_user;
/* MySQL password */
char *mysql_db_pass;
/* MySQL database */
char *mysql_db_name;
/* DB handle */
MYSQL *mysql_event_db;
/* Option to process silenced events */
zend_bool mysql_process_silenced_events;
/* Boolean to ensure request content is only inserted once */
zend_bool mysql_is_request_created;
#endif
#ifdef APM_DRIVER_STATSD
/* Boolean controlling whether the driver is active or not */
zend_bool statsd_enabled;
/* Boolean controlling the collection of stats */
zend_bool statsd_stats_enabled;
/* (unused for StatsD) */
long statsd_exception_mode;
/* (unused for StatsD) */
int statsd_error_reporting;
/* StatsD host */
char *statsd_host;
/* StatsD port */
unsigned int statsd_port;
/* StatsD key prefix */
char *statsd_prefix;
/* addinfo for StatsD server */
struct addrinfo *statsd_servinfo;
/* Option to process silenced events */
zend_bool statsd_process_silenced_events;
#endif
#ifdef APM_DRIVER_SOCKET
/* Boolean controlling whether the driver is active or not */
zend_bool socket_enabled;
/* Boolean controlling the collection of stats */
zend_bool socket_stats_enabled;
/* (unused for socket driver) */
long socket_exception_mode;
/* (unused for socket driver) */
int socket_error_reporting;
/* Option to process silenced events */
zend_bool socket_process_silenced_events;
/* socket path */
char *socket_path;
apm_event_entry *socket_events;
apm_event_entry **socket_last_event;
#endif
ZEND_END_MODULE_GLOBALS(apm)
ZEND_EXTERN_MODULE_GLOBALS(apm)
#ifdef ZTS
#define APM_G(v) TSRMG(apm_globals_id, zend_apm_globals *, v)
#else
#define APM_G(v) (apm_globals.v)
#endif
#define APM_RD(data) APM_G(request_data).data
#if PHP_VERSION_ID >= 70000
# define APM_RD_STRVAL(var) Z_STRVAL_P(APM_RD(var))
# define APM_RD_SMART_STRVAL(var) APM_RD(var).s->val
#else
# define APM_RD_STRVAL(var) Z_STRVAL_PP(APM_RD(var))
# define APM_RD_SMART_STRVAL(var) APM_RD(var).c
#endif
#define SEC_TO_USEC(sec) ((sec) * 1000000.00)
#define USEC_TO_SEC(usec) ((usec) / 1000000.00)
#if PHP_VERSION_ID >= 70000
# define zend_is_auto_global_compat(name) (zend_is_auto_global_str(ZEND_STRL((name))))
# define add_assoc_long_compat(array, key, value) add_assoc_long_ex((array), (key), (sizeof(key) - 1), (value));
#else
# define zend_is_auto_global_compat(name) (zend_is_auto_global(ZEND_STRL((name)) TSRMLS_CC))
# define add_assoc_long_compat(array, key, value) add_assoc_long_ex((array), (key), (sizeof(key)), (value));
#endif
void extract_data(TSRMLS_D);
#endif