Skip to content

Commit 49db4df

Browse files
authored
feat(fxsql): Provided migration logger (#227)
1 parent 77b202b commit 49db4df

File tree

7 files changed

+127
-13
lines changed

7 files changed

+127
-13
lines changed

docs/modules/fxsql.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,20 @@ modules:
6464
sql:
6565
driver: mysql # database driver
6666
dsn: "user:password@tcp(localhost:3306)/db?parseTime=true" # database DSN
67-
migrations: db/migrations # migrations path
67+
migrations:
68+
path: db/migrations # migrations path (empty by default)
69+
stdout: true # to print in stdout the migration logs (disabled by default)
6870
log:
69-
enabled: true # to enable SQL queries logging (disabled by default)
70-
level: debug # to configure SQL queries logs level (debug by default)
71-
arguments: true # to add SQL queries arguments to logs (disabled by default)
72-
exclude: # to exclude SQL operations from logging (empty by default)
71+
enabled: true # to enable SQL queries logging (disabled by default)
72+
level: debug # to configure SQL queries logs level (debug by default)
73+
arguments: true # to add SQL queries arguments to logs (disabled by default)
74+
exclude: # to exclude SQL operations from logging (empty by default)
7375
- "connection:ping"
7476
- "connection:reset-session"
7577
trace:
76-
enabled: true # to enable SQL queries tracing (disabled by default)
77-
arguments: true # to add SQL queries arguments to trace spans (disabled by default)
78-
exclude: # to exclude SQL operations from tracing (empty by default)
78+
enabled: true # to enable SQL queries tracing (disabled by default)
79+
arguments: true # to add SQL queries arguments to trace spans (disabled by default)
80+
exclude: # to exclude SQL operations from tracing (empty by default)
7981
- "connection:ping"
8082
- "connection:reset-session"
8183
```

fxsql/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ modules:
9898
sql:
9999
driver: mysql # database driver (empty by default)
100100
dsn: "user:password@tcp(localhost:3306)/db?parseTime=true" # database DSN (empty by default)
101-
migrations: db/migrations # migrations path (empty by default)
101+
migrations:
102+
path: db/migrations # migrations path (empty by default)
103+
stdout: true # to print in stdout the migration logs (disabled by default)
102104
log:
103105
enabled: true # to enable SQL queries logging (disabled by default)
104106
level: debug # to configure SQL queries logs level (debug by default)

fxsql/logger.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package fxsql
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/ankorstore/yokai/log"
7+
"github.com/rs/zerolog"
8+
)
9+
10+
// MigratorLogger is a logger compatible with [Goose].
11+
//
12+
// [Goose]: https://github.com/pressly/goose.
13+
type MigratorLogger struct {
14+
logger *log.Logger
15+
stdout bool
16+
}
17+
18+
// NewMigratorLogger returns a new MigratorLogger instance.
19+
func NewMigratorLogger(logger *log.Logger, stdout bool) *MigratorLogger {
20+
return &MigratorLogger{
21+
logger: logger,
22+
stdout: stdout,
23+
}
24+
}
25+
26+
// Printf logs with info level, and prints to stdout if configured to do so.
27+
func (l *MigratorLogger) Printf(format string, v ...interface{}) {
28+
l.logger.Info().Msgf(format, v...)
29+
30+
if l.stdout {
31+
//nolint:forbidigo
32+
fmt.Printf(format, v...)
33+
}
34+
}
35+
36+
// Fatalf logs with fatal level, and prints to stdout if configured to do so.
37+
func (l *MigratorLogger) Fatalf(format string, v ...interface{}) {
38+
l.logger.WithLevel(zerolog.FatalLevel).Msgf(format, v...)
39+
40+
if l.stdout {
41+
//nolint:forbidigo
42+
fmt.Printf("[FATAL] "+format, v...)
43+
}
44+
}

fxsql/logger_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package fxsql_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/ankorstore/yokai/fxsql"
7+
"github.com/ankorstore/yokai/log"
8+
"github.com/ankorstore/yokai/log/logtest"
9+
"github.com/rs/zerolog"
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestMigratorLoggerPrintf(t *testing.T) {
14+
t.Parallel()
15+
16+
logBuffer := logtest.NewDefaultTestLogBuffer()
17+
18+
migratorLogger := createTestMigratorLogger(t, logBuffer)
19+
20+
migratorLogger.Printf("test %s %d", "foo", 42)
21+
22+
logtest.AssertHasLogRecord(t, logBuffer, map[string]interface{}{
23+
"level": "info",
24+
"message": "test foo 42",
25+
})
26+
}
27+
28+
func TestMigratorLoggerFatalf(t *testing.T) {
29+
t.Parallel()
30+
31+
logBuffer := logtest.NewDefaultTestLogBuffer()
32+
33+
migratorLogger := createTestMigratorLogger(t, logBuffer)
34+
35+
migratorLogger.Fatalf("test %s %d", "foo", 42)
36+
37+
logtest.AssertHasLogRecord(t, logBuffer, map[string]interface{}{
38+
"level": "fatal",
39+
"message": "test foo 42",
40+
})
41+
}
42+
43+
func createTestMigratorLogger(t *testing.T, buffer logtest.TestLogBuffer) *fxsql.MigratorLogger {
44+
t.Helper()
45+
46+
logger, err := log.NewDefaultLoggerFactory().Create(
47+
log.WithLevel(zerolog.DebugLevel),
48+
log.WithOutputWriter(buffer),
49+
)
50+
assert.NoError(t, err)
51+
52+
return fxsql.NewMigratorLogger(logger, true)
53+
}

fxsql/migrator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
// Migrator is a database migrator based on [Goose].
1212
//
13-
// [Fx]: https://github.com/pressly/goose
13+
// [Goose]: https://github.com/pressly/goose
1414
type Migrator struct {
1515
db *sql.DB
1616
logger *log.Logger

fxsql/module.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@ package fxsql
33
import (
44
"context"
55
"database/sql"
6+
"sync"
67

78
"github.com/ankorstore/yokai/config"
89
"github.com/ankorstore/yokai/log"
910
yokaisql "github.com/ankorstore/yokai/sql"
1011
yokaisqllog "github.com/ankorstore/yokai/sql/hook/log"
1112
yokaisqltrace "github.com/ankorstore/yokai/sql/hook/trace"
13+
"github.com/pressly/goose/v3"
1214
"go.uber.org/fx"
1315
)
1416

17+
var once sync.Once
18+
1519
// ModuleName is the module name.
1620
const ModuleName = "sql"
1721

@@ -98,11 +102,18 @@ func NewFxSQLDatabase(p FxSQLDatabaseParam) (*sql.DB, error) {
98102
type FxSQLMigratorParam struct {
99103
fx.In
100104
Db *sql.DB
105+
Config *config.Config
101106
Logger *log.Logger
102107
}
103108

104109
// NewFxSQLMigrator returns a Migrator instance.
105110
func NewFxSQLMigrator(p FxSQLMigratorParam) *Migrator {
111+
// set once migrator the logger
112+
once.Do(func() {
113+
goose.SetLogger(NewMigratorLogger(p.Logger, p.Config.GetBool("modules.sql.migrations.stdout")))
114+
})
115+
116+
// migrator
106117
return NewMigrator(p.Db, p.Logger)
107118
}
108119

@@ -126,7 +137,7 @@ func RunFxSQLMigration(command string, args ...string) fx.Option {
126137
return migrator.Run(
127138
ctx,
128139
config.GetString("modules.sql.driver"),
129-
config.GetString("modules.sql.migrations"),
140+
config.GetString("modules.sql.migrations.path"),
130141
command,
131142
args...,
132143
)
@@ -144,7 +155,7 @@ func RunFxSQLMigrationAndShutdown(command string, args ...string) fx.Option {
144155
return migrator.Run(
145156
ctx,
146157
config.GetString("modules.sql.driver"),
147-
config.GetString("modules.sql.migrations"),
158+
config.GetString("modules.sql.migrations.path"),
148159
command,
149160
args...,
150161
)

fxsql/testdata/config/config.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ modules:
1111
sql:
1212
driver: ${SQL_DRIVER}
1313
dsn: ${SQL_DSN}
14-
migrations: testdata/migrations
14+
migrations:
15+
path: testdata/migrations
16+
stdout: false
1517
log:
1618
enabled: true
1719
level: debug

0 commit comments

Comments
 (0)