Π Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΠ²Π°Ρ Linux, Π² ΠΊΠΎΡΠΎΡΡΡ ΡΠ΄ΡΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡ eBPF, ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΡΠΈΠΊ bpftrace ΡΠΌΠ΅Π΅Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡΡΡ ΠΊ Π·ΠΎΠ½Π΄Π°ΠΌ PHP DTrace USDT Π±Π΅Π· ΠΏΠΎΡΡΠ΅Π΄Π½ΠΈΡΠ΅ΡΡΠ²Π° ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠ° SystemTap.
Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ bpftrace ΡΠ΅ΡΠ΅Π· ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² Π΄ΠΈΡΡΡΠΈΠ±ΡΡΠΈΠ²Π°. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π² Oracle Linux, RHEL ΠΈΠ»ΠΈ Fedora:
# dnf install bpftrace
# apt install bpftrace
Π‘Π»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΡ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡΡ, ΡΡΠΎ ΡΠ΅Π»Π΅Π²ΠΎΠΉ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» PHP ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ ΠΏΠΎ ΠΏΡΡΠΈ /usr/bin/php.
Π’Π΅ ΠΆΠ΅ Π·ΠΎΠ½Π΄Ρ USDT ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡΡ ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ SAPI, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΎΠ±ΡΠ°Π»ΠΈ ΠΈΠ· ΡΠΎΠ³ΠΎ ΠΆΠ΅ Π΄Π΅ΡΠ΅Π²Π° ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°,
ΠΏΠΎΡΡΠΎΠΌΡ ΡΠ΅Π»ΡΡ Π·ΠΎΠ½Π΄ΠΎΠ² Π²ΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ Π²ΡΡΡΡΠΏΠ°Π΅Ρ Π»ΠΈΠ±ΠΎ ΠΌΠΎΠ΄ΡΠ»Ρ Apache
(libphp.so), Π»ΠΈΠ±ΠΎ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» Π΄ΠΈΡΠΏΠ΅ΡΡΠ΅ΡΠ° ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² FastCGI
(php-fpm); ΠΏΠΎΠ΄ΡΡΠ°Π²ΡΡΠ΅ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ
ΠΏΡΡΡ ΠΈΠ»ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΠ΅ΡΡ ΠΏΠΎ PID-ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ ΡΠ΅ΡΠ΅Π· ΠΊΠ»ΡΡ -p ΠΏΡΠΈ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ.
Π£Π±Π΅Π΄ΠΈΡΠ΅ΡΡ, ΡΡΠΎ ΡΠΎΠ±ΡΠ°Π»ΠΈ ΡΠ΅Π»Π΅Π²ΠΎΠΉ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠ° DTrace ΠΈ ΡΡΠΎ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ Π½Π°ΡΡΡΠΎΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ. ΠΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ ΠΎΠΏΠΈΡΡΠ²Π°Π΅Ρ ΡΠ°Π·Π΄Π΅Π» ΠΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ PHP ΡΠΎ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌΠΈ Π·ΠΎΠ½Π΄Π°ΠΌΠΈ DTrace.
Π‘ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π·ΠΎΠ½Π΄Ρ PHP Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄Π° bpftrace:
# bpftrace -l 'usdt:/usr/bin/php:php:*'
ΠΠΎΠΌΠ°Π½Π΄Π° Π²ΡΠ²ΠΎΠ΄ΠΈΡ:
usdt:/usr/bin/php:php:compile__file__entry usdt:/usr/bin/php:php:compile__file__return usdt:/usr/bin/php:php:error usdt:/usr/bin/php:php:exception__caught usdt:/usr/bin/php:php:exception__thrown usdt:/usr/bin/php:php:execute__entry usdt:/usr/bin/php:php:execute__return usdt:/usr/bin/php:php:function__entry usdt:/usr/bin/php:php:function__return usdt:/usr/bin/php:php:request__shutdown usdt:/usr/bin/php:php:request__startup
ΠΡΠΈΠΌΠ΅Ρ #1 Π‘ΠΊΡΠΈΠΏΡ all_probes.bt β ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΠ° Π²ΡΠ΅Ρ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ PHP-Π·ΠΎΠ½Π΄ΠΎΠ² ΡΠ΅ΡΠ΅Π· bpftrace
#!/usr/bin/env bpftrace
usdt:/usr/bin/php:php:compile__file__entry
{
printf("Probe compile__file__entry\n");
printf(" compile_file %s\n", str(arg0));
printf(" compile_file_translated %s\n", str(arg1));
}
usdt:/usr/bin/php:php:compile__file__return
{
printf("Probe compile__file__return\n");
printf(" compile_file %s\n", str(arg0));
printf(" compile_file_translated %s\n", str(arg1));
}
usdt:/usr/bin/php:php:error
{
printf("Probe error\n");
printf(" errormsg %s\n", str(arg0));
printf(" request_file %s\n", str(arg1));
printf(" lineno %d\n", (int32)arg2);
}
usdt:/usr/bin/php:php:exception__caught
{
printf("Probe exception__caught\n");
printf(" classname %s\n", str(arg0));
}
usdt:/usr/bin/php:php:exception__thrown
{
printf("Probe exception__thrown\n");
printf(" classname %s\n", str(arg0));
}
usdt:/usr/bin/php:php:execute__entry
{
printf("Probe execute__entry\n");
printf(" request_file %s\n", str(arg0));
printf(" lineno %d\n", (int32)arg1);
}
usdt:/usr/bin/php:php:execute__return
{
printf("Probe execute__return\n");
printf(" request_file %s\n", str(arg0));
printf(" lineno %d\n", (int32)arg1);
}
usdt:/usr/bin/php:php:function__entry
{
printf("Probe function__entry\n");
printf(" function_name %s\n", str(arg0));
printf(" request_file %s\n", str(arg1));
printf(" lineno %d\n", (int32)arg2);
printf(" classname %s\n", str(arg3));
printf(" scope %s\n", str(arg4));
}
usdt:/usr/bin/php:php:function__return
{
printf("Probe function__return\n");
printf(" function_name %s\n", str(arg0));
printf(" request_file %s\n", str(arg1));
printf(" lineno %d\n", (int32)arg2);
printf(" classname %s\n", str(arg3));
printf(" scope %s\n", str(arg4));
}
usdt:/usr/bin/php:php:request__shutdown
{
printf("Probe request__shutdown\n");
printf(" file %s\n", str(arg0));
printf(" request_uri %s\n", str(arg1));
printf(" request_method %s\n", str(arg2));
}
usdt:/usr/bin/php:php:request__startup
{
printf("Probe request__startup\n");
printf(" file %s\n", str(arg0));
printf(" request_uri %s\n", str(arg1));
printf(" request_method %s\n", str(arg2));
}
ΠΡΠΈΠ²Π΅Π΄ΡΠ½Π½ΡΠΉ ΡΠΊΡΠΈΠΏΡ ΡΡΠ°ΡΡΠΈΡΡΠ΅Ρ Π²ΡΠ΅ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π·ΠΎΠ½Π΄Ρ ΡΠ΄ΡΠ° PHP Π½Π° Π²ΡΡΠΌ ΠΏΡΠΎΡΡΠΆΠ΅Π½ΠΈΠΈ ΡΠ°Π±ΠΎΡΡ PHP-ΡΠΊΡΠΈΠΏΡΠ°. Π’ΡΠ°ΡΡΠΈΡΠΎΠ²ΡΠΈΠΊΡ bpftrace ΡΡΠ΅Π±ΡΡΡΡΡ ΠΏΡΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΈ ΡΡΠΏΠ΅ΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ:
# USE_ZEND_DTRACE=1 bpftrace -c '/usr/bin/php test.php' all_probes.bt
ΠΠ»Ρ ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΠΈ ΡΠΆΠ΅ Π·Π°ΠΏΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ PHP-ΠΏΡΠΎΡΠ΅ΡΡΠ°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ°Π±ΠΎΡΠ΅Π³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ° php-fpm ΠΈΠ»ΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠ° Apache, ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°Π³ΡΡΠ·ΠΈΠ» Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ libphp.so, ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΠ΅ΡΡ ΠΏΠΎ PID:
# bpftrace -p $PID all_probes.bt
usdt: ΠΏΠΎΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠΊΠ°Π·Π°ΡΡ ΡΠ΅Π»Ρ β ΠΏΡΡΡ Π΄ΠΎ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°
Π·Π°ΠΏΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ°: usdt:/usr/bin/php;
Π·Π°ΠΌΠ΅Π½ΠΈΡΠ΅ ΠΏΡΡΡ Π² ΡΡΡΠΎΠΊΠ΅ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ Π·ΠΎΠ½Π΄Π° Π½Π° ΠΏΡΡΡ Π΄ΠΎ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° php-fpm
ΠΈΠ»ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ libphp.so, Π΅ΡΠ»ΠΈ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅ΡΡΡ.