如何使用pgx记录查询日志?

7

我找不到有关如何在使用pgx连接池时记录sql查询的文档。例如,我已经像这样创建了连接池:

func DB() *pgxpool.Pool {
    connStr := os.Getenv("DATABASE_URL")
    conn, err := pgxpool.Connect(context.Background(), connStr)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
        os.Exit(1)
    }
    return conn
}

请告诉我如何记录我的查询呢?


以与记录其他内容相同的方式:通过调用记录方法。看起来你正在这样做。你试图解决什么问题? - Jonathan Hall
3个回答

6
我得出了以下解决方案:
func DB() *pgxpool.Pool {
    config, err := pgxpool.ParseConfig(connStr)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to parse config: %v\n", err)
        os.Exit(1)
    }
    looger := &log.Logger{
        Out:          os.Stderr,
        Formatter:    new(log.JSONFormatter),
        Hooks:        make(log.LevelHooks),
        Level:        log.InfoLevel,
        ExitFunc:     os.Exit,
        ReportCaller: false,
    }
    config.ConnConfig.Logger = logrusadapter.NewLogger(looger)
    conn, err := pgxpool.ConnectConfig(context.Background(), config)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
        os.Exit(1)
    }
    return conn
}

5
你可能还希望对记录的查询有适当的控制,这时你可以使用跟踪器:
这里我使用了zap.SugaredLogger作为日志记录器,但也可以使用其他的。
type myQueryTracer struct {
    log *zap.SugaredLogger
}

func (tracer *myQueryTracer) TraceQueryStart(
    ctx context.Context,
    _ *pgx.Conn,
    data pgx.TraceQueryStartData) context.Context {
    tracer.log.Infow("Executing command", "sql", data.SQL, "args", data.Args)

    return ctx
}

func (tracer *myQueryTracer) TraceQueryEnd(ctx context.Context, conn *pgx.Conn, data pgx.TraceQueryEndData) {
}

func DB() *pgxpool.Pool {
    connStr := os.Getenv("DATABASE_URL")
    dbConfig, err := pgx.ParseConfig(connStr)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to parse connString: %v\n", err)
        os.Exit(1)
    }

    dbConfig.Tracer = &myQueryTracer{
        log: log,
    }

    conn, err := pgx.ConnectConfig(
        context.Background(),
        dbConfig,
    )

    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
        os.Exit(1)
    }

    return conn
}

4

全部功劳归功于@mystdeim,他在上面回答了。

复制原因:清晰地解释了导入

为什么不只是评论?:我没有50个声望

让我们开始吧

原始答案:

func DB() *pgxpool.Pool {
config, err := pgxpool.ParseConfig(connStr)
if err != nil {
    fmt.Fprintf(os.Stderr, "Unable to parse config: %v\n", err)
    os.Exit(1)
}
looger := &log.Logger{
    Out:          os.Stderr,
    Formatter:    new(log.JSONFormatter),
    Hooks:        make(log.LevelHooks),
    Level:        log.InfoLevel,
    ExitFunc:     os.Exit,
    ReportCaller: false,
}
config.ConnConfig.Logger = logrusadapter.NewLogger(looger)
conn, err := pgxpool.ConnectConfig(context.Background(), config)
if err != nil {
    fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
    os.Exit(1)
}
return conn
}

上述代码是可行的,但我将在这里谈论两点。
  1. 导入:log

有一个令人困惑的log导入

让我们仔细看一下

    looger := &log.Logger{
    Out:          os.Stderr,
    Formatter:    new(log.JSONFormatter),
    Hooks:        make(log.LevelHooks),
    Level:        log.InfoLevel,
    ExitFunc:     os.Exit,
    ReportCaller: false,
}
config.ConnConfig.Logger = logrusadapter.NewLogger(looger)

首先,让我们谈谈log包的导入。根据最后一行的假设,他正在使用logrus

因此

import (
"log"
)

如果你将logrus更名为log,那么这是不可能的,因为你将失去logrus的功能。

现在,如果你使用以下命令将logrus重命名为log

import (
log "github.com/sirupsen/logrus"
)

它将生成另一个错误:

LstdFlags not declared by package logrus (UndeclaredImportedName)
  1. 导入 logrusadapter

不再起作用:

    import (
"github.com/jackc/pgx/log/logrusadapter"
)

目前正在工作:

        import (
"github.com/jackc/pgx/v4/log/logrusadapter"
)

[嗯,看起来在2021年是v4版本,在将来导入之前,请确保检查您的版本]

  1. 我修改后的解决方案

您不需要将logrus重命名,保持原样即可。

                import (
 "github.com/sirupsen/logrus"
 "github.com/jackc/pgx/v4/pgxpool"
"github.com/jackc/pgx/v4/log/logrusadapter"

)

最后

func DB() *pgxpool.Pool {
    config, err := pgxpool.ParseConfig(connStr)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to parse config: %v\n", err)
        os.Exit(1)
    }
    logrusLogger := &logrus.Logger{
    Out:          os.Stderr,
    Formatter:    new(logrus.JSONFormatter),
    Hooks:        make(logrus.LevelHooks),
    Level:        logrus.InfoLevel,
    ExitFunc:     os.Exit,
    ReportCaller: false,
   }
    config.ConnConfig.Logger = logrusadapter.NewLogger(logrusLogger)
    conn, err := pgxpool.ConnectConfig(context.Background(), config)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
        os.Exit(1)
    }
    return conn
}

非常感谢@mystdeim帮我找到一个好的日志系统


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接