-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathdtrace.xml
582 lines (536 loc) · 20.6 KB
/
dtrace.xml
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
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: d35d7d811ccf7662eefe4f23ff1cabc727a917ca Maintainer: samesch Status: ready -->
<!-- Reviewed: no -->
<chapter xml:id="features.dtrace" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>DTrace Dynamic Tracing (Anwendungsanalyse in Echtzeit)</title>
<sect1 xml:id="features.dtrace.introduction">
<title>Einführung in PHP und DTrace</title>
<para>
DTrace ist ein Tracing-Framework, das immer verfügbar ist, einen geringen
zusätzlichen Rechenaufwand verursacht und auf vielen Plattformen wie
Solaris, macOS, Oracle Linux und BSD zur Verfügung steht. DTrace kann das
Verhalten des Betriebssystems und die Ausführung von Benutzerprogrammen
verfolgen. Es kann Parameterwerte anzeigen und zur Abschätzung von
Leistungsstatistiken verwendet werden. Prüfsonden (Probes) werden durch vom
Benutzer erstellte Skripte, die in der DTrace-Skriptsprache D geschrieben
sind, überwacht. Dies ermöglicht eine effiziente Analyse der Datenpunkte.
</para>
<para>
PHP-Sonden, die nicht aktiv vom DTrace-D-Skript eines Benutzers überwacht
werden, enthalten keinen Instrumentierungscode, sodass es während der
normalen Ausführung der Anwendungen keine Leistungseinbußen gibt. Sonden,
die überwacht werden, verursachen im Allgemeinen einen so geringen
zusätzlichen Rechenaufwand, dass die Überwachung mit DTrace auf
Produktivsystemen möglich ist.
</para>
<para>
PHP verfügt über USDT-Sonden, die zur Laufzeit ausgelöst werden (USDT:
User-level Statically Defined Tracing; statisch definiertes Tracing auf
Benutzerebene). Wenn ein D-Skript zum Beispiel PHP's
<literal>function-entry</literal>-Sonde überwacht, löst diese Sonde bei
jedem Funktionsaufruf den entsprechenden D-Skript-Aktionscode aus. Dieser
Aktionscode könnte zum Beispiel die Parameter der Sonde, also &zb; den
Speicherort der Quelldatei dieser PHP-Funktion, ausgeben. Oder die Aktion
könnte Daten sammeln, &zb; wie oft jede Funktion aufgerufen wird.
</para>
<para>
Hier werden nur die PHP-USDT-Sonden beschrieben. Um zu erfahren, wie DTrace
verwendet werden kann, um beliebige Funktionen und das Verhalten des
Betriebssystems zu überwachen, sind die allgemeine und die
betriebssystemspezifische DTrace-Literatur zu empfehlen. Es ist zu
beachten, dass nicht alle DTrace-Funktionen in allen
DTrace-Implementierungen verfügbar sind.
</para>
<para>
Die statischen DTrace-Sonden in PHP können auf einigen Linux-Distributionen
alternativ auch mit SystemTap verwendet werden.
</para>
</sect1>
<sect1 xml:id="features.dtrace.dtrace">
<title>PHP mit DTrace verwenden</title>
<para>
PHP kann auf Plattformen, die DTrace Dynamic Tracing unterstützen, mit
statischen DTrace-Sonden konfiguriert werden.
</para>
<sect2 xml:id="features.dtrace.install">
<title>PHP für statische DTrace-Sonden konfigurieren</title>
<para>
Um die DTrace-Unterstützung des Betriebssystems zu aktivieren, siehe die
externe plattformspezifische Dokumentation. Unter Oracle Linux muss zum
Beispiel ein UEK3-Kernel gebootet und anschließend Folgendes ausgeführt
werden:
<informalexample>
<programlisting role="php">
<![CDATA[
# modprobe fasttrap
# chmod 666 /dev/dtrace/helper
]]>
</programlisting>
</informalexample>
</para>
<para>
Anstatt <literal>chmod</literal> zu verwenden, kann stattdessen eine
ACL-Paketregel verwendet werden, um den Gerätezugriff auf einen bestimmten
Benutzer zu beschränken.
</para>
<para>
PHP mit dem Konfigurationsparameter <literal>--enable-dtrace</literal>
kompilieren:
<informalexample>
<programlisting role="php">
<![CDATA[
# ./configure --enable-dtrace ...
# make
# make install
]]>
</programlisting>
</informalexample>
</para>
<para>
Dadurch werden die statischen Sonden im Kern von PHP verfügbar. Alle
PHP-Erweiterungen, die ihre eigenen Sonden bereitstellen, müssen separat
als dynamische Erweiterungen gebaut werden.
</para>
<para>
Um Sonden zu aktivieren, muss die Umgebungsvariable
<option>USE_ZEND_DTRACE=1</option> für die PHP-Zielprozesse gesetzt werden.
</para>
</sect2>
<sect2 xml:id="features.dtrace.static-probes">
<title>Statische DTrace-Sonden im Kern von PHP</title>
<table>
<title>Die folgenden statischen Sonden stehen in PHP zur Verfügung</title>
<tgroup cols="2">
<thead>
<row>
<entry>Name der Probe</entry>
<entry>Beschreibung der Probe</entry>
<entry>Parameter der Probe</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>request-startup</literal></entry>
<entry>Wird ausgelöst, wenn eine Anfrage beginnt.</entry>
<entry>char *<varname>file</varname>, char *<varname>request_uri</varname>, char *<varname>request_method</varname></entry>
</row>
<row>
<entry><literal>request-shutdown</literal></entry>
<entry>Wird ausgelöst, wenn eine Anfrage endet.</entry>
<entry>char *<varname>file</varname>, char *<varname>request_uri</varname>, char *<varname>request_method</varname></entry>
</row>
<row>
<entry><literal>compile-file-entry</literal></entry>
<entry>Wird ausgelöst, wenn die Kompilierung eines Skripts beginnt.</entry>
<entry>char *<varname>compile_file</varname>, char *<varname>compile_file_translated</varname></entry>
</row>
<row>
<entry><literal>compile-file-return</literal></entry>
<entry>Wird ausgelöst, wenn die Kompilierung eines Skripts endet.</entry>
<entry>char *<varname>compile_file</varname>, char *<varname>compile_file_translated</varname></entry>
</row>
<row>
<entry><literal>execute-entry</literal></entry>
<entry>
Wird ausgelöst, wenn ein OpCode-Array ausgeführt wird, &zb; bei
Funktionsaufrufen, Includes und wenn ein Generator fortfährt.
</entry>
<entry>char *<varname>request_file</varname>, int <varname>lineno</varname></entry>
</row>
<row>
<entry><literal>execute-return</literal></entry>
<entry>Wird nach der Ausführung eines OpCode-Arrays ausgelöst.</entry>
<entry>char *<varname>request_file</varname>, int <varname>lineno</varname></entry>
</row>
<row>
<entry><literal>function-entry</literal></entry>
<entry>
Wird ausgelöst, wenn die PHP-Engine in eine PHP-Funktion oder -Methode
gelangt.
</entry>
<entry>char *<varname>function_name</varname>, char *<varname>request_file</varname>, int <varname>lineno</varname>, char *<varname>classname</varname>, char *<varname>scope</varname></entry>
</row>
<row>
<entry><literal>function-return</literal></entry>
<entry>
Wird ausgelöst, wenn die PHP-Engine aus einer PHP-Funktion oder -Methode
zurückkehrt.
</entry>
<entry>char *<varname>function_name</varname>, char *<varname>request_file</varname>, int <varname>lineno</varname>, char *<varname>classname</varname>, char *<varname>scope</varname></entry>
</row>
<row>
<entry><literal>exception-thrown</literal></entry>
<entry>Wird ausgelöst, wenn eine Exception ausgelöst wird.</entry>
<entry>char *<varname>classname</varname></entry>
</row>
<row>
<entry><literal>exception-caught</literal></entry>
<entry>Wird ausgelöst, wenn eine Exception abgefangen wird.</entry>
<entry>char *<varname>classname</varname></entry>
</row>
<row>
<entry><literal>error</literal></entry>
<entry>
Wird ausgelöst, wenn ein Fehler auftritt, unabhängig von der
<link linkend="ini.error-reporting">error_reporting</link>-Stufe.
</entry>
<entry>char *<varname>errormsg</varname>, char *<varname>request_file</varname>, int <varname>lineno</varname></entry>
</row>
</tbody>
</tgroup>
</table>
<para>
PHP-Erweiterungen verfügen möglicherweise über zusätzliche statische Sonden.
</para>
</sect2>
<sect2 xml:id="features.dtrace.list-probes">
<title>Liste statischer DTrace-Sonden in PHP</title>
<para>
Um die verfügbaren Sonden aufzulisten, ist es nötig, einen PHP-Prozess zu
starten und dann Folgendes auszuführen:
<informalexample>
<programlisting>
<![CDATA[
# dtrace -l
]]>
</programlisting>
</informalexample>
</para>
<para>
Die Ausgabe wird ungefähr so aussehen:
<informalexample>
<programlisting>
<![CDATA[
ID PROVIDER MODULE FUNCTION NAME
[ . . . ]
4 php15271 php dtrace_compile_file compile-file-entry
5 php15271 php dtrace_compile_file compile-file-return
6 php15271 php zend_error error
7 php15271 php ZEND_CATCH_SPEC_CONST_CV_HANDLER exception-caught
8 php15271 php zend_throw_exception_internal exception-thrown
9 php15271 php dtrace_execute_ex execute-entry
10 php15271 php dtrace_execute_internal execute-entry
11 php15271 php dtrace_execute_ex execute-return
12 php15271 php dtrace_execute_internal execute-return
13 php15271 php dtrace_execute_ex function-entry
14 php15271 php dtrace_execute_ex function-return
15 php15271 php php_request_shutdown request-shutdown
16 php15271 php php_request_startup request-startup
]]>
</programlisting>
</informalexample>
</para>
<para>
Die Werte der Spalte PROVIDER setzen sich aus <literal>php</literal> und
der Prozess-ID des aktuell laufenden PHP-Prozesses zusammen.
</para>
<para>
Wenn der Apache-Webserver läuft, könnte der Modulname zum Beispiel
<filename>libphp5.so</filename> sein, und es gäbe pro laufendem
Apache-Prozess einen Auflistungs-Block.
</para>
<para>
Die Spalte FUNCTION verweist auf den Funktionsnamen der PHP-internen
C-Implementierung, in der sich der jeweilige Provider befindet.
</para>
<para>
Wenn kein PHP-Prozess läuft, werden auch keine PHP-Sonden angezeigt.
</para>
</sect2>
<sect2 xml:id="features.dtrace.examples">
<title>DTrace-Beispiel für PHP</title>
<para>
Dieses Beispiel zeigt die grundlegenden Möglichkeiten der
DTrace-Skriptsprache D.
<example>
<title><filename>all_probes.d</filename> für die Verfolgung aller statischen PHP-Sonden mit DTrace</title>
<programlisting>
<![CDATA[
#!/usr/sbin/dtrace -Zs
#pragma D option quiet
php*:::compile-file-entry
{
printf("PHP compile-file-entry\n");
printf(" compile_file %s\n", copyinstr(arg0));
printf(" compile_file_translated %s\n", copyinstr(arg1));
}
php*:::compile-file-return
{
printf("PHP compile-file-return\n");
printf(" compile_file %s\n", copyinstr(arg0));
printf(" compile_file_translated %s\n", copyinstr(arg1));
}
php*:::error
{
printf("PHP error\n");
printf(" errormsg %s\n", copyinstr(arg0));
printf(" request_file %s\n", copyinstr(arg1));
printf(" lineno %d\n", (int)arg2);
}
php*:::exception-caught
{
printf("PHP exception-caught\n");
printf(" classname %s\n", copyinstr(arg0));
}
php*:::exception-thrown
{
printf("PHP exception-thrown\n");
printf(" classname %s\n", copyinstr(arg0));
}
php*:::execute-entry
{
printf("PHP execute-entry\n");
printf(" request_file %s\n", copyinstr(arg0));
printf(" lineno %d\n", (int)arg1);
}
php*:::execute-return
{
printf("PHP execute-return\n");
printf(" request_file %s\n", copyinstr(arg0));
printf(" lineno %d\n", (int)arg1);
}
php*:::function-entry
{
printf("PHP function-entry\n");
printf(" function_name %s\n", copyinstr(arg0));
printf(" request_file %s\n", copyinstr(arg1));
printf(" lineno %d\n", (int)arg2);
printf(" classname %s\n", copyinstr(arg3));
printf(" scope %s\n", copyinstr(arg4));
}
php*:::function-return
{
printf("PHP function-return\n");
printf(" function_name %s\n", copyinstr(arg0));
printf(" request_file %s\n", copyinstr(arg1));
printf(" lineno %d\n", (int)arg2);
printf(" classname %s\n", copyinstr(arg3));
printf(" scope %s\n", copyinstr(arg4));
}
php*:::request-shutdown
{
printf("PHP request-shutdown\n");
printf(" file %s\n", copyinstr(arg0));
printf(" request_uri %s\n", copyinstr(arg1));
printf(" request_method %s\n", copyinstr(arg2));
}
php*:::request-startup
{
printf("PHP request-startup\n");
printf(" file %s\n", copyinstr(arg0));
printf(" request_uri %s\n", copyinstr(arg1));
printf(" request_method %s\n", copyinstr(arg2));
}
]]>
</programlisting>
</example>
</para>
<para>
Dieses Skript verwendet <filename>dtrace</filename> mit der Option
<literal>-Z</literal>, damit es auch dann ausgeführt werden kann, wenn
gerade kein PHP-Prozess läuft. Ohne diese Option würde das Skript sofort
beendet, weil es erkennt, dass keine der zu überwachenden Sonden vorhanden
ist.
</para>
<para>
Das Skript verfolgt während der gesamten Zeit, in der ein PHP-Skript
läuft, alle statischen Sondenpunkte des PHP-Kerns.
<informalexample>
<programlisting>
<![CDATA[
# ./all_probes.d
]]>
</programlisting>
</informalexample>
</para>
<para>
Sobald nun ein PHP-Skript oder eine Anwendung ausgeführt wird, beginnt das
überwachende D-Skript, alle Parameter der ausgelösten Sonden auszugeben.
</para>
<para>
Um die Überwachung abzuschließen, kann das D-Skript mittels
<keycombo action='simul'><keycap>CTRL</keycap><keycap>C</keycap></keycombo>
beendet werden.
</para>
<para>
Auf Rechnern mit mehreren CPUs ist die Reihenfolge der Tests möglicherweise
nicht sequentiell. Dies hängt davon ab, welche CPU die Sonden verarbeitet
hat und wie die Threads zwischen den CPUs wechseln. Die Anzeige der
Zeitstempel der Sonden hilft, Verwechslungen zu vermeiden, zum Beispiel:
<informalexample>
<programlisting>
<![CDATA[
php*:::function-entry
{
printf("%lld: PHP function-entry ", walltimestamp);
[ . . .]
}
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="features.dtrace.references">
&reftitle.seealso;
<simplelist>
<member><link linkend="oci8.dtrace">OCI8 und DTrace Dynamic Tracing</link></member>
</simplelist>
</sect2>
</sect1>
<sect1 xml:id="features.dtrace.systemtap">
<title>Verwendung von SystemTap mit statischen PHP-DTrace-Sonden</title>
<para>
Auf einigen Linux-Distributionen kann das Tracing-Tool SystemTap verwendet
werden, um die statischen DTrace-Sonden von PHP zu überwachen. Diese
Möglichkeit steht mit PHP 5.4.20 und PHP 5.5 zur Verfügung.
</para>
<sect2 xml:id="features.dtrace.systemtap-install">
<title>Installation von PHP mit SystemTap</title>
<para>
Installieren des SystemTap-SDT-Entwicklungspakets:
<informalexample>
<programlisting role="shell">
<![CDATA[
# yum install systemtap-sdt-devel
]]>
</programlisting>
</informalexample>
</para>
<para>
Installieren von PHP mit aktivierten DTrace-Sonden:
<informalexample>
<programlisting role="shell">
<![CDATA[
# ./configure --enable-dtrace ...
# make
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="features.dtrace.systemtap-list-probes">
<title>Auflistung statischer Sonden mittels SystemTap</title>
<para>
Die statischen Sonden in PHP können mittels <filename>stap</filename>
aufgelistet werden:
<informalexample>
<programlisting>
<![CDATA[
# stap -l 'process.provider("php").mark("*")' -c 'sapi/cli/php -i'
]]>
</programlisting>
</informalexample>
</para>
<para>
This outputs:
<informalexample>
<programlisting>
<![CDATA[
process("sapi/cli/php").provider("php").mark("compile__file__entry")
process("sapi/cli/php").provider("php").mark("compile__file__return")
process("sapi/cli/php").provider("php").mark("error")
process("sapi/cli/php").provider("php").mark("exception__caught")
process("sapi/cli/php").provider("php").mark("exception__thrown")
process("sapi/cli/php").provider("php").mark("execute__entry")
process("sapi/cli/php").provider("php").mark("execute__return")
process("sapi/cli/php").provider("php").mark("function__entry")
process("sapi/cli/php").provider("php").mark("function__return")
process("sapi/cli/php").provider("php").mark("request__shutdown")
process("sapi/cli/php").provider("php").mark("request__startup")
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="features.dtrace.systemtap-examples">
<title>Beispiel für die Verwendung von SystemTap mit PHP</title>
<para>
<example>
<title><filename>all_probes.stp</filename> - Verfolgung aller statischen PHP-Sonden mit SystemTap</title>
<programlisting role="shell">
<![CDATA[
probe process("sapi/cli/php").provider("php").mark("compile__file__entry") {
printf("Probe compile__file__entry\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("compile__file__return") {
printf("Probe compile__file__return\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("error") {
printf("Probe error\n");
printf(" errormsg %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
}
probe process("sapi/cli/php").provider("php").mark("exception__caught") {
printf("Probe exception__caught\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("exception__thrown") {
printf("Probe exception__thrown\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("execute__entry") {
printf("Probe execute__entry\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("execute__return") {
printf("Probe execute__return\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("function__entry") {
printf("Probe function__entry\n");
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("function__return") {
printf("Probe function__return: %s\n", user_string($arg1));
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("request__shutdown") {
printf("Probe request__shutdown\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
probe process("sapi/cli/php").provider("php").mark("request__startup") {
printf("Probe request__startup\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
]]>
</programlisting>
</example>
</para>
<para>
Das obige Skript verfolgt während der gesamten Dauer eines laufenden
PHP-Skripts alle statischen Sondenpunkte des PHP-Kerns:
<informalexample>
<programlisting>
<![CDATA[
# stap -c 'sapi/cli/php test.php' all_probes.stp
]]>
</programlisting>
</informalexample>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->