Dies ist leicht machbar, da der log.Logger
Typ garantiert, dass jede Protokollnachricht an das Ziel io.Writer
zugestellt wird mit einem einzigen Writer.Write()
Aufruf:
Jeder Protokollierungsvorgang ruft die Methode Writer's Write einmal auf. Ein Logger kann gleichzeitig von mehreren Goroutinen verwendet werden; es garantiert den Zugriff auf den Writer zu serialisieren.
Im Grunde müssen Sie also nur einen Typ erstellen, der io.Writer
implementiert , und deren Write()
-Methode erstellt ein neues Dokument mit dem Inhalt des Byte-Slice und speichert es in der MongoDB.
Hier ist eine einfache Implementierung, die das tut:
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
}
Verwendung:
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.")
Offensichtlich, wenn Sie einen anderen log.Logger
verwenden Legen Sie beispielsweise den MongoWriter
fest dazu z.B.:
mylogger := log.New(mw, "", 0)
mylogger.Println("Custom logger")
Beachten Sie, dass die Log-Meldungen mit Newline als log.Logger
enden hängt es an, auch wenn die Protokollnachricht selbst nicht mit Zeilenumbruch endet. Wenn Sie den Zeilenumbruch am Ende nicht protokollieren möchten, können Sie ihn einfach abschneiden, z. B.:
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)
}