APM Field LabECV Operation · Technical Enablement RHEL · Apache · PHP-FPM
ทดสอบจริงแล้ว · Manual lab

Deploy. Trace.
Verify.

ติดตั้ง Datadog APM บน EC2 RHEL แบบทีละขั้น ตั้งแต่ Apache และ PHP-FPM ไปจนถึง trace แรกที่มองเห็นได้จริง

เริ่มจาก Pre-check RHEL 8/9 · Agent 7 · PHP 8.x
7 manual steps Learn at your pace
Trace goalยืนยัน Traces received > 0
DATADOG APM · HANDS-ON

ทำตามทีละขั้นตอน

ทุกคำสั่งเป็นแบบ manual และผลตัวอย่างด้านล่างมาจากการทดสอบจริงบน RHEL 9.8

Terraform scope

lab/ สร้างเฉพาะ EC2 + encrypted volume + IAM/SSM ส่วน Apache, PHP-FPM, sample app และ Datadog ให้ทำตาม 7 ขั้นตอนด้านล่างด้วยตนเอง

01
STEP 01

สำรวจเครื่องก่อนติดตั้ง

3 min

บันทึก OS, เวอร์ชัน runtime, สถานะ service และ endpoint ของ PHP-FPM ก่อนแก้ configuration

bash · EC2
cat /etc/redhat-release
php -v || true
php-fpm -v || true
httpd -v || true

sudo systemctl status httpd --no-pager || true
sudo systemctl status php-fpm --no-pager || true
sudo grep -E '^[; ]*listen[ .=]' /etc/php-fpm.d/www.conf || true

# ตรวจ outbound ที่ Agent ต้องใช้
curl -I --max-time 10 https://app.datadoghq.com

ผ่านเมื่อ ยืนยันได้ว่าเป็น RHEL 8/9 และออก HTTPS ไป Datadog ได้

ผลทดสอบจริงRHEL 9.8 · x86_64 · SSM activehttpd, php-fpm, datadog-agent: not installed
02
STEP 02

ติดตั้ง Apache และ PHP-FPM

5 min

ติดตั้ง package มาตรฐานของ RHEL แล้วเปิด service ให้เริ่มพร้อมระบบ

bash · EC2
sudo dnf install -y httpd php php-fpm php-cli curl

# แลปนี้ใช้ Security Group ที่มี inbound กว้าง จึง bind เฉพาะ localhost
sudo sed -i 's/^Listen 80$/Listen 127.0.0.1:80/' /etc/httpd/conf/httpd.conf

sudo systemctl enable --now php-fpm httpd

sudo apachectl configtest
systemctl is-active httpd php-fpm
curl -I http://127.0.0.1/

ผ่านเมื่อ configtest แสดง Syntax OK และ service ทั้งสองเป็น active

ผลทดสอบจริงApache 2.4.62 · PHP-FPM 8.0.30Syntax OK · httpd active · php-fpm active · 127.0.0.1:80
03
STEP 03

สร้าง PHP endpoint สำหรับยิง traffic

5 min

ตัวอย่างมี latency หลายช่วงเพื่อให้ trace flame graph อ่านง่าย โดยไม่ต้องมีฐานข้อมูลภายนอก

bash · EC2
sudo tee /var/www/html/index.php >/dev/null <<'PHP'
<?php
header('Content-Type: application/json');

function loadCatalog(): array {
    usleep(random_int(15000, 45000));
    return ['agent', 'apm', 'integration'];
}

$started = microtime(true);
$items = loadCatalog();
usleep(random_int(5000, 20000));

echo json_encode([
    'service' => 'customer-demo-php',
    'status' => 'ok',
    'items' => $items,
    'duration_ms' => round((microtime(true) - $started) * 1000, 2)
], JSON_PRETTY_PRINT);
PHP

sudo restorecon -Rv /var/www/html
curl -s http://127.0.0.1/index.php

ผ่านเมื่อ ได้ JSON ที่มี "status": "ok"

ผลทดสอบจริงApache → PHP-FPM socket ทำงาน{ "service": "customer-demo-php", "status": "ok" }
05
STEP 05

กำหนด tags และ SELinux policy

15 min

