sql >> Base de Datos >  >> NoSQL >> MongoDB

Ir:Crear interfaz io.Writer para iniciar sesión en la base de datos mongodb

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)
}