Go言語でロガー gologgerを作ってみた

# はじめに
* Go言語でロガーを作ってみました。
* qiitaでも何度か「ロガー作ってみましたー」っといった記事がたまに出てくるんで何番煎じだよ？って気もしないでもないですが。
* やっぱどれも自分の使いたい機能がないので作ってみることにしました。
* アピールポイントとして、こんなところがメリットだなーと思ってます。
    * なんにも意識しなくてもGoroutine IDが表示できる。
    * メッセージの型を意識しなくても表示できる。
    * 呼び出し元関数名、ファイル名、行番号が出る。
    * JSONフォーマットも対応してる。
* よろしければ使ってみてほしいです。

## リポジトリ
https://github.com/suganoo/gologger

# 使い方
## 基本的使い方
### ダウンロード
```
go get -u github.com/suganoo/gologger
```
### コーディングサンプル
```golang：gologgerSample.go
package main

import (
	"github.com/suganoo/gologger"
)

var glog *gologger.Gologger

func hogeFunc() {
	glog.Debug("this is debug hogeFunc")
	glog.Info("call hogeFunc")
}

func main() {
	glog = gologger.NewGologger(gologger.Configuration{Logfile : "./testlog.log"})
	defer glog.CloseFile()

	msg := "hogehoge"
	glog.Debug("this is debug")   // default debug is muted
	glog.Info("this is info")
	glog.Info("msg : " + msg)
	glog.Warning("this is warning")
	glog.Error("this is Error")

	glog.UnmuteDebug()
	hogeFunc()

	glog.Debug("this is debug xxx")
	glog.MuteDebug()
	glog.Debug("this is debug yyy")  // this debug message is muted
}
```
```
2018-02-21T10:07:44.277+09:00	INFO	hoge.sever	3892	GrtnID:1	fuga-user	1.0.0	this is info	main	[gologgerSample.go:18]
2018-02-21T10:07:44.277+09:00	INFO	hoge.sever	3892	GrtnID:1	fuga-user	1.0.0	msg : hogehoge	main	[gologgerSample.go:19]
2018-02-21T10:07:44.277+09:00	WARNING	hoge.sever	3892	GrtnID:1	fuga-user	1.0.0	this is warning	main	[gologgerSample.go:20]
2018-02-21T10:07:44.277+09:00	ERROR	hoge.sever	3892	GrtnID:1	fuga-user	1.0.0	this is Error	main	[gologgerSample.go:21]
2018-02-21T10:07:44.277+09:00	DEBUG	hoge.sever	3892	GrtnID:1	fuga-user	1.0.0	this is debug hogeFunc	hogeFunc	[gologgerSample.go:8]
2018-02-21T10:07:44.277+09:00	INFO	hoge.sever	3892	GrtnID:1	fuga-user	1.0.0	call hogeFunc	hogeFunc	[gologgerSample.go:9]
2018-02-21T10:07:44.277+09:00	DEBUG	hoge.sever	3892	GrtnID:1	fuga-user	1.0.0	this is debug xxx	main	[gologgerSample.go:26]
```
### ログ表示項目
デフォルトで表示する項目は下記になります。タブ区切りにしてます。

* タイムスタンプ
* ログレベル
* サーバー名
* プロセスID
* Goroutine ID
    * `runtime.Stack()` から抜き出してます。
* ユーザー名
* バージョン
    * 任意で指定できるプロダクトのバージョンの意味です。後述しますが変更可能です。
* ログメッセージ
* ロガーを呼び出した関数名
* ロガーを呼び出したファイルと行番号

### 標準出力
最初の `gologger.NewGologger`で `gologger.Configuration`の `Logfile`に何も指定しなければ標準出力になります。

```
glog = gologger.NewGologger(gologger.Configuration{})
glog.Info("test")
```

### 書き込むログメッセージの型について
ログに書き込むメッセージの型はstring以外にもリスト型でも構造体型でも書き込めます。

