
Go言語でログの管理するプログラムを知りたいな…
今回はGoのプログラムでログを管理するための準備についてお伝えします。
エラーハンドリングをして、そのエラーを把握するためにもログ管理は必須です。
ゆっくりと進めていくのと同時に、標準パッケージでの関数の説明はプログラム内で採用しているものに限定しますのでご了承ください。
あと、教材としては当ブログのiniファイルを読み込む記事を採用していますので、最初から理解したい方は下記の記事を参考にしてください。
記事で紹介しているコードはGitHubからダウンロードできます。
Goのプログラムでログを管理するためのファイル構成
先に、今回行う作業の最終的なファイル構成をご紹介いたします。
morip@morip-PC1:~/go/src/ini_test$ tree
.
├── config
│ └── config.go
├── config.ini
├── go.mod
├── go.sum
├── main.go
├── utils // logなどを管理するフォルダ
│ └── logging.go// log設定ファイル
└── webapp2.log // logファイル(自動生成)
2 directories, 7 files
上記のようなファイル構成で、ログ管理の準備は終了です。
テストとして main.go
で動作確認まで行いましょう。
ログ管理のためのフォルダと設定ファイル
それでは、早速、作業にとりかかりましょう。

順番通りにすすめていくだけでOKです。
ログ管理のためのフォルダと設定ファイルを作成する
~/go/src/ini_test
の直下に utils
フォルダを作成します。
utils
フォルダの直下に logging.go
ファイルを作成しましょう。
logging.goファイルにコードを記述
logging.go
ファイルに下記のコードを記述していきます。
具体的な内容に関してはコメントを参照してください。
// logging.go
package utils
import (
"io"
"log"
"os"
)
// log設定をする関数
func LoggingSetting(logFile string) {
// ファイルを開く
logfile, err := os.OpenFile(
logFile, // ログの内容を出力
os.O_RDWR|os.O_CREATE|os.O_APPEND, // 別途解説
0666) // パーミッション
// エラーハンドリング
if err != nil {
log.Fatalln(err)
}
// ログの出力方法を指定
multLogFile := io.MultiWriter(os.Stdout, logfile)
// 取得するログの内容
log.SetFlags(log.Ldate|log.Ltime|log.Lshortfile)
// ログの出力先を指定
log.SetOutput(multLogFile)
}
logging.go
ファイルについては、上記のコードがパターン化されています。
ファイルに対する操作やログの出力先、取得するログ内容に特別変更がなければこれで問題ないでしょう。
プログラムで使用している標準パッケージの関数
それでは、今回作成した logging.go
ファイルで使用している標準パッケージの関数を見ていきましょう。
os.OpenFile()
os.OpenFile()
はファイルを開いて、引数に以下の設定を行うことができます。
第1引数 | ログの内容 |
第2引数 | 開くファイルに行える操作 |
第3引数 | パーミッション(ファイルに関する実行権限) |
特に注意すべきところは、第2引数で行えるファイル操作に関してです。
今回のプログラムでは、下記の操作を行える設定にしています。
os.O_RDWR | ファイルに読み書きできる |
os.O_CREATE | 第1引数で指定したファイルが無ければ作成する |
os.O_APPEND | ログの追記 |
第2引数での設定は | で区切ることで複数設定することができます。
その他にも…
os.O_RDONLY | ファイルの読み込み専用 |
os.O_WRONLY | ファイルの書き込み専用 |
os.O_TRUNC | 可能であればファイルの内容を開く時に空にする |
などがあります。

状況に応じて変更していきましょう!
log.Fatalln()
log.Fatalln()
はログメッセージを改行付きで出力してから、os.Exit(1)
にてプログラムを終了します。
ログメッセージは出力したいけど、プログラムを終了させたくない時は log.Println()
を使用します。
io.MultiWriter()
io.MultiWriter()
は、ログの出力先を複数書き出しできます。
今回のプログラムでは、下記の設定でログの出力先を2つ設定しています。
os.Stdout | ログを標準出力;画面への出力 |
logfile | logfileへのログを出力 |
log.SetFlags()
log.SetFlags()
はログの出力内容を設定します。
今回のプログラムでは、下記の設定でログの出力内容を設定しています。
log.Ldate | 日付 |
log.Ltime | 時間 |
log.Lshortfile | ログを出力しているファイル名と行番号 |
log.SetOutput()
log.SetOutput()
はログの出力先を指定します。
今回は、io.MultiWriter()
の内容を代入している変数 multLogFile
を設定しています。
ログの設定を読み込む
今までのログの設定内容は、config.ini
の設定と同様にメインプログラムが実行される前に読み込まれる必要があります。
ですから、config.ini
を読み込む設定ファイル config.go
ファイルの init
の箇所に追記します。
// config.go
package config
import (
"ini_test/utils" // importに追記
"log"
"gopkg.in/go-ini/ini.v1"
)
type ConfigList struct {
Port int
SQLDriver string
DBName string
LogFile string
}
var Config ConfigList
func init() {
LoadConfig() // iniファイルの読み込み
utils.LoggingSetting(Config.LogFile) // (追記)log設定を読み込み
}
// iniファイルを読み込む
func LoadConfig() {
cfg, err := ini.Load("config.ini")
if err != nil {
log.Fatalln(err)
}
Config = ConfigList{
Port: cfg.Section("web").Key("port").MustInt(8080),
SQLDriver: cfg.Section("db").Key("driver").String(),
DBName: cfg.Section("db").Key("name").String(),
LogFile: cfg.Section("web").Key("logfile").String(),
}
}
これで、config.ini
と同時にログの設定内容が読み込まれます。
ログの動作を確認する
それでは、実際に今までのプログラムが正常に動作するか確認しましょう。
main.go
ファイルに下記のコードを記述して実行します。
package main
import (
"fmt"
"ini_test/config"
"log"
)
func main() {
// configの内容を読み込む(今回プログラム実行するために必要)
fmt.Println(config.Config.Port)
fmt.Println(config.Config.SQLDriver)
fmt.Println(config.Config.DBName)
fmt.Println(config.Config.LogFile)
// logを実行する
log.Println("TEST")
}
// 出力結果
$ go run main.go
8080
sqlite3
webapp2.sql
webapp2.log
2021/09/01 09:49:00 main.go:17: TEST
2021/09/01 09:49:00 main.go:17: TEST
とログが出力されました。
設定内容通りに、日付・時間・実行ファイル名と行番号・ログ内容と出力されています。
今回は log.Println("TEST")
と引数を "TEST"
としましたが、エラーハンドリングする時は err
を変数にしてログの内容を出力することが多いでしょう。
そして、ログの実行プログラムが最初であれば、フォルダ内に webapp.log
が自動的に作成されログ出力と同じ内容が記述されているので確認してみましょう。
【最後に】logファイルをGoのプログラムで管理のため準備
今回は「logファイルをGoのプログラムで管理のため準備」についてお伝えしてきました。
パターン化されているので覚えることはないと思いますが、紹介したプログラムをメモなどで管理して必要な時に使用していくのが良いでしょう。
細かい設定などもアプリの仕様に応じて変更してください。
今後も、Goのプログラムでパターン化されているものは紹介していきます。
comment