PHP-FPM มักใช้ clear_env=yes จึงกำหนด Unified Service Tags ใน pool โดยตรง และบังคับ tracer ส่งไป Agent ผ่าน localhost TCP 8126

ini · /etc/php-fpm.d/www.conf
env[DD_SERVICE] = customer-demo-php
env[DD_ENV] = dev
env[DD_VERSION] = 1.0.0
env[DD_TRACE_ENABLED] = true
env[DD_LOGS_INJECTION] = true
env[DD_TRACE_AGENT_URL] = http://127.0.0.1:8126

ให้ SSI เห็น endpoint ตั้งแต่เริ่ม service ด้วย systemd drop-in:

bash · systemd drop-in
sudo install -d -m 755 /etc/systemd/system/php-fpm.service.d
sudo tee /etc/systemd/system/php-fpm.service.d/datadog-apm.conf >/dev/null <<'EOF'
[Service]
Environment="DD_TRACE_AGENT_URL=http://127.0.0.1:8126"
EOF
ห้ามปิด SELinux

บน RHEL 9.8 ที่ทดสอบ AppSec sidecar ถูกบล็อกและทำให้ PHP-FPM worker abort จึงใช้ policy ที่จำกัดเฉพาะสิทธิ์และ port ของงานนี้ ไม่ใช้ setenforce 0 และไม่สร้าง policy กว้างด้วย audit2allow

เปิด sudo vi /tmp/datadog_php_sidecar.te แล้ววาง policy ต่อไปนี้:

selinux · /tmp/datadog_php_sidecar.te
module datadog_php_sidecar 1.2;

require {
    type httpd_t;
    type httpd_tmpfs_t;
    type ld_so_t;
    attribute port_type;
    class file { execute execute_no_trans };
    class tcp_socket name_connect;
}

type datadog_apm_port_t;
typeattribute datadog_apm_port_t port_type;

allow httpd_t httpd_tmpfs_t:file { execute execute_no_trans };
allow httpd_t ld_so_t:file execute_no_trans;
allow httpd_t datadog_apm_port_t:tcp_socket name_connect;
bash · compile, install & label
sudo dnf install -y policycoreutils-python-utils checkpolicy policycoreutils-devel

sudo checkmodule -M -m -o /tmp/datadog_php_sidecar.mod /tmp/datadog_php_sidecar.te
sudo semodule_package -o /tmp/datadog_php_sidecar.pp \
  -m /tmp/datadog_php_sidecar.mod
sudo semodule -i /tmp/datadog_php_sidecar.pp
sudo semanage port -a -t datadog_apm_port_t -p tcp 8126

getenforce
sudo semodule -l | grep datadog_php_sidecar
sudo semanage port -l | grep datadog_apm_port_t
bash · apply & inspect
sudo systemctl daemon-reload
sudo php-fpm -t
sudo systemctl restart php-fpm httpd

php-fpm -i | grep -iE 'ddtrace|datadog|dd_library_loader'

ผ่านเมื่อ SELinux ยังเป็น Enforcing, services เป็น active และ PHP-FPM พบ Datadog library loader

ผลทดสอบจริงSELinux Enforcing · policy 1.2 · TCP 8126Requests_OK=40 · Requests_Failed=0 · PHP tracer 1.25.1
06
STEP 06

เปิด Apache และ PHP-FPM integrations

12 min

6.1 Apache mod_status

apache · /etc/httpd/conf.d/datadog-status.conf
<Location "/server-status">
    SetHandler server-status
    Require local
</Location>

ExtendedStatus On
yaml · /etc/datadog-agent/conf.d/apache.d/conf.yaml
init_config:

instances:
  - apache_status_url: http://127.0.0.1/server-status?auto
    tags:
      - env:dev
      - service:customer-demo-php

6.2 PHP-FPM status และ ping

ini · เพิ่มใน /etc/php-fpm.d/www.conf
pm.status_path = /status
ping.path = /ping
ping.response = pong
apache · เพิ่มใน datadog-status.conf
<LocationMatch "^/(status|ping)$">
    SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost/"
    Require local
</LocationMatch>
yaml · /etc/datadog-agent/conf.d/php_fpm.d/conf.yaml
init_config:

