我想创建一个设置为特定log.Logger的所有内容都附加到特定变量的字符串数组的情况。io.MultiWriter与golang的pass-by-value
变量的类型实现了io.Writer接口,所以它应该很容易通过io.MultiWriter添加到log.New(),但我似乎遇到了棘手的问题:io.Writer接口是固定的并且根据给定golang的传值,变量不可能引用它自己。
也许会更有意义有一个例子:
package main
import "fmt"
import "io"
import "log"
import "os"
import "strings"
var Log *log.Logger
type Job_Result struct {
Job_ID int64
// other stuff
Log_Lines []string
}
// satisfies io.Writer interface
func (jr Job_Result) Write (p []byte) (n int, err error) {
s := strings.TrimRight(string(p),"\n ")
jr.Log_Lines= append(jr.Log_Lines,s)
return len(s), nil
}
func (jr Job_Result) Dump() {
fmt.Println("\nHere is a dump of the job result log lines:")
for n, s := range jr.Log_Lines{
fmt.Printf("\tline %d: %s\n",n,s)
}
}
func main() {
// make a Job_Result
var jr Job_Result
jr.Job_ID = 123
jr.Log_Lines = make([]string,0)
// create an io.MultiWriter that points to both stdout
// and that Job_Result var
var writers io.Writer
writers = io.MultiWriter(os.Stdout,jr)
Log = log.New(writers,
"",
log.Ldate|log.Ltime|log.Lshortfile)
// send some stuff to the log
Log.Println("program starting")
Log.Println("something happened")
Log.Printf("last thing that happened, should be %drd line\n",3)
jr.Dump()
}
这是输出,这并不奇怪:
2016/07/28 07:20:07 testjob.go:43: program starting
2016/07/28 07:20:07 testjob.go:44: something happened
2016/07/28 07:20:07 testjob.go:45: last thing that happened, should be 3rd line
Here is a dump of the job result log lines:
我理解这个问题 - 写()是得到一个副本的Job_Result变量,所以它忠实地追加,然后副本消失,因为它是本地的。我应该传递一个指向Job_Result的指针......但我不是那个叫Write()的人,它是由Logger完成的,我不能改变它。我认为这是一个简单的解决方案来捕获日志输出到数组中(还有其他订阅/取消订阅的东西,我没有显示),但这一切都归结为这个问题的io.Write()接口。
飞行员误差?糟糕的设计?我不是在追求什么?感谢您的任何建议。
简单而优雅。我过分关注确保Write()签名匹配,我忘记了其余部分。非常感谢! – raindog308