お題
表題の通り。 Goではruntime.Caller
を使うと、その関数の呼び出し箇所の情報が取れるので、それを使う。
実践
ソースは下記。
https://github.com/sky0621/tips-go/tree/master/try/log
共通ロガー
[logger/logger.go]
package logger
import (
"fmt"
"runtime"
)
type AppLogger interface {
Log(msg string)
}
type appLogger struct {
}
func NewAppLogger() AppLogger {
return &appLogger{}
}
func (l *appLogger) Log(msg string) {
fmt.Printf("[Path:%s] %s\n", fileWithLineNum(), msg)
}
func fileWithLineNum() string {
_, name, line, ok := runtime.Caller(2)
if !ok {
return "-"
}
return fmt.Sprintf("%s:%d", name, line)
}
ドメイン層
呼び出し箇所が階層化されているケースでちゃんとログにパスが吐かれることの確認用に用意。
[domain/user.go]
package domain
import "tips-go/try/log/logger"
type User interface {
Hello()
}
type user struct {
lgr logger.AppLogger
}
func NewUser(lgr logger.AppLogger) User {
return &user{lgr: lgr}
}
func (u *user) Hello() {
u.lgr.Log("Hello!")
}
メイン関数
[main.go]
package main
import (
"tips-go/try/log/domain"
"tips-go/try/log/logger"
)
func main() {
lgr := logger.NewAppLogger()
user := domain.NewUser(lgr)
user.Hello()
}
実行結果
$ go run main.go
[Path:〜ルートからのフルパス〜/tips-go/try/log/domain/user.go:18] Hello!