MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Go:Crie a interface io.Writer para logar no banco de dados mongodb


Isso é facilmente possível, porque o log.Logger type garante que cada mensagem de log seja entregue ao destino io.Writer com um único Writer.Write() ligar:

Cada operação de registro faz uma única chamada ao método Write do Writer. Um Logger pode ser usado simultaneamente a partir de várias goroutines; ele garante serializar o acesso ao Writer.

Então, basicamente, você só precisa criar um tipo que implemente io.Writer , e cujo Write() O método cria um novo documento com o conteúdo da fatia de bytes e o salva no MongoDB.

Aqui está uma implementação simples que faz isso:
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
}

Usando isso:
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, se você estiver usando outro log.Logger instância, defina o MongoWriter para isso, por exemplo:
mylogger := log.New(mw, "", 0)
mylogger.Println("Custom logger")

Observe que as mensagens de log terminam com uma nova linha como log.Logger anexa-o mesmo que a própria mensagem de log não termine com nova linha. Se você não quiser registrar a nova linha final, você pode simplesmente cortá-la, por exemplo:
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)
}