2017-03-13 8 views
7

log.Lshortfileフラグを使用して、ロガーは、例えば、ロガー関数呼び出しのファイル名と行番号を持つすべてのログ行を接頭辞行番号プレフィックスを失うことなくlog.Logger関数をラップすることはできますか?私は、例えば、このようなログ機能をラップする場合</p> <pre>myfile.go:14: Hello, world!</pre> <p>:

この関数が発行するすべての行には、Printf呼び出しの行番号が接頭辞として付けられます。これは期待通りですが、望ましい動作は、各行に接頭辞として、infoが呼び出された行の行番号を付けることです。

その周りに方法はありますか?

答えて

6
func info(format string, args ...interface{}) { 
    _, file, line, _ := runtime.Caller(1) 

    prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line) 

    if logger != nil { 
     logger.Printf(prefix+format+"\n", args...) 
    } 
} 

メソッドを適切な出力にメッセージを送信する:

回避策は、log.Lshortfileフラグを削除し、手動での動作を実現することです。 Logger.Output()は、calldepth(スキップするフレーム数)を渡すことを許可します。

残念なことに、log.Loggerのメソッドにはcalldepthが「配線されている」ため、ラッパー関数のフレームをスキップするためにオフセットを指定することはできません。

しかし、はるかに良い代替方法は、このLogger.Output()をラッパーから呼び出すことです。フレームや行を気にする必要はありません。また、"\n"という改行を追加する必要はありません。log.Loggerタイプでは、ログに記録されるメッセージが改行で終わっていない場合は、既にそれが行われています。

だから、代替より良いと短い:

var myLogger = log.New(os.Stdout, "[my]", log.Lshortfile) 

func info(pattern string, args ...interface{}) { 
    myLogger.Output(2, fmt.Sprintf(pattern, args...)) 
} 

テストそれ:

func main() { 
    log.SetFlags(log.Lshortfile) 
    log.Println("hello") 
    info("world") 
} 

出力(Go Playground上でそれを試してみてください):

main.go:11: hello 
[my]main.go:12: world 

あなたが見ることができるように、info()適切な行番号を印刷します(+1はで印刷された行番号前の行の)。

+2

これは私が話していることです:D大きな答え – Hubro

0

この問題を私の現在の回避策として含めるつもりでしたが、有効な答えと思われます。誰かが私に尋ねたロガー設定オプションについて教えてくれることを願っています。runtime.Callerを呼び出すときにロガーが使用する深さを調整できます。 log.LoggerコールLogger.Output()方法の

関連する問題