Go言語でロギングを学ぼう!

こんにちは。KOUKIです。

とある企業でGo言語を使ったアプリ開発をしています。

最近は、goroutineを使った並行処理プログラミングの勉強をしていて、本記事では、それを組み合わせてロギングを作りました。

ワークスペースの作成

最初にワークスペースを作成してください。

ログ出力をgoroutine化する意義

ログ出力と書いてますが、標準出力ととらえていただいても問題ないです。

go言語では、fmt/logパッケージにて、情報を出力する関数を利用することができます。

結果は、以下の通りです。

これらの関数は、ログやデバック、エラーメッセージなどに利用されますよね。

普段何気なく使っていたのですが、もし仮に「大容量のデータを出力する」ようなことがあった場合、どうなるのでしょうか。

おそらく、一旦処理が停止すると思うんですよね。例えば、こんな感じに。

上記のコードは、”test string”を100000回結合したものをlog.Printlnでログ出力しました。このコードを実行すると次の結果になります。

処理の完了までに「1.653652417s」もかかっています。

仮に後続処理があった場合、その時間分だけ遅れが生じます。

Go言語は高速処理が自慢の言語であるため、goroutineを使って改善したいなぁと思った次第です。

実装

ロガーの作成

goroutineを活用するロガーを独自に作りましょう。作成手順は、こんな感じです。

loggerの作成手順 1. メッセージをやり取りするチャネルを作成
2. goroutine + for + selectを組み合わせたサブプロセス処理を作成
3. チャネルからメッセージを送信する関数を作成

実装してみましょう。

上記のような「goroutine + for + select」はパターンとしてよく利用されますね。覚えておくと便利です。

main関数の実装

先ほど定義したloggerを利用してみましょう。

ロガーを使うには、「logger.Setup(os.Stdout)」で初期化します。引数にはlogger.goに設定したl *log.Loggerを生成するため、os.Stdoutを渡しています。

そして、今回はログ出力が「別プロセスで動くこと」を確認できればいいので、time.Sleepを入れて別プロセスが完了するのを待っています。

プログラムを実行してみましょう。

log.New(out, "", log.Ldate|log.Ltime)にて、プレフィックス(Ldate/Ltime)を設定しているので、「2021/01/12 8:37:45」のように日時が出力されています。その後、出力レベルに従った文字列(Info:など)とメッセージ内容も出力されているので、これで概ねOKでしょう。

ロギングとしてはパワー不足かもしれませんが、必要な機能は随時追加していただければ幸いです^^

おわりに

昔記事にした「Pythonでロギングを学ぼう」を久しぶりに読み返して、Go言語でもやってみようと思い、この記事を書きました。

昔はPythonの方が好きでしたが、今ではGo言語の方が好きになりつつあります。

日本でもっとGo言語が流行ればいいのにと思います。

それでは、また!

Goオススメ本

Go記事まとめ

コメントを残す