Detta är enkelt att göra eftersom log.Logger
typ garanterar att varje loggmeddelande levereras till destinationen io.Writer
med en enda Writer.Write()
ring:
Varje loggningsoperation gör ett enda anrop till Writer's Write-metoden. En Logger kan användas samtidigt från flera goroutiner; det garanterar att serialisera åtkomst till Writer.
Så i princip behöver du bara skapa en typ som implementerar io.Writer
, och vars Write()
metoden skapar ett nytt dokument med innehållet i bytesegmentet och sparar det i MongoDB.
Här är en enkel implementering som gör det:
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
}
Använder det:
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.")
Uppenbarligen om du använder en annan log.Logger
instans, ställ in MongoWriter
till det, t.ex.:
mylogger := log.New(mw, "", 0)
mylogger.Println("Custom logger")
Observera att loggmeddelandena slutar med newline som log.Logger
lägger till det även om själva loggmeddelandet inte slutar med ny rad. Om du inte vill logga den sista nyraden kan du helt enkelt klippa den, t.ex.:
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)
}