```
// Array
items := []string{"aaaa", "bbbb"}
glog.Info(items)

// Int
glog.Info(1000)

// Struct
type Hoge struct {
	Id int
	Name string
}
hoge := Hoge{Id: 1222, Name:"aaaa"}
glog.Info(hoge)

// Mixed
glog.Info("ddddddddddd", "ooooo", 123)
```
```
// Array
2019-01-07T12:17:01.248+09:00	INFO	hoge.sever	18184	GrtnID:1	fuga-user	1.0.0	[aaaa bbbb]	main	[main.go:24]
// Int
2019-01-07T12:17:01.248+09:00	INFO	hoge.sever	18184	GrtnID:1	fuga-user	1.0.0	1000	main	[main.go:23]
// Struct
2019-01-07T12:17:01.248+09:00	INFO	hoge.sever	18184	GrtnID:1	fuga-user	1.0.0	{1222 aaaa}	main	[main.go:30]
// Mixed
2019-01-07T12:17:01.248+09:00	INFO	hoge.sever	18184	GrtnID:1	fuga-user	1.0.0	ddddddddddd ooooo 123	main	[main.go:31]
```

### ログのレベルについて
ログレベルとしては下記のレベルがあります。とりあえずよくありがちなレベルを作ってみました。こんな感じかなーっとふわっと作ってます。
FatalはErrorと違いがないので、一応作ったってレベルです。またPanicは実行するとPanicで終了します(不要かもと検討レベルです)。

```golang
glog.Debug()
glog.Info()
glog.Warning()
glog.Error()
// 以下は非推奨
glog.Fatal()
glog.Panic()
```
## 設定変更したい
いくつか設定変更できる機能を実装しています。

### タイムスタンプのフォーマットを変える
`SetTimeFormat`でフォーマットが変えられます。
フォーマットについてはこちらを参照してください。
[Go言語のタイムフォーマット](https://qiita.com/suganoooo/items/6df2d277c2d7bd15a35d#%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E5%A4%89%E6%8F%9B)

```
glog.SetTimeFormat("2006/01/02")
```
```
2018/02/21	INFO	hoge.sever...
```

### タブ区切り以外にする
デフォルトはタブ区切りにしてますが、それ以外にもできます。

```
glog.SetSeparator("---")
```
```
2018-02-21T10:07:44.277+09:00---INFO---hoge.sever---...
```

### デバッグをミュートする
サンプルにも書いてますが `Debug()`をミュート・アンミュートできます。

```
glog.UnmuteDebug()
// ここ以降 Debug()は出力されます。
glog.MuteDebug()
// ここ以降、Debug()は出力されません。
```

### 表示項目を変える
ログに出力する項目を `SetItemsList()`で変えることができます。

```
glog.SetItemsList([]gologger.KeyId{gologger.KeyMessage, gologger.KeyFunc, gologger.KeyFileName, gologger.KeyLogLevel, gologger.KeyProcessId})
glog.Info("hogehoge")
```
```
hogehoge	main	[main.go:11]	INFO	10780
```
こちらを参考にしてください。
[表示項目](https://github.com/suganoo/gologger/blob/master/gologger.go#L18)

```golang
const (
	KeyTimestamp KeyId = iota
	KeyLogLevel
	KeyHostName
	KeyProcessId
	KeyGoroutineId
	KeyUserName
	KeyVersion
	KeyMessage
	KeyFunc
	KeyFileName
)
```

### 出力フォーマットを変える
今のところJSONフォーマットに変えることができます。

```
glog.SetOutputFormat(gologger.FmtJSON)
```
```
ex.
{"filename":"[sample.go:18]","func":"main","gid":"GrtnID:1","hostname":"hoge.server","loglevel":"INFO","msg":"this is info","pid":"4124","timestamp":"2019-02-10T23:54:07.854+09:00","username":"fuga-user","version":"1.0.0"}
```

### バージョンを変える
バージョン変えられます。

```
glog.SetVersion("1.2.3")
```
```
1.2.3
```

# 最後
もしあなたが心優しい人で使ってみていただけて、なにか思うところあれば優しい言葉でコメントしてみていただけますとありがたいです。