这很容易
log.Logger做到,因为该类型可以保证每个日志消息都可以通过
io.Writer一次
Writer.Write()调用传递到目标:
每个日志记录操作都会调用Writer的Write方法。一个Logger可以同时从多个goroutine中使用;它保证序列化对Writer的访问。
因此,基本上,您只需要创建一个实现的类型
io.Writer,并且其
Write()方法将创建一个具有字节片内容的新文档,并将其保存在MongoDB中。
这是执行此操作的简单实现:
type MongoWriter struct { sess *mgo.Session}func (mw *MongoWriter) Write(p []byte) (n int, err error) { c := mw.sess.DB("").C("log") err = c.Insert(bson.M{ "created": time.Now(), "msg": string(p), }) if err != nil { return } return len(p), nil}使用它:
sess := ... // Get a MongoDB sessionmw := &MongoWriter{sess}log.SetOutput(mw)// Now the default Logger of the log package uses our MongoWriter.// Generate a log message that will be inserted into MongoDB:log.Println("I'm the first log message.")log.Println("I'm multi-line,nbut will still be in a single log message.")显然,如果您使用的是其他
log.Logger实例,请将其设置为该实例
MongoWriter,例如:
mylogger := log.New(mw, "", 0)mylogger.Println("Custom logger")请注意,
log.Logger即使日志消息本身不以换行符结尾,日志消息也以换行符结尾。如果您不想记录结尾的换行符,则可以简单地剪切它,例如:
func (mw *MongoWriter) Write(p []byte) (n int, err error) { origLen := len(p) if len(p) > 0 && p[len(p)-1] == 'n' { p = p[:len(p)-1] // Cut terminating newline } c := mw.sess.DB("").C("log") // ... the rest is the same return origLen, nil // Must return original length (we resliced p)}


