三部作に分かれる記事となりました。
今回で完結です!
前回、前々回の記事はこちら↓
要件のおさらいから始めます。
要件
- アクセスログとエラーログをそれぞれ別ファイルで保管したい
- 1日1ファイルで日付が変わると新しいファイルにログが書き込まれるようにしたい
- 元々書き込まれていたログは新しいファイルに書き込まれたタイミングで消える
- ファイル名はファイルが作られた時の日付
- ログのローテーション(保存期間)は1週間
- ログファイルができたタイミングでslack通知(新しい要件)
前回まででローカルのDocker上で指定した時間にローテーションできることまで確認できました。
今回は本番環境サーバーに設定をしていきます。
ローカルと本番で若干ユーザーが異なったりしたので備忘録として書きます。
本番サーバーでのファイル設定
基本的にローカルと同じです。以下3つのファイルを追加します。
Linuxの操作コマンドがわからないときはこちらをどうそ↓
1. etc/cron.d
にsample-project
ファイルを作成
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
# PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
0 4 * * * root /usr/local/bin/get_daily_log.sh
本番ではslack通知するという要件も追加されたので、ローテーションの実行とslackの通知をまとめてシェルスクリプトにしました。毎日4時にget_daily_log.sh
が実行されます。
2.etc/logrotate.d
にsample-project
を追加
ローテーションの設定ファイルです。
ローカルではユーザーをdevel-server
にしていましたが、本番ではubuntu
だったのでubuntu
に合わせています。
/home/ubuntu/sample-project/apps/sample-project/log/*.log {
daily
rotate 7
nocompress
missingok
notifempty
copytruncate
dateext
dateformat %Y-%m-%d
dateyesterday
extension .log
create 640 ubuntu ubuntu
olddir /home/ubuntu/sample-project/apps/sample-project/log/old
createolddir 755 ubuntu ubuntu
su ubuntu ubuntu
}
logrotate.d
をls -l
し、パーミションを確認するとrootユーザーに読み書きの権限がある状態なので、rootユーザーに変えてファイルを作るなどしてパーミション情報を合わせます。
ubuntu@dummy:/etc/logrotate.d$ ls -l
total 60
-rw-r--r-- 1 root root 120 Sep 12 2021 alternatives
-rw-r--r-- 1 root root 126 Oct 27 2021 apport
-rw-r--r-- 1 root root 173 Apr 8 2022 apt
-rw-r--r-- 1 root root 91 Mar 18 2022 bootlog
-rw-r--r-- 1 root root 130 Oct 14 2019 btmp
-rw-r--r-- 1 root root 112 Sep 12 2021 dpkg
-rw-r--r-- 1 root root 336 Mar 15 16:32 nginx
-rw-r--r-- 1 root root 329 May 31 2023 nginx.org
-rw-r--r-- 1 root root 380 Apr 8 11:33 sample-project
-rw-r--r-- 1 root root 173 Feb 21 2021 postgresql-common
-rw-r--r-- 1 root root 374 Dec 24 2021 rsyslog
-rw-r--r-- 1 root root 270 Mar 8 2022 ubuntu-advantage-tools
-rw-r--r-- 1 root root 209 Sep 19 2021 ufw
-rw-r--r-- 1 root root 235 Feb 19 2021 unattended-upgrades
-rw-r--r-- 1 root root 145 Oct 14 2019 wtmp
3. usr/local/bin
にシェルスクリプトの配置
get_daily_log.sh
という名前で作成しました。
###
### Phoenix の日次ログをローテートする
###
# 通知のPrefix
NOTIFICATION_PREFIX="[日次Phoenixログローテート処理]"
# エラー通知のPrefix
ERROR_NOTIFICATION_PREFIX=":exclamation:$NOTIFICATION_PREFIX"
# 正常終了通知のPrefix
INFO_NOTIFICATION_PREFIX=":information_source:$NOTIFICATION_PREFIX"
# logrotate実行パス
LOGROTATE_CONF="/etc/logrotate.d/sample-project"
/usr/sbin/logrotate $LOGROTATE_CONF
result=$?
# logrotateの実行結果に応じて通知を送信
if [ $result -eq 0 ]; then
send_slack_notification.sh "$INFO_NOTIFICATION_PREFIX logrotate処理が正常に終了しました。"
else
send_slack_notification.sh "$ERROR_NOTIFICATION_PREFIX logrotate処理に失敗しました。 result_code: $result"
exit 1
fi
exit 0
send_slack_notification.sh
にslackの通知先URLなどが書かれています。
本番サーバーTips
本番サーバーはコンソール1つで操作するため特殊なコマンド操作も必要です。
今回は、使用したコマンドについて解説します。
ジョブサービスについてDockerはsysvinit
で本番はsystemed
を使用
どちらもLinuxシステムでプロセスの初期化と管理を行うシステムですが、それぞれに異なる設計思想と機能があります。
SysVinit
- 歴史的背景: SysVinitは古いLinuxおよびUNIXシステムの標準的な初期化システムで、シンプルなスクリプトベースのアプローチを採用
- スクリプトベース: SysVinitは、/etc/init.d/ディレクトリに配置されたスタートアップスクリプトを使用してサービスを管理。これらのスクリプトは手動で書く必要があり、依存関係の管理が難しい
- ランレベル: システムの異なる状態(ランレベル)に応じて、特定のサービスを起動または停止。ランレベルは、マルチユーザーモード、シングルユーザーモード、シャットダウンなどの状態を定義
- シンプルな管理: SysVinitは基本的な機能しか提供しないため、システムリソースの消費は少ないですが、現代の多くの要求には対応できない場合がある
systemd
- 近代的なアプローチ: systemdはSysVinitの問題点を解決するために設計されたモダンな初期化システムで、より効率的なサービス管理とシステムの起動時間の短縮を実現
- 依存関係の自動解決: systemdはサービス間の依存関係を自動的に解決し、サービスを適切な順序で起動します。これにより、システムの起動がより速く、確実に
- 統合された機能: ログ管理(journalctl)、タイマー(cronの代替)、ユーザーセッションの管理、スナップショット機能など、多くの統合された機能を提供
コンフィグレーションファイル: systemdは.serviceファイルを用いてサービスを管理し、これによりサービスの設定と管理がより簡単かつ柔軟になる
systemd
の場合のジョブの起動
systemctl restart cron.service
起動の確認
systemctl status cron.servicie
サーバーをkillするコマンド
lsof -i :4000
表示されたPID(プロセスID)を指定してkillします
kill PID
ひとつの画面上で複数のターミナルセッションを同時に実行、管理することができるツール(tmux)
tmuxは簡単にいうとコンソール。セッションを切ってもコンソールを維持し続けるのがtmux
というイメージです。
tmux
を使用する理由
- セッションの保持: サーバーにリモートで接続して作業しているときに、接続が切れた場合でも、tmux セッションは保持され、再接続時に作業をそのまま再開できる
- 複数のウィンドウとペイン: 一つの画面内で複数のウィンドウを開いたり、ウィンドウを複数のペインに分割して、複数のコマンドやアプリケーションを同時に見ることができる
- カスタマイズとスクリプト自動化: 設定ファイルを編集することで、キーバインドや外観などをカスタマイズしたり、一連のコマンドをスクリプトとして実行して、作業を効率化することが可能
コマンド
コマンド | やりたいこと |
---|---|
tmux | tmuxでコンソールを立ち上げる |
ctrl+c ctrl+D | tmuxコンソールから抜ける |
tmux -a | 直前のtmuxセッションに戻る |
tmux -ls | セッションの一覧を表示 |
Control+B とその後に D | セッションからデタッチ(切断)※ |
※現在の tmux セッションからログアウトせずに一時的に抜けるために使用します。セッションはバックグラウンドで活動を続け、後で再接続することができます。
さいごに
ローカルでログを出力し、本番で設定するところまで解説しました。Elixirの知識だけでなくUnixの知識も必要だということがわかりました。
パズルのピースが1つでもないと解けない問題を解いているような気分でした。
また、thewaggleではElixirでの開発にジョインしてくださる仲間を募集しています!
ご興味ある方、お気軽にご連絡ください。