instances:
  - status_url: http://127.0.0.1/status
    ping_url: http://127.0.0.1/ping
    ping_reply: pong
    tags:
      - env:dev
      - service:customer-demo-php
bash · restart & verify
sudo apachectl configtest
sudo php-fpm -t
sudo systemctl restart php-fpm httpd datadog-agent

curl -s 'http://127.0.0.1/server-status?auto' | head
curl -s http://127.0.0.1/status | head
curl -s http://127.0.0.1/ping

sudo datadog-agent check apache
sudo datadog-agent check php_fpm

ผ่านเมื่อ Apache และ PHP-FPM checks แสดง [OK] และ ping ตอบ pong

ผลทดสอบจริงApache 7.5.0 [OK] · PHP-FPM 6.4.1 [OK]apache.can_connect: 0 · php_fpm.can_ping: 0
07
STEP 07

สร้าง traffic และยืนยัน trace

5 min
bash · EC2
for i in {1..20}; do
  curl -fsS http://127.0.0.1/index.php >/dev/null
  sleep 0.2
done

# รอให้ Agent สรุป previous-minute receiver counters
sleep 60
sudo datadog-agent status
sudo datadog-agent health

จากนั้นไปที่ APM → Traces ใน Datadog แล้ว filter ด้วย:

service:customer-demo-php AND env:dev

ผ่านเมื่อ เห็น request traces, runtime fpm-fcgi และ Agent รายงาน traces/spans มากกว่า 0

ผลทดสอบจริง · ปิด debug แล้ว20/20 requests · Agent health PASS · Datadog HEALTH OKTraces received: 20 · Spans received: 20 · customer-demo-php / web.request
05 · RECOVERY

Troubleshooting map

เริ่มจาก symptom แล้วไล่ตรวจจุดที่ใกล้ที่สุดก่อน

01Agent ทำงาน แต่ไม่มี trace+

ตรวจ endpoint ที่ tracer เห็น, restart PHP-FPM หลังติดตั้ง SSI และยิง request เข้า PHP จริง จากนั้นรอให้ Agent เปลี่ยน previous-minute window

sudo systemctl show -p Environment php-fpm
php-fpm -i | grep -iE 'ddtrace|datadog|dd_library_loader'
curl -fsS http://127.0.0.1/index.php
sudo datadog-agent status
02Apache check เชื่อมต่อไม่ได้+

ทดสอบ URL เดียวกับใน config และยืนยันว่า Require local อนุญาต localhost

curl -v 'http://127.0.0.1/server-status?auto'
sudo apachectl -M | grep status
sudo journalctl -u httpd -n 50 --no-pager
03PHP-FPM status ได้ 404 / 503+

ตรวจ socket จาก directive listen, module proxy_fcgi และ syntax ของทั้งสอง service

sudo grep -E '^listen|^pm.status_path|^ping.path' /etc/php-fpm.d/www.conf
sudo apachectl -M | grep proxy_fcgi
sudo ls -l /run/php-fpm/www.sock
04PHP-FPM timeout / AppSec sidecar crash บน SELinux+

อาการที่พบจริงคือ Apache AH01075, PHP-FPM worker SIGABRT และ AVC execute_no_trans บน dynamic linker ใช้ policy ใน Step 05 โดยคง SELinux เป็น Enforcing และส่ง trace ผ่าน port type เฉพาะ 8126

getenforce
sudo ausearch -m AVC -ts recent | tail -30
sudo semodule -l | grep datadog_php_sidecar
sudo semanage port -l | grep datadog_apm_port_t
sudo systemctl restart php-fpm
curl -fsS http://127.0.0.1/index.php

SSI อาจยัง log AVC แบบ getattr ตอน probe Unix socket หรือ cgroup แม้ TCP trace ใช้งานได้ ให้พิจารณาผล request และ APM counters ร่วมกัน และอย่าอนุญาตทุก AVC ด้วย policy กว้างโดยไม่ review

05ต้องเก็บ log เพิ่มเพื่อส่ง Support+

สร้าง flare หลัง reproduce ปัญหา โดยตรวจข้อมูลลับก่อน upload ทุกครั้ง

sudo datadog-agent flare
sudo journalctl -u datadog-agent -n 100 --no-pager
sudo tail -100 /var/log/php-fpm/error.log
คัดลอกแล้ว