Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

binlogsyncer: Format config in logs #763

Merged
merged 2 commits into from
Jan 31, 2023

Conversation

dveeden
Copy link
Collaborator

@dveeden dveeden commented Jan 27, 2023

Example code:

package main

import "github.com/go-mysql-org/go-mysql/replication"

func main() {
	cfg := replication.BinlogSyncerConfig{
		ServerID: 100,
		Flavor:   "mysql",
		Host:     "127.0.0.1",
		Port:     3306,
		User:     "root",
		Password: "secret",
	}
	replication.NewBinlogSyncer(cfg)
}

Without this PR:

[2023/01/27 11:58:30] [info] binlogsyncer.go:173 create BinlogSyncer with config {100 mysql 127.0.0.1 3306 root    false false <nil> false UTC false 0 0s 0s 0 false false 0 <nil> 0xc0000ac180 0x52a420 <nil> false}

With this PR:

[2023/01/27 11:56:31] [info] binlogsyncer.go:170 create BinlogSyncer with config {"ServerID":100,"Flavor":"mysql","Host":"127.0.0.1","Port":3306,"User":"root","Password":"\u003chidden\u003e","Localhost":"","Charset":"","SemiSyncEnabled":false,"RawModeEnabled":false,"TLSConfig":null,"ParseTime":false,"TimestampStringLocation":null,"UseDecimal":false,"RecvBufferSize":0,"HeartbeatPeriod":0,"ReadTimeout":0,"MaxReconnectAttempts":0,"DisableRetrySync":false,"VerifyChecksum":false,"DumpCommandFlag":0,"Logger":{"Advanced":null}}

And the value after formatting:

{
  "ServerID": 100,
  "Flavor": "mysql",
  "Host": "127.0.0.1",
  "Port": 3306,
  "User": "root",
  "Password": "<hidden>",
  "Localhost": "",
  "Charset": "",
  "SemiSyncEnabled": false,
  "RawModeEnabled": false,
  "TLSConfig": null,
  "ParseTime": false,
  "TimestampStringLocation": null,
  "UseDecimal": false,
  "RecvBufferSize": 0,
  "HeartbeatPeriod": 0,
  "ReadTimeout": 0,
  "MaxReconnectAttempts": 0,
  "DisableRetrySync": false,
  "VerifyChecksum": false,
  "DumpCommandFlag": 0,
  "Logger": {
    "Advanced": null
  }
}
  1. This more clearly identifies fields in the config
  2. This more explicitly shows that the password was masked

Another option would be to do this:

diff --git a/replication/binlogsyncer.go b/replication/binlogsyncer.go
index 9c88aa8..e0164c0 100644
--- a/replication/binlogsyncer.go
+++ b/replication/binlogsyncer.go
@@ -170,7 +170,7 @@ func NewBinlogSyncer(cfg BinlogSyncerConfig) *BinlogSyncer {
        // Clear the Password to avoid outputing it in log.
        pass := cfg.Password
        cfg.Password = ""
-       cfg.Logger.Infof("create BinlogSyncer with config %v", cfg)
+       cfg.Logger.Infof("create BinlogSyncer with config %#v", cfg)
        cfg.Password = pass
 
        b := new(BinlogSyncer)

which results in:

[2023/01/27 11:59:52] [info] binlogsyncer.go:173 create BinlogSyncer with config replication.BinlogSyncerConfig{ServerID:0x64, Flavor:"mysql", Host:"127.0.0.1", Port:0xcea, User:"root", Password:"", Localhost:"", Charset:"", SemiSyncEnabled:false, RawModeEnabled:false, TLSConfig:(*tls.Config)(nil), ParseTime:false, TimestampStringLocation:(*time.Location)(nil), UseDecimal:false, RecvBufferSize:0, HeartbeatPeriod:0, ReadTimeout:0, MaxReconnectAttempts:0, DisableRetrySync:false, VerifyChecksum:false, DumpCommandFlag:0x0, Option:(func(*client.Conn) error)(nil), Logger:(*log.Logger)(0xc0000ac180), Dialer:(client.Dialer)(0x52a420), RowsEventDecodeFunc:(func(*replication.RowsEvent, []uint8) error)(nil), DiscardGTIDSet:false}

But I think JSON is more useful here.

It would also be possible to do this on top of the PR:

diff --git a/replication/binlogsyncer.go b/replication/binlogsyncer.go
index ad4592c..23ede39 100644
--- a/replication/binlogsyncer.go
+++ b/replication/binlogsyncer.go
@@ -38,7 +38,7 @@ type BinlogSyncerConfig struct {
        // User is for MySQL user.
        User string
        // Password is for MySQL password.
-       Password string
+       Password string `json:"-"`
 
        // Localhost is local hostname if register salve.
        // If not set, use os.Hostname() instead.
@@ -159,9 +159,6 @@ func NewBinlogSyncer(cfg BinlogSyncerConfig) *BinlogSyncer {
                cfg.Dialer = dialer.DialContext
        }
 
-       // Clear the Password to avoid outputing it in log.
-       pass := cfg.Password
-       cfg.Password = "<hidden>"
        jsonCfg, err := json.Marshal(cfg)
        if err != nil {
                cfg.Logger.Warnf("Failed to encode config as JSON: %s", err)
@@ -169,8 +166,6 @@ func NewBinlogSyncer(cfg BinlogSyncerConfig) *BinlogSyncer {
        }
        cfg.Logger.Infof("create BinlogSyncer with config %s", jsonCfg)
 
-       cfg.Password = pass
-
        b := new(BinlogSyncer)
 
        b.cfg = cfg

This would remove the password from the config and remove the need to replace it. But this might limit future use of JSON encoded BinlogSyncerConfig.

@dveeden
Copy link
Collaborator Author

dveeden commented Jan 30, 2023

@atercattus atercattus merged commit 724bb94 into go-mysql-org:master Jan 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants