Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPとFluentdで実現するリアルタイムログ分析

picopico
March 09, 2024
91

 PHPとFluentdで実現するリアルタイムログ分析

picopico

March 09, 2024
Tweet

Transcript

  1. (例)Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
  2. (例)Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" →構造化されていない、独自のシンプルな形式が多い
  3. 20 想定シナリオ: あるウェブアプリケーションが毎日平均して 100万回のアクセスを受けるとします。各アクセスは、ユー ザー認証、ページビュー、 APIリクエストなど複数のログエントリを生成すると仮定します。 ログ量の推計 1アクセスあたりのログエントリ数 : 5件(認証、ページビュー、

    APIリクエストx3) 1日あたりの総ログエントリ数 : 100万アクセス × 5 = 500万件 1ログエントリの平均サイズ : 500バイト(日時、セッション ID、アクション詳細などを含む) これらの値を元に1日あたりのログデータの総量を計算すると、
  4. 21 想定シナリオ: あるウェブアプリケーションが毎日平均して 100万回のアクセスを受けるとします。各アクセスは、ユー ザー認証、ページビュー、 APIリクエストなど複数のログエントリを生成すると仮定します。 ログ量の推計 1アクセスあたりのログエントリ数 : 5件(認証、ページビュー、

    APIリクエストx3) 1日あたりの総ログエントリ数 : 100万アクセス × 5 = 500万件 1ログエントリの平均サイズ : 500バイト(日時、セッション ID、アクション詳細などを含む) これらの値を元に1日あたりのログデータの総量を計算すると、 1日あたりのログデータ量: 500万件 × 500バイト = 2,500,000,000バイト(約2.33GB)
  5. [08-Mar-2023 12:00:00 UTC] PHP Warning: Division by zero in /path/to/your/script.php

    on line 10 [08-Mar-2023 12:00:02 UTC] PHP Fatal error: Uncaught Error: Call to undefined function testFunction() in /path/to/your/script.php:15 PHPのエラーログ
  6. [08-Mar-2023 12:00:00 UTC] PHP Warning: Division by zero in /path/to/your/script.php

    on line 10 [08-Mar-2023 12:00:02 UTC] PHP Fatal error: Uncaught Error: Call to undefined function testFunction() in /path/to/your/script.php:15 PHPのエラーログ タイムスタンプ
  7. [08-Mar-2023 12:00:00 UTC] PHP Warning: Division by zero in /path/to/your/script.php

    on line 10 [08-Mar-2023 12:00:02 UTC] PHP Fatal error: Uncaught Error: Call to undefined function testFunction() in /path/to/your/script.php:15 PHPのエラーログ エラーの種類
  8. [08-Mar-2023 12:00:00 UTC] PHP Warning: Division by zero in /path/to/your/script.php

    on line 10 [08-Mar-2023 12:00:02 UTC] PHP Fatal error: Uncaught Error: Call to undefined function testFunction() in /path/to/your/script.php:15 PHPのエラーログ エラーの詳細、発生場所
  9. Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
  10. Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" IPアドレス
  11. Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" リモートユーザー名・ユーザーID
  12. Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" タイムスタンプ
  13. Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" リクエスト
  14. Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" HTTPステータスコード・バイト数
  15. Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" リファラ
  16. Nginxのアクセスログ 192.168.1.1 - - [08/Mar/2023:12:00:00 +0000] "GET /index.html HTTP/1.1" 200

    612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" ユーザーエージェント
  17. MySQLのログ 2023-03-08T12:00:00.000000Z 0 [Note] InnoDB: Buffer pool(s) load completed at

    230308 8:00:00 2023-03-08T12:00:00.000000Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode. 2023-03-08T12:00:00.000000Z 0 [ERROR] Cannot open table test/users from the internal data dictionary of InnoDB though the .frm file for the table exists.
  18. MySQLのログ 2023-03-08T12:00:00.000000Z 0 [Note] InnoDB: Buffer pool(s) load completed at

    230308 8:00:00 2023-03-08T12:00:00.000000Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode. 2023-03-08T12:00:00.000000Z 0 [ERROR] Cannot open table test/users from the internal data dictionary of InnoDB though the .frm file for the table exists. タイムスタンプ
  19. MySQLのログ 2023-03-08T12:00:00.000000Z 0 [Note] InnoDB: Buffer pool(s) load completed at

    230308 8:00:00 2023-03-08T12:00:00.000000Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode. 2023-03-08T12:00:00.000000Z 0 [ERROR] Cannot open table test/users from the internal data dictionary of InnoDB though the .frm file for the table exists. プロセスID
  20. MySQLのログ 2023-03-08T12:00:00.000000Z 0 [Note] InnoDB: Buffer pool(s) load completed at

    230308 8:00:00 2023-03-08T12:00:00.000000Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode. 2023-03-08T12:00:00.000000Z 0 [ERROR] Cannot open table test/users from the internal data dictionary of InnoDB though the .frm file for the table exists. ログレベル
  21. MySQLのログ 2023-03-08T12:00:00.000000Z 0 [Note] InnoDB: Buffer pool(s) load completed at

    230308 8:00:00 2023-03-08T12:00:00.000000Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode. 2023-03-08T12:00:00.000000Z 0 [ERROR] Cannot open table test/users from the internal data dictionary of InnoDB though the .frm file for the table exists. ログ内容
  22. システムログ(syslog) Mar 8 12:00:00 myhost systemd[1]: Started Session 1234 of

    user root. Mar 8 12:05:00 myhost sshd[23456]: Accepted publickey for user1 from 192.168.1.100 port 22 ssh2 Mar 8 12:10:00 myhost CRON[23457]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1) Mar 8 12:15:00 myhost kernel: [123456.789012] Firewall: *TCP_IN Blocked* IN=eth0 OUT= MAC=01:23:45:67:89:ab:cd:ef:gh:ij:kl:mn SRC=10.1.2.3 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=12345 DF PROTO=TCP SPT=12345 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0
  23. システムログ(syslog) Mar 8 12:00:00 myhost systemd[1]: Started Session 1234 of

    user root. Mar 8 12:05:00 myhost sshd[23456]: Accepted publickey for user1 from 192.168.1.100 port 22 ssh2 Mar 8 12:10:00 myhost CRON[23457]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1) Mar 8 12:15:00 myhost kernel: [123456.789012] Firewall: *TCP_IN Blocked* IN=eth0 OUT= MAC=01:23:45:67:89:ab:cd:ef:gh:ij:kl:mn SRC=10.1.2.3 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=12345 DF PROTO=TCP SPT=12345 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0 タイムスタンプ
  24. システムログ(syslog) Mar 8 12:00:00 myhost systemd[1]: Started Session 1234 of

    user root. Mar 8 12:05:00 myhost sshd[23456]: Accepted publickey for user1 from 192.168.1.100 port 22 ssh2 Mar 8 12:10:00 myhost CRON[23457]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1) Mar 8 12:15:00 myhost kernel: [123456.789012] Firewall: *TCP_IN Blocked* IN=eth0 OUT= MAC=01:23:45:67:89:ab:cd:ef:gh:ij:kl:mn SRC=10.1.2.3 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=12345 DF PROTO=TCP SPT=12345 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0 ホスト名
  25. システムログ(syslog) Mar 8 12:00:00 myhost systemd[1]: Started Session 1234 of

    user root. Mar 8 12:05:00 myhost sshd[23456]: Accepted publickey for user1 from 192.168.1.100 port 22 ssh2 Mar 8 12:10:00 myhost CRON[23457]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1) Mar 8 12:15:00 myhost kernel: [123456.789012] Firewall: *TCP_IN Blocked* IN=eth0 OUT= MAC=01:23:45:67:89:ab:cd:ef:gh:ij:kl:mn SRC=10.1.2.3 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=12345 DF PROTO=TCP SPT=12345 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0 プロセス名とプロセスID
  26. システムログ(syslog) Mar 8 12:00:00 myhost systemd[1]: Started Session 1234 of

    user root. Mar 8 12:05:00 myhost sshd[23456]: Accepted publickey for user1 from 192.168.1.100 port 22 ssh2 Mar 8 12:10:00 myhost CRON[23457]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1) Mar 8 12:15:00 myhost kernel: [123456.789012] Firewall: *TCP_IN Blocked* IN=eth0 OUT= MAC=01:23:45:67:89:ab:cd:ef:gh:ij:kl:mn SRC=10.1.2.3 DST=192.168.1.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=12345 DF PROTO=TCP SPT=12345 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0 ログ内容
  27. バッチ処理の例 total 40 -rw-r--r-- 1 root root 1024 Mar 5

    00:00 app.log-20230304 -rw-r--r-- 1 root root 20480 Mar 6 00:00 app.log-20230305 -rw-r--r-- 1 root root 10240 Mar 7 00:00 app.log-20230306 -rw-r--r-- 1 root root 5120 Mar 8 00:00 app.log-20230307 -rw-r--r-- 1 root root 123 Mar 8 12:00 app.log
  28. バッチ処理の例 total 40 -rw-r--r-- 1 root root 1024 Mar 5

    00:00 app.log-20230304 -rw-r--r-- 1 root root 20480 Mar 6 00:00 app.log-20230305 -rw-r--r-- 1 root root 10240 Mar 7 00:00 app.log-20230306 -rw-r--r-- 1 root root 5120 Mar 8 00:00 app.log-20230307 -rw-r--r-- 1 root root 123 Mar 8 12:00 app.log 1日ごとに処理する
  29. バッチ処理の例 total 40 -rw-r--r-- 1 root root 1024 Mar 5

    00:00 app.log-20230304 -rw-r--r-- 1 root root 20480 Mar 6 00:00 app.log-20230305 -rw-r--r-- 1 root root 10240 Mar 7 00:00 app.log-20230306 -rw-r--r-- 1 root root 5120 Mar 8 00:00 app.log-20230307 -rw-r--r-- 1 root root 123 Mar 8 12:00 app.log 1日ごとに処理する
  30. バッチ処理の例 total 40 -rw-r--r-- 1 root root 1024 Mar 5

    00:00 app.log-20230304 -rw-r--r-- 1 root root 20480 Mar 6 00:00 app.log-20230305 -rw-r--r-- 1 root root 10240 Mar 7 00:00 app.log-20230306 -rw-r--r-- 1 root root 5120 Mar 8 00:00 app.log-20230307 -rw-r--r-- 1 root root 123 Mar 8 12:00 app.log 1日ごとに処理する
  31. バッチ処理の例 total 40 -rw-r--r-- 1 root root 1024 Mar 5

    00:00 app.log-20230304 -rw-r--r-- 1 root root 20480 Mar 6 00:00 app.log-20230305 -rw-r--r-- 1 root root 10240 Mar 7 00:00 app.log-20230306 -rw-r--r-- 1 root root 5120 Mar 8 00:00 app.log-20230307 -rw-r--r-- 1 root root 123 Mar 8 12:00 app.log 1日ごとに処理する
  32. ストリーム処理の例 (app.log) [2023-03-08 12:00:01 UTC] PHP Warning: include(/path/to/file/mi [2023-03-08 12:01:02

    UTC] PHP Notice: Undefined variable: usern [2023-03-08 12:02:03 UTC] PHP Fatal error: Uncaught Error: Call Stack trace: #0 {main} thrown in /path/to/your/script.php on line 70
  33. ストリーム処理の例 (app.log) [2023-03-08 12:00:01 UTC] PHP Warning: include(/path/to/file/mi [2023-03-08 12:01:02

    UTC] PHP Notice: Undefined variable: usern [2023-03-08 12:02:03 UTC] PHP Fatal error: Uncaught Error: Call Stack trace: #0 {main} thrown in /path/to/your/script.php on line 70
  34. Fluentdの特徴 60 • Unified Logging with JSON • Pluggable Architecture

    • Minimum Resources Required • Built-in Reliability
  35. Fluentdの特徴 61 • Unified Logging with JSON • Pluggable Architecture

    • Minimum Resources Required • Built-in Reliability
  36. 62 イベント [08-Mar-2023 12:00:00 UTC] PHP Warning: Division by zero

    in /path/to/your/script.php on line 10 [“app.log”, 2023-03-08T12:00:00Z, {"level": "WARNING","message": "Division by zero", …}] Input
  37. 63 イベント [08-Mar-2023 12:00:00 UTC] PHP Warning: Division by zero

    in /path/to/your/script.php on line 10 [“app.log”, 2023-03-08T12:00:00Z, {"level": "WARNING","message": "Division by zero", …}] Inputプラグインがログからイベ ントを生成する Input
  38. Fluentdの特徴 64 • Unified Logging with JSON • Pluggable Architecture

    • Minimum Resources Required • Built-in Reliability
  39. 66

  40. Fluentdの特徴 67 • Unified Logging with JSON • Pluggable Architecture

    • Minimum Resources Required • Built-in Reliability
  41. Fluentdの特徴 69 • Unified Logging with JSON • Pluggable Architecture

    • Minimum Resources Required • Built-in Reliability
  42. fluent.conf <source> @type forward </source> <filter app.**> @type grep <regexp>

    key level pattern /^ERROR$/ </regexp> </filter> <match app.**> @type file path /var/log/fluentd/error_logs </match>
  43. fluent.conf <source> @type forward </source> <filter app.**> @type grep <regexp>

    key level pattern /^ERROR$/ </regexp> </filter> <match app.**> @type file path /var/log/fluentd/error_logs </match>
  44. fluent.conf <source> @type forward </source> <filter app.**> @type grep <regexp>

    key level pattern /^ERROR$/ </regexp> </filter> <match app.**> @type file path /var/log/fluentd/error_logs </match>
  45. fluent.conf <source> @type forward </source> <filter app.**> @type grep <regexp>

    key level pattern /^ERROR$/ </regexp> </filter> <match app.**> @type file path /var/log/fluentd/error_logs </match>
  46. ディレクティブ 81 • <source>: 入力 • <match>: 出力 • <parse>:

    ログの構造化 • <filter>: ログの選択・加工 • <buffer>: バッファリング • …
  47. Fluentdの設定(AP側) <source> @type tail path /var/log/app.log pos_file /var/log/app.log.pos tag php.error

    <parse> @type regexp expression /^(?<time>[^ ]* [^ ]*) (?<type>[^:]*): (?<message time_format %d-%b-%Y %H:%M:%S types time:time,type:string,message:string,file:string,line: </parse> </source>
  48. Fluentdの設定(Aggregator側) <match php.error> @type mysql_bulk host mysql database db username

    root password root column_names time,type,message,file,line table php_errors <buffer> flush_interval 10s </buffer> </match>