## sql日志和持久化
通过第5节, 我们知道了如何获取和打印当前会话的sql. 此时的sql是保存在内存中的, 如果我们想永久保存的话, 也是可以做到的
## 示例
```go
package main
...
func main() {
// 链接数据库
connection, err := gorose.Open(DbConfigMaster)
if err != nil {
panic(err)
}
// 持久化sql中间件
connection.Use(gorose.NewLogger())
}
```
通过代码, 我们可以看到, 只需要在链接数据库之后, 调用持久化中间件, 即可实现sql的持久化, 这里的 `connection.Use(gorose.NewLogger())` 到底做了什么操作呢?
1. 我们先看看 `connection.Use()` , 这个是中间件的入口, 可以添加任意多个中间件, 只需要做对应的中间件支持即可
2. `gorose.NewLogger()` 这个是 sql log 中间件的核心部分, 这里是采用了 `gorose` 提供的默认持久化中间件, 是将 sql 保存在log文件中, 默认保存在当前路径, 以日期命名. 既然提供了中间件, 那么, 就意味着, 这里的中间件, 我们完全可以自定义. 我们可以在这里使用其他的任何日志系统来完成 sql 日志的持久化, 以便调试和查找问题之用.
下面, 我们详细分析下, 中间件 和 log 中间件的实现过程
## 中间件的设计
gorose中, 对于中间件的设计非常简洁, 没有过多的配置和架构, 我们先看下 `connection.Use()` 的代码:
```go
// Use : cors
func (conn *Connection) Use(options ...func(*Connection)) *Connection {
for _, option := range options {
option(conn)
}
return conn
}
```
这里的 Use 是 gorose.Connection 的一个 method, 同时可以接收多个中间件, 接收的中间件是一个常规的闭包函数, 返回 gorose.Connection 指针本身.
这里的 `option(conn)` 就是中间件的具体操作, 接受一个 参数 *gorose.Connection, 具体的中间件只需要完成 *gorose.Connection 对应的绑定即可.
接着, 我们看下 `gorose.NewLogger()` 中间件绑定的实现过程:
## Logger 中间件的实现
cors.go
```go
package gorose
import "github.com/gohouse/gorose/cors"
func NewLogger() func(*Connection) {
return func(conn *Connection) {
conn.Logger = cors.NewDefaultLogger()
}
}
```
cors/logger.go
```go
package cors
import (
"fmt"
"os"
"time"
)
type LoggerHandler interface {
Write(sql string, runtime string, datetime string)
}
type Logger struct {
}
func (w *Logger) Write(sql string, runtime string, datetime string) {
f := readFile(fmt.Sprintf("%v.log", time.Now().Format("2006-01-02")))
defer f.Close()
content := fmt.Sprintf("[Datetime: %v][Runtime: %v][Sql: %v]\n",
datetime, runtime, sql)
//fmt.Println(content)
buf := []byte(content)
f.Write(buf)
}
func readFile(filepath string) *os.File {
file, err := os.OpenFile(filepath, os.O_WRONLY|os.O_APPEND, 0666)
if err != nil && os.IsNotExist(err) {
file, err = os.Create(filepath)
}
return file
}
func NewDefaultLogger() *Logger {
return &Logger{}
}
```
1. cors.go 放置中间件的驱动入口, 也可以放置其他驱动中间件入口. 这里就一个返回中间件具体实现的一个闭包
2. `cors/logger.go` , cors目录中放置中间件的具体实现. 这里定义了一个
```
type LoggerHandler interface {
Write(sql string, runtime string, datetime string)
}
```
接收 `sql(sql语句)`, `runtime(执行消耗时间)`, `datetime(执行时间)` 三个参数. 我们自定义的中间件, 只需要实现该接口即可.
这里, 我们可以使用任何的log系统处理, 如 ELK, hadoop 等来做日志分析