Goのアプリをsystemdで動かせてみた
前回はGo言語の動かす所までを記載しましたが、毎回コンパイルして、実行。
リリースなどで再起動するときはプロセスを見つけて、それをkillしてまた実行
というプロセスがかなり面倒だったので、Unit定義ファイルを作成してGoのWEBアプリのsystemdをデーモンとして作るよう試みました。
シェルスクリプトを駆使して自動化もできるのですが、シェルのスクリプトのコード量が大きくなれば属人的にななってしまうのではという懸念と、デーモンを作った結果想定していたより簡単だったので、systemdのデーモンがいいのではという事も含めてメモ代わりに記録しておきます。
まずは下記のUnit定義ファイルが完成形です。
Unit セクション |
|
Description | このサービスが何なのかをフリーテキストで記載するところ |
Service セクション |
|
ExecStart | これがメイン。起動するコマンドをここに記載 |
WorkingDirectory | 自分が作るGo言語アプリの場合カレントディレクトリにそのソースコードのトップ main.goがあるディレクトリから実行しないと動かないのでこの機能はありがたい、 なかった場合は実現不可能かGoアプリの作り方を考え直す必要があった |
Restart | 基本noでいいかと。 alwaysとかにすると2次災害とかが怖いので |
Type | はじめsimpleに設定してログの上書き問題を解決するためにoneshotにしたけど、 oneshotにしたらそのコンソール上で実行するのと変わらないのでsimpleに戻した |
User | 実行ユーザー |
StandardOutput | 通常ログが吐かれる場所 systemとかに設定すると/var/log/とかに保存されるみたい でも今回はアプリのログなので、同じディレクトリのログディレクトリにしました |
StandardError | StandardOutputのエラー版 具体的にどういうエラー時に吐かれるかは試していない |
Install セクション |
|
WantedBy | いまいちわからないけど、すべてのWEB記事でmulti-user.targetだったので、そうしておきます |
ログに関して追記されないみたいな記事があったので、その挙動を調査してみたのですが、ログが追記されたりされなかったり、時間差でロギングされたりなとなかなかつかめない部分も多いです。
ゆっくり時間をおいてログをみながら確認すると
sudo systemctl restart blog(アプリのデーモン名)
で再起動してからはログファイルが上から書き換わってきています。
なので実運用時にはアプリのデーモン再起動の前にログファイル名を書き換えるなどが必要になってくるかと思います。
ちょっとそこがイケてないですね。。
もっと簡単にスマートにログが収集できてろてーともしてくれるやり方があれば教えてください。
>> /var/www/blog/log/go$(date +%Y_%m_%d).log
のようにUnit定義ファイルをシェルスクリプトみたいに使おうとしたのですが、そもそも動的に変数のような扱いができない!?
少なくとも自分が調べた限りと実際に動かしてみた限りでは直接変数は使えなかったです。
環境変数を利用する事もできますが、そこまでのめりこむとそれはそれでスマートなやり方ではなくなってきてしまいます。
シェルスクリプト内にGo言語を起動するように作ればいくらでも実現は可能なのですが、それではもはやGoのアプリではなくて、シェアるスクリプトのデーモンになってしまいます。
ログロテートでほぼリアルタイムにログの複製をしておくのが一番わかりやすくてスマートなやり方なのではと今の結論です。
ただ、このブログ程度のアプリの規模であればログロテートですら面倒なので、とりあえずこのまま放置しておきます。
完全にログが見れなくなるわけではないので、まぁいっかっていう程度です。
以下参考になったページ
man systemd.service 日本語訳 - Qiita
systemdを使ってsynergycを自動起動する - Qiita
systemd環境でアプリのログをsyslogに流してlogrotateする - Qiita
登録日:
更新日: