tl;dr
WEB+DB PRESS Vol.116 の記事を読んでみたメモです.
読みながら気になる単語や内容をマインドマップにまとめていきたいと思います. 今回は「特集 1: トラブルシューティング」の「第 2 章バックエンド」を読みました.
マインドマップ
メモ
憶測するな計測せよ
curl で smtp
SMTP との会話
HTTP プロトコル以外にも対応してるということなので, curl で SMTP と会話してみたいと思います.
手元で SMTP サーバーを起動
こちらの記事を参考にさせて頂きました.
Docker を利用します.
$ docker run -d -p 25:25 \ --name mailserver \ -e maildomain=example.com \ -e smtp_user=username:password \ catatnight/postfix $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 367c3f04439a catatnight/postfix "/bin/sh -c '/opt/in…" 16 minutes ago Up 16 minutes 0.0.0.0:25->25/tcp mailserver
一旦, telnet で会話してみます.
$ telnet localhost 25 Trying ::1... Connected to localhost. Escape character is '^]'. 220 example.com ESMTP Postfix (Ubuntu) HELO example.com 250 example.com MAIL FROM: from@example.com 250 2.1.0 Ok RCPT TO: to@example.com 454 4.7.1 <to@example.com>: Relay access denied QUIT 221 2.0.0 Bye Connection closed by foreign host.
curl でメールを送信してみる
こちらの記事を参考にさせて頂きました.
以下のようなテキストファイルを用意します. このテキストファイルを test.txt というファイル名で保存します.
To: to@example.com From: from@example.com Subject: this is a test hello world!
以下のように curl コマンドでメールを送信します.
$ curl -sv smtp://localhost:25 --mail-from 'from@example.com' --mail-rcpt 'to@example.com' -u username -T test.txt
以下のように出力されました.
Enter host password for user 'username': * Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 25 (#0) < 220 example.com ESMTP Postfix (Ubuntu) > EHLO test.txt < 250-example.com < 250-PIPELINING < 250-SIZE 10240000 < 250-VRFY < 250-ETRN < 250-STARTTLS < 250-AUTH PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM < 250-AUTH=PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM < 250-ENHANCEDSTATUSCODES < 250-8BITMIME < 250 DSN > AUTH DIGEST-MD5 < 334 bm9uY2U9IjJJZnVhc1JVbnRTdjVpcmFuRXpYY0k1NklPeWFiMXF2YmdrKzdSL2JhMkE9IixyZWFsbT0iZXhhbXBsZS5jb20iLHFvcD0iYXV0aCIsY2hhcnNldD11dGYtOCxhbGdvcml0aG09bWQ1LXNlc3M= > dXNlcm5hbWU9InVzZXJuYW1lIixyZWFsbT0iZXhhbXBsZS5jb20iLG5vbmNlPSIySWZ1YXNSVW50U3Y1aXJhbkV6WGNJNTZJT3lhYjFxdmJnays3Ui9iYTJBPSIsY25vbmNlPSJlODcwZWFlMDNhOWQ5MGYwZjQyNTQ4OWJlMmNjOGI4YiIsbmM9IjAwMDAwMDAxIixkaWdlc3QtdXJpPSJzbXRwL2V4YW1wbGUuY29tIixyZXNwb25zZT1lZWFhNTliY2ZiNjJkMmUwZWI2MWYzM2JiOGU2MTA1Mixxb3A9YXV0aA== < 334 cnNwYXV0aD1kMWYxNmI4ODUzZGJkMjRlZTdjZmY0YTE4MjhiZjM3MQ== > < 235 2.7.0 Authentication successful > MAIL FROM:<from@example.com> SIZE=80 < 250 2.1.0 Ok > RCPT TO:<to@example.com> < 250 2.1.5 Ok > DATA < 354 End data with <CR><LF>.<CR><LF> } [80 bytes data] * We are completely uploaded and fine < 250 2.0.0 Ok: queued as 1448D342D47 * Connection #0 to host localhost left intact
SMTP のやりとりを確認することが出来ました.
trdsql について
ログを SQL ライクに検索出来る
ログを SQL ライクな構文で検索出来る trdsql というツールを初めて知ったので少し触ってみました. 尚, 動作検証環境は以下の通りです.
root@6dc811524b1d:/work# cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 10 (buster)" NAME="Debian GNU/Linux" VERSION_ID="10" VERSION="10 (buster)" VERSION_CODENAME=buster ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" root@6dc811524b1d:/work# ruby --version ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux] root@6dc811524b1d:/work# gem list | grep apache apache-loggen (0.0.5) root@6dc811524b1d:/work# ./trdsql_v0.7.5_linux_amd64/trdsql --version trdsql version v0.7.5 $ sw_vers ProductName: Mac OS X ProductVersion: 10.14.6 BuildVersion: 18G3020 $ ~/bin/trdsql --version trdsql version v0.7.5
ログの用意
Apache のログを用意します. Apache のダミーログを用意するには, apache_log_gen がとても便利です.
以下のように出力しました.
$ apache-loggen --json --limit=5000 sample.log
JSON フォーマットで 5000 件のログを生成して sample.log というファイルを生成しています.
検索
trdsql でログを検索してみたいと思います. まずは, ステータスコード 200 以外のログを抽出してみます.
$ ~/bin/trdsql -ijson -oat "SELECT path,code,count(path) AS count \ FROM sample.log WHERE code != '200' \ GROUP BY path, code ORDER BY count DESC"
-ijson
はJSON フォーマットのログを読み込むオプション, -oat
は ASCII Table 形式で出力するオプションです.
以下のように出力されました.
+------------------------+------+-------+ | path | code | count | +------------------------+------+-------+ | /item/games/2228 | 404 | 4 | | /item/electronics/2168 | 404 | 3 | | /item/games/452 | 404 | 3 | +------------------------+------+-------+
念の為, ログを Linux コマンドを駆使して抽出してみました.
$ grep -v '"code":200' sample.log | jq -r .path | sort | uniq -c | sort -r 4 /item/games/2228 3 /item/games/452 3 /item/electronics/2168
続いて, 接続元の IP アドレス毎にアクセス件数を確認してみます.
$ ~/bin/trdsql -ijson -oat "SELECT host, count(host) AS count \ FROM sample.log GROUP BY host ORDER BY count DESC LIMIT 20"
以下のような結果となりました.
+-----------------+-------+ | host | count | +-----------------+-------+ | 84.144.85.122 | 11 | | 28.186.132.148 | 10 | | 216.93.121.144 | 10 | | 216.177.205.222 | 10 | | 208.135.120.209 | 10 | | 188.123.189.209 | 10 | | 180.225.208.155 | 10 | | 124.75.103.212 | 10 | | 112.69.129.87 | 10 | | 104.21.41.136 | 10 | | 100.90.123.168 | 10 | | 96.132.66.43 | 9 | | 96.126.37.143 | 9 | | 92.144.43.39 | 9 | | 88.162.143.128 | 9 | | 60.90.182.138 | 9 | | 40.21.86.73 | 9 | | 40.141.66.26 | 9 | | 28.105.160.88 | 9 | | 24.189.98.124 | 9 | +-----------------+-------+
おおー. 素晴らしい. SQL でログを直接検索出来るのは SQL が苦手な自分でも頑張りたくなります.
以上
やっぱ, 「憶測するな計測せよ」はトラブルシューティングの鉄板. そして, trdsql に出会えたのは最高でした. これはギョームで使っていこうと思います.