Това е лесно изпълнимо, тъй като log.Logger
type гарантира, че всяко съобщение в дневника се доставя до местоназначението io.Writer
с един Writer.Write()
обадете се:
Всяка операция за регистриране прави едно извикване на метода Writer на Writer. Logger може да се използва едновременно от множество горутини; той гарантира сериализиране на достъпа до 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 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.")
Очевидно, ако използвате друг 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)
}