Esto es fácilmente factible, porque el log.Logger
type garantiza que cada mensaje de registro se entrega al destino io.Writer
con un solo Writer.Write()
llamar:
Cada operación de registro realiza una única llamada al método Write del escritor. Un registrador se puede usar simultáneamente desde varias rutinas; garantiza serializar el acceso al Escritor.
Básicamente, solo necesita crear un tipo que implemente io.Writer
, y cuyo Write()
El método crea un nuevo documento con el contenido del segmento de bytes y lo guarda en MongoDB.
Aquí hay una implementación simple que hace eso:
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
}
Usándolo:
sess := ... // Get a MongoDB session
mw := &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.")
Obviamente, si está utilizando otro log.Logger
instancia, configure el MongoWriter
a eso, por ejemplo:
mylogger := log.New(mw, "", 0)
mylogger.Println("Custom logger")
Tenga en cuenta que los mensajes de registro terminan con una nueva línea como log.Logger
lo agrega incluso si el mensaje de registro en sí no termina con una nueva línea. Si no desea registrar la nueva línea final, simplemente córtela, por ejemplo:
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)
}