Skip to content

Commit db9b6c9

Browse files
serprexdveedenlance6716
authored
replace github.com/siddontang/go-log with log/slog (#993)
* replace github.com/siddontang/go-log with log/slog * feedback Co-authored-by: Daniël van Eeden <[email protected]> * avoid fmt.Sprintf logging * go-mysqlbinlog: allow configuring logger * feedback * lance feedback Co-authored-by: lance6716 <[email protected]> --------- Co-authored-by: Daniël van Eeden <[email protected]> Co-authored-by: lance6716 <[email protected]>
1 parent 042dd6c commit db9b6c9

21 files changed

+120
-151
lines changed

README.md

+3-21
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ package main
147147

148148
import (
149149
"github.com/go-mysql-org/go-mysql/canal"
150-
"github.com/siddontang/go-log/log"
151150
)
152151

153152
type MyEventHandler struct {
@@ -491,27 +490,10 @@ We pass all tests in https://github.com/bradfitz/go-sql-test using go-mysql driv
491490

492491
## Logging
493492

494-
Logging by default is send to stdout.
495-
496-
To disable logging completely:
497-
```go
498-
import "github.com/siddontang/go-log/log"
499-
...
500-
nullHandler, _ := log.NewNullHandler()
501-
cfg.Logger = log.NewDefault(nullHandler)
502-
```
503-
504-
To write logging to any [`io.Writer`](https://pkg.go.dev/io#Writer):
505-
```go
506-
import "github.com/siddontang/go-log/log"
507-
...
508-
w := ...
509-
streamHandler, _ := log.NewStreamHandler(w)
510-
cfg.Logger = log.NewDefault(streamHandler)
511-
```
512-
513-
Or you can implement your own [`log.Handler`](https://pkg.go.dev/github.com/siddontang/go-log/log#Handler).
493+
Logging uses [log/slog](https://pkg.go.dev/log/slog) and by default is sent to standard out.
514494

495+
For the old logging package `github.com/siddontang/go-log/log`, a converting package
496+
`https://github.com/serprex/slog-siddontang` is available.
515497
## How to migrate to this repo
516498
To change the used package in your repo it's enough to add this `replace` directive to your `go.mod`:
517499
```

canal/canal.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"io"
7+
"log/slog"
78
"net"
89
"os"
910
"regexp"
@@ -21,7 +22,6 @@ import (
2122
"github.com/go-mysql-org/go-mysql/utils"
2223
"github.com/pingcap/errors"
2324
"github.com/pingcap/tidb/pkg/parser"
24-
"github.com/siddontang/go-log/log"
2525
)
2626

2727
// Canal can sync your MySQL data into everywhere, like Elasticsearch, Redis, etc...
@@ -66,8 +66,7 @@ var (
6666
func NewCanal(cfg *Config) (*Canal, error) {
6767
c := new(Canal)
6868
if cfg.Logger == nil {
69-
streamHandler, _ := log.NewStreamHandler(os.Stdout)
70-
cfg.Logger = log.NewDefault(streamHandler)
69+
cfg.Logger = slog.Default()
7170
}
7271
if cfg.Dialer == nil {
7372
dialer := &net.Dialer{}
@@ -243,14 +242,14 @@ func (c *Canal) run() error {
243242
close(c.dumpDoneCh)
244243

245244
if err != nil {
246-
c.cfg.Logger.Errorf("canal dump mysql err: %v", err)
245+
c.cfg.Logger.Error("canal dump mysql err", slog.Any("error", err))
247246
return errors.Trace(err)
248247
}
249248
}
250249

251250
if err := c.runSyncBinlog(); err != nil {
252251
if errors.Cause(err) != context.Canceled {
253-
c.cfg.Logger.Errorf("canal start sync binlog err: %v", err)
252+
c.cfg.Logger.Error("canal start sync binlog err", slog.Any("error", err))
254253
return errors.Trace(err)
255254
}
256255
}
@@ -259,7 +258,7 @@ func (c *Canal) run() error {
259258
}
260259

261260
func (c *Canal) Close() {
262-
c.cfg.Logger.Infof("closing canal")
261+
c.cfg.Logger.Info("closing canal")
263262
c.m.Lock()
264263
defer c.m.Unlock()
265264

@@ -379,7 +378,7 @@ func (c *Canal) GetTable(db string, table string) (*schema.Table, error) {
379378
c.errorTablesGetTime[key] = utils.Now()
380379
c.tableLock.Unlock()
381380
// log error and return ErrMissingTableMeta
382-
c.cfg.Logger.Errorf("canal get table meta err: %v", errors.Trace(err))
381+
c.cfg.Logger.Error("canal get table meta err", slog.Any("error", errors.Trace(err)))
383382
return nil, schema.ErrMissingTableMeta
384383
}
385384
return nil, err

canal/canal_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"time"
77

88
"github.com/pingcap/tidb/pkg/parser"
9-
"github.com/siddontang/go-log/log"
109
"github.com/stretchr/testify/require"
1110
"github.com/stretchr/testify/suite"
1211

@@ -99,7 +98,7 @@ func (s *canalTestSuite) SetupSuite() {
9998

10099
s.execute("SET GLOBAL binlog_format = 'ROW'")
101100

102-
s.c.SetEventHandler(&testEventHandler{})
101+
s.c.SetEventHandler(&testEventHandler{T: s.T()})
103102
go func() {
104103
set, _ := mysql.ParseGTIDSet("mysql", "")
105104
err = s.c.StartFromGTID(set)
@@ -126,10 +125,11 @@ func (s *canalTestSuite) execute(query string, args ...interface{}) *mysql.Resul
126125

127126
type testEventHandler struct {
128127
DummyEventHandler
128+
T *testing.T
129129
}
130130

131131
func (h *testEventHandler) OnRow(e *RowsEvent) error {
132-
log.Infof("OnRow %s %v\n", e.Action, e.Rows)
132+
h.T.Log("OnRow", e.Action, e.Rows)
133133
umi, ok := e.Rows[0][4].(uint32) // 4th col is umi. mysqldump gives uint64 instead of uint32
134134
if ok && (umi != umiA && umi != umiB && umi != umiC) {
135135
return fmt.Errorf("invalid unsigned medium int %d", umi)

canal/config.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ package canal
22

33
import (
44
"crypto/tls"
5+
"log/slog"
56
"math/rand"
67
"net"
78
"os"
89
"time"
910

1011
"github.com/BurntSushi/toml"
1112
"github.com/pingcap/errors"
12-
"github.com/siddontang/go-log/log"
13-
"github.com/siddontang/go-log/loggers"
1413

1514
"github.com/go-mysql-org/go-mysql/client"
1615
"github.com/go-mysql-org/go-mysql/mysql"
@@ -101,7 +100,7 @@ type Config struct {
101100
TLSConfig *tls.Config
102101

103102
// Set Logger
104-
Logger loggers.Advanced
103+
Logger *slog.Logger
105104

106105
// Set Dialer
107106
Dialer client.Dialer
@@ -150,8 +149,7 @@ func NewDefaultConfig() *Config {
150149
c.Dump.DiscardErr = true
151150
c.Dump.SkipMasterData = false
152151

153-
streamHandler, _ := log.NewStreamHandler(os.Stdout)
154-
c.Logger = log.NewDefault(streamHandler)
152+
c.Logger = slog.Default()
155153

156154
dialer := &net.Dialer{}
157155
c.Dialer = dialer.DialContext

canal/dump.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package canal
33
import (
44
"encoding/hex"
55
"fmt"
6+
"log/slog"
67
"strconv"
78
"strings"
89
"time"
@@ -49,7 +50,7 @@ func (h *dumpParseHandler) Data(db string, table string, values []string) error
4950
e == schema.ErrMissingTableMeta {
5051
return nil
5152
}
52-
h.c.cfg.Logger.Errorf("get %s.%s information err: %v", db, table, err)
53+
h.c.cfg.Logger.Error("error getting table information", slog.String("database", db), slog.String("table", table), slog.Any("error", err))
5354
return errors.Trace(err)
5455
}
5556

@@ -163,7 +164,7 @@ func (c *Canal) dump() error {
163164
if err != nil {
164165
return errors.Trace(err)
165166
}
166-
c.cfg.Logger.Infof("skip master data, get current binlog position %v", pos)
167+
c.cfg.Logger.Info("skip master data, get current binlog position", slog.Any("position", pos))
167168
h.name = pos.Name
168169
h.pos = uint64(pos.Pos)
169170
}
@@ -185,8 +186,7 @@ func (c *Canal) dump() error {
185186
c.master.UpdateGTIDSet(h.gset)
186187
startPos = h.gset
187188
}
188-
c.cfg.Logger.Infof("dump MySQL and parse OK, use %0.2f seconds, start binlog replication at %s",
189-
time.Since(start).Seconds(), startPos)
189+
c.cfg.Logger.Info("dump MySQL and parse OK", slog.Duration("use", time.Since(start)), slog.String("position", startPos.String()))
190190
return nil
191191
}
192192

@@ -196,7 +196,7 @@ func (c *Canal) tryDump() error {
196196
if (len(pos.Name) > 0 && pos.Pos > 0) ||
197197
(gset != nil && gset.String() != "") {
198198
// we will sync with binlog name and position
199-
c.cfg.Logger.Infof("skip dump, use last binlog replication pos %s or GTID set %v", pos, gset)
199+
c.cfg.Logger.Info("skip dump, use last binlog replication position or GTID set", slog.String("file", pos.Name), slog.Uint64("position", uint64(pos.Pos)), slog.Any("GTID set", gset))
200200
return nil
201201
}
202202

canal/master.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package canal
22

33
import (
4+
"log/slog"
45
"sync"
56

67
"github.com/go-mysql-org/go-mysql/mysql"
7-
"github.com/siddontang/go-log/loggers"
88
)
99

1010
type masterInfo struct {
@@ -16,27 +16,27 @@ type masterInfo struct {
1616

1717
timestamp uint32
1818

19-
logger loggers.Advanced
19+
logger *slog.Logger
2020
}
2121

2222
func (m *masterInfo) Update(pos mysql.Position) {
23-
m.logger.Debugf("update master position %s", pos)
23+
m.logger.Debug("update master position", slog.Any("pos", pos))
2424

2525
m.Lock()
2626
m.pos = pos
2727
m.Unlock()
2828
}
2929

3030
func (m *masterInfo) UpdateTimestamp(ts uint32) {
31-
m.logger.Debugf("update master timestamp %d", ts)
31+
m.logger.Debug("update master timestamp", slog.Int64("ts", int64(ts)))
3232

3333
m.Lock()
3434
m.timestamp = ts
3535
m.Unlock()
3636
}
3737

3838
func (m *masterInfo) UpdateGTIDSet(gset mysql.GTIDSet) {
39-
m.logger.Debugf("update master gtid set %s", gset)
39+
m.logger.Debug("update master gtid set", slog.Any("gset", gset))
4040

4141
m.Lock()
4242
m.gset = gset

canal/sync.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package canal
22

33
import (
4+
"log/slog"
45
"sync/atomic"
56
"time"
67

@@ -20,15 +21,15 @@ func (c *Canal) startSyncer() (*replication.BinlogStreamer, error) {
2021
if err != nil {
2122
return nil, errors.Errorf("start sync replication at binlog %v error %v", pos, err)
2223
}
23-
c.cfg.Logger.Infof("start sync binlog at binlog file %v", pos)
24+
c.cfg.Logger.Info("start sync binlog at binlog file", slog.Any("pos", pos))
2425
return s, nil
2526
} else {
2627
gsetClone := gset.Clone()
2728
s, err := c.syncer.StartSyncGTID(gset)
2829
if err != nil {
2930
return nil, errors.Errorf("start sync replication at GTID set %v error %v", gset, err)
3031
}
31-
c.cfg.Logger.Infof("start sync binlog at GTID set %v", gsetClone)
32+
c.cfg.Logger.Info("start sync binlog at GTID set", slog.Any("gset", gsetClone))
3233
return s, nil
3334
}
3435
}
@@ -57,7 +58,7 @@ func (c *Canal) runSyncBinlog() error {
5758
// and https://github.com/mysql/mysql-server/blob/8cc757da3d87bf4a1f07dcfb2d3c96fed3806870/sql/rpl_binlog_sender.cc#L899
5859
if ev.Header.Timestamp == 0 {
5960
fakeRotateLogName := string(e.NextLogName)
60-
c.cfg.Logger.Infof("received fake rotate event, next log name is %s", e.NextLogName)
61+
c.cfg.Logger.Info("received fake rotate event", slog.String("nextLogName", string(e.NextLogName)))
6162

6263
if fakeRotateLogName != c.master.Position().Name {
6364
c.cfg.Logger.Info("log name changed, the fake rotate event will be handled as a real rotate event")
@@ -93,17 +94,16 @@ func (c *Canal) handleEvent(ev *replication.BinlogEvent) error {
9394
case *replication.RotateEvent:
9495
pos.Name = string(e.NextLogName)
9596
pos.Pos = uint32(e.Position)
96-
c.cfg.Logger.Infof("rotate binlog to %s", pos)
97+
c.cfg.Logger.Info("rotate binlog", slog.Any("pos", pos))
9798
savePos = true
9899
force = true
99100
if err = c.eventHandler.OnRotate(ev.Header, e); err != nil {
100101
return errors.Trace(err)
101102
}
102103
case *replication.RowsEvent:
103104
// we only focus row based event
104-
err = c.handleRowsEvent(ev)
105-
if err != nil {
106-
c.cfg.Logger.Errorf("handle rows event at (%s, %d) error %v", pos.Name, curPos, err)
105+
if err := c.handleRowsEvent(ev); err != nil {
106+
c.cfg.Logger.Error("handle rows event", slog.String("file", pos.Name), slog.Uint64("position", uint64(curPos)), slog.Any("error", err))
107107
return errors.Trace(err)
108108
}
109109
return nil
@@ -113,7 +113,7 @@ func (c *Canal) handleEvent(ev *replication.BinlogEvent) error {
113113
for _, subEvent := range ev.Events {
114114
err = c.handleEvent(subEvent)
115115
if err != nil {
116-
c.cfg.Logger.Errorf("handle transaction payload subevent at (%s, %d) error %v", pos.Name, curPos, err)
116+
c.cfg.Logger.Error("handle transaction payload subevent", slog.String("file", pos.Name), slog.Uint64("position", uint64(curPos)), slog.Any("error", err))
117117
return errors.Trace(err)
118118
}
119119
}
@@ -144,7 +144,7 @@ func (c *Canal) handleEvent(ev *replication.BinlogEvent) error {
144144
if err != nil {
145145
// The parser does not understand all syntax.
146146
// For example, it won't parse [CREATE|DROP] TRIGGER statements.
147-
c.cfg.Logger.Errorf("parse query(%s) err %v, will skip this event", e.Query, err)
147+
c.cfg.Logger.Error("error parsing query, will skip this event", slog.String("query", string(e.Query)), slog.Any("error", err))
148148
return nil
149149
}
150150
if len(stmts) > 0 {
@@ -246,7 +246,7 @@ func parseStmt(stmt ast.StmtNode) (ns []*node) {
246246

247247
func (c *Canal) updateTable(header *replication.EventHeader, db, table string) (err error) {
248248
c.ClearTableCache([]byte(db), []byte(table))
249-
c.cfg.Logger.Infof("table structure changed, clear table cache: %s.%s\n", db, table)
249+
c.cfg.Logger.Info("table structure changed, clear table cache", slog.String("database", db), slog.String("table", table))
250250
if err = c.eventHandler.OnTableChanged(header, db, table); err != nil && errors.Cause(err) != schema.ErrTableNotExist {
251251
return errors.Trace(err)
252252
}
@@ -316,7 +316,8 @@ func (c *Canal) WaitUntilPos(pos mysql.Position, timeout time.Duration) error {
316316
if curPos.Compare(pos) >= 0 {
317317
return nil
318318
} else {
319-
c.cfg.Logger.Debugf("master pos is %v, wait catching %v", curPos, pos)
319+
c.cfg.Logger.Debug("master pos is behind, wait to catch up", slog.String("master file", curPos.Name), slog.Uint64("master position", uint64(curPos.Pos)),
320+
slog.String("target file", pos.Name), slog.Uint64("target position", uint64(curPos.Pos)))
320321
time.Sleep(100 * time.Millisecond)
321322
}
322323
}

0 commit comments

Comments
 (0)