diff --git a/cmd/validate.go b/cmd/validate.go index 5968db2d1..85adc731e 100644 --- a/cmd/validate.go +++ b/cmd/validate.go @@ -100,8 +100,8 @@ func newCheckSumCommand() *cobra.Command { zap.Uint64("totalBytes", file.GetTotalBytes()), zap.Uint64("startVersion", file.GetStartVersion()), zap.Uint64("endVersion", file.GetEndVersion()), - zap.Binary("startKey", file.GetStartKey()), - zap.Binary("endKey", file.GetEndKey()), + zap.Stringer("startKey", utils.WrapKey(file.GetStartKey())), + zap.Stringer("endKey", utils.WrapKey(file.GetEndKey())), ) var data []byte @@ -179,7 +179,7 @@ func newBackupMetaCommand() *cobra.Command { log.Error( "file ranges overlapped", zap.Stringer("out", out), - zap.Stringer("file", file), + utils.ZapFile(file), ) } } diff --git a/pkg/backup/client.go b/pkg/backup/client.go index 83966e524..9552e507b 100644 --- a/pkg/backup/client.go +++ b/pkg/backup/client.go @@ -451,8 +451,8 @@ func (bc *Client) BackupRange( } }() log.Info("backup started", - zap.Binary("StartKey", startKey), - zap.Binary("EndKey", endKey), + zap.Stringer("StartKey", utils.WrapKey(startKey)), + zap.Stringer("EndKey", utils.WrapKey(endKey)), zap.Uint64("RateLimit", req.RateLimit), zap.Uint32("Concurrency", req.Concurrency)) ctx, cancel := context.WithCancel(ctx) @@ -494,8 +494,8 @@ func (bc *Client) BackupRange( bc.backupMeta.RawRanges = append(bc.backupMeta.RawRanges, &kvproto.RawRange{StartKey: startKey, EndKey: endKey, Cf: req.Cf}) log.Info("backup raw ranges", - zap.ByteString("startKey", startKey), - zap.ByteString("endKey", endKey), + zap.Stringer("startKey", utils.WrapKey(startKey)), + zap.Stringer("endKey", utils.WrapKey(endKey)), zap.String("cf", req.Cf)) } else { log.Info("backup time range", @@ -531,10 +531,10 @@ func (bc *Client) findRegionLeader( } if region.Leader != nil { log.Info("find leader", - zap.Reflect("Leader", region.Leader), zap.Binary("Key", key)) + zap.Reflect("Leader", region.Leader), zap.Stringer("Key", utils.WrapKey(key))) return region.Leader, nil } - log.Warn("no region found", zap.Binary("Key", key)) + log.Warn("no region found", zap.Stringer("Key", utils.WrapKey(key))) time.Sleep(time.Millisecond * time.Duration(100*i)) continue } @@ -618,8 +618,8 @@ func (bc *Client) fineGrainedBackup( zap.Reflect("error", resp.Error)) } log.Info("put fine grained range", - zap.Binary("StartKey", resp.StartKey), - zap.Binary("EndKey", resp.EndKey), + zap.Stringer("StartKey", utils.WrapKey(resp.StartKey)), + zap.Stringer("EndKey", utils.WrapKey(resp.EndKey)), ) rangeTree.Put(resp.StartKey, resp.EndKey, resp.Files) @@ -770,8 +770,8 @@ func SendBackup( respFn func(*kvproto.BackupResponse) error, ) error { log.Info("try backup", - zap.Binary("StartKey", req.StartKey), - zap.Binary("EndKey", req.EndKey), + zap.Stringer("StartKey", utils.WrapKey(req.StartKey)), + zap.Stringer("EndKey", utils.WrapKey(req.EndKey)), zap.Uint64("storeID", storeID), ) ctx, cancel := context.WithCancel(ctx) @@ -793,8 +793,8 @@ func SendBackup( } // TODO: handle errors in the resp. log.Info("range backuped", - zap.Any("StartKey", resp.GetStartKey()), - zap.Any("EndKey", resp.GetEndKey())) + zap.Stringer("StartKey", utils.WrapKey(resp.GetStartKey())), + zap.Stringer("EndKey", utils.WrapKey(req.GetEndKey()))) err = respFn(resp) if err != nil { return err diff --git a/pkg/restore/import.go b/pkg/restore/import.go index 90a2f5610..61a539854 100644 --- a/pkg/restore/import.go +++ b/pkg/restore/import.go @@ -185,7 +185,7 @@ func (importer *FileImporter) Import( rejectStoreMap map[uint64]bool, rewriteRules *RewriteRules, ) error { - log.Debug("import file", zap.Stringer("file", file)) + log.Debug("import file", utils.ZapFile(file)) // Rewrite the start key and end key of file to scan regions var startKey, endKey []byte var err error @@ -203,9 +203,9 @@ func (importer *FileImporter) Import( return err } log.Debug("rewrite file keys", - zap.Stringer("file", file), - zap.Binary("startKey", startKey), - zap.Binary("endKey", endKey)) + utils.ZapFile(file), + zap.Stringer("startKey", utils.WrapKey(startKey)), + zap.Stringer("endKey", utils.WrapKey(endKey))) needReject := len(rejectStoreMap) > 0 @@ -226,7 +226,7 @@ func (importer *FileImporter) Import( for _, region := range regionInfos { if !waitForRemoveRejectStores(ctx, importer.metaClient, region, rejectStoreMap) { log.Error("waiting for removing rejected stores failed", - zap.Stringer("region", region.Region)) + utils.ZapRegion(region.Region)) return errors.New("waiting for removing rejected stores failed") } } @@ -235,7 +235,7 @@ func (importer *FileImporter) Import( needReject = false } - log.Debug("scan regions", zap.Stringer("file", file), zap.Int("count", len(regionInfos))) + log.Debug("scan regions", utils.ZapFile(file), zap.Int("count", len(regionInfos))) // Try to download and ingest the file in every region regionLoop: for _, regionInfo := range regionInfos { @@ -266,10 +266,10 @@ func (importer *FileImporter) Import( } } log.Error("download file failed", - zap.Stringer("file", file), - zap.Stringer("region", info.Region), - zap.Binary("startKey", startKey), - zap.Binary("endKey", endKey), + utils.ZapFile(file), + utils.ZapRegion(info.Region), + zap.Stringer("startKey", utils.WrapKey(startKey)), + zap.Stringer("endKey", utils.WrapKey(endKey)), zap.Error(errDownload)) return errDownload } @@ -300,7 +300,7 @@ func (importer *FileImporter) Import( } } log.Debug("ingest sst returns not leader error, retry it", - zap.Stringer("region", info.Region), + utils.ZapRegion(info.Region), zap.Stringer("newLeader", newInfo.Leader)) if !checkRegionEpoch(newInfo, info) { @@ -326,9 +326,9 @@ func (importer *FileImporter) Import( if errIngest != nil { log.Error("ingest file failed", - zap.Stringer("file", file), + utils.ZapFile(file), zap.Stringer("range", downloadMeta.GetRange()), - zap.Stringer("region", info.Region), + utils.ZapRegion(info.Region), zap.Error(errIngest)) return errIngest } @@ -379,9 +379,9 @@ func (importer *FileImporter) downloadSST( RewriteRule: rule, } log.Debug("download SST", - zap.Stringer("sstMeta", &sstMeta), - zap.Stringer("file", file), - zap.Stringer("region", regionInfo.Region), + utils.ZapSSTMeta(&sstMeta), + utils.ZapFile(file), + utils.ZapRegion(regionInfo.Region), ) var resp *import_sstpb.DownloadResponse for _, peer := range regionInfo.Region.GetPeers() { @@ -432,8 +432,8 @@ func (importer *FileImporter) downloadRawKVSST( RewriteRule: rule, } log.Debug("download SST", - zap.Stringer("sstMeta", &sstMeta), - zap.Stringer("region", regionInfo.Region), + utils.ZapSSTMeta(&sstMeta), + utils.ZapRegion(regionInfo.Region), ) var resp *import_sstpb.DownloadResponse for _, peer := range regionInfo.Region.GetPeers() { @@ -470,7 +470,7 @@ func (importer *FileImporter) ingestSST( Context: reqCtx, Sst: sstMeta, } - log.Debug("ingest SST", zap.Stringer("sstMeta", sstMeta), zap.Reflect("leader", leader)) + log.Debug("ingest SST", utils.ZapSSTMeta(sstMeta), zap.Reflect("leader", leader)) resp, err := importer.importClient.IngestSST(importer.ctx, leader.GetStoreId(), req) if err != nil { return nil, errors.Trace(err) diff --git a/pkg/restore/range.go b/pkg/restore/range.go index 0e016dbde..37324ac47 100644 --- a/pkg/restore/range.go +++ b/pkg/restore/range.go @@ -13,6 +13,7 @@ import ( "go.uber.org/zap" "github.com/pingcap/br/pkg/rtree" + "github.com/pingcap/br/pkg/utils" ) // SortRanges checks if the range overlapped and sort them. @@ -26,26 +27,26 @@ func SortRanges(ranges []rtree.Range, rewriteRules *RewriteRules) ([]rtree.Range if startID == endID { rg.StartKey, rule = replacePrefix(rg.StartKey, rewriteRules) if rule == nil { - log.Warn("cannot find rewrite rule", zap.Binary("key", rg.StartKey)) + log.Warn("cannot find rewrite rule", zap.Stringer("key", utils.WrapKey(rg.StartKey))) } else { log.Debug( "rewrite start key", - zap.Binary("key", rg.StartKey), - zap.Stringer("rule", rule)) + zap.Stringer("key", utils.WrapKey(rg.StartKey)), + utils.ZapRewriteRule(rule)) } rg.EndKey, rule = replacePrefix(rg.EndKey, rewriteRules) if rule == nil { - log.Warn("cannot find rewrite rule", zap.Binary("key", rg.EndKey)) + log.Warn("cannot find rewrite rule", zap.Stringer("key", utils.WrapKey(rg.EndKey))) } else { log.Debug( "rewrite end key", - zap.Binary("key", rg.EndKey), - zap.Stringer("rule", rule)) + zap.Stringer("key", utils.WrapKey(rg.EndKey)), + utils.ZapRewriteRule(rule)) } } else { log.Warn("table id does not match", - zap.Binary("startKey", rg.StartKey), - zap.Binary("endKey", rg.EndKey), + zap.Stringer("startKey", utils.WrapKey(rg.StartKey)), + zap.Stringer("endKey", utils.WrapKey(rg.EndKey)), zap.Int64("startID", startID), zap.Int64("endID", endID)) return nil, errors.New("table id does not match") diff --git a/pkg/restore/split.go b/pkg/restore/split.go index 21fc5b58a..36649c50d 100644 --- a/pkg/restore/split.go +++ b/pkg/restore/split.go @@ -17,6 +17,7 @@ import ( "go.uber.org/zap" "github.com/pingcap/br/pkg/rtree" + "github.com/pingcap/br/pkg/utils" ) // Constants for split retry machinery. @@ -117,9 +118,9 @@ SplitRegions: if strings.Contains(errSplit.Error(), "no valid key") { for _, key := range keys { log.Error("no valid key", - zap.Binary("startKey", region.Region.StartKey), - zap.Binary("endKey", region.Region.EndKey), - zap.Binary("key", codec.EncodeBytes([]byte{}, key))) + zap.Stringer("startKey", utils.WrapKey(region.Region.StartKey)), + zap.Stringer("endKey", utils.WrapKey(region.Region.EndKey)), + zap.Stringer("key", utils.WrapKey(codec.EncodeBytes([]byte{}, key)))) } return errors.Trace(errSplit) } @@ -129,11 +130,11 @@ SplitRegions: } time.Sleep(interval) if i > 3 { - log.Warn("splitting regions failed, retry it", zap.Error(errSplit), zap.ByteStrings("keys", keys)) + log.Warn("splitting regions failed, retry it", zap.Error(errSplit), zap.Array("keys", utils.WrapKeys(keys))) } continue SplitRegions } - log.Debug("split regions", zap.Stringer("region", region.Region), zap.ByteStrings("keys", keys)) + log.Debug("split regions", utils.ZapRegion(region.Region), zap.Array("keys", utils.WrapKeys(keys))) scatterRegions = append(scatterRegions, newRegions...) onSplit(keys) } @@ -226,7 +227,7 @@ func (rs *RegionSplitter) waitForScatterRegion(ctx context.Context, regionInfo * ok, err := rs.isScatterRegionFinished(ctx1, regionID) if err != nil { log.Warn("scatter region failed: do not have the region", - zap.Stringer("region", regionInfo.Region)) + utils.ZapRegion(regionInfo.Region)) return } if ok { @@ -251,7 +252,7 @@ func (rs *RegionSplitter) splitAndScatterRegions( // Wait for a while until the regions successfully splits. rs.waitForSplit(ctx, region.Region.Id) if err = rs.client.ScatterRegion(ctx, region); err != nil { - log.Warn("scatter region failed", zap.Stringer("region", region.Region), zap.Error(err)) + log.Warn("scatter region failed", utils.ZapRegion(region.Region), zap.Error(err)) } } return newRegions, nil @@ -279,9 +280,9 @@ func getSplitKeys(rewriteRules *RewriteRules, ranges []rtree.Range, regions []*R } splitKeyMap[region.Region.GetId()] = append(splitKeys, key) log.Debug("get key for split region", - zap.Binary("key", key), - zap.Binary("startKey", region.Region.StartKey), - zap.Binary("endKey", region.Region.EndKey)) + zap.Stringer("key", utils.WrapKey(key)), + zap.Stringer("startKey", utils.WrapKey(region.Region.StartKey)), + zap.Stringer("endKey", utils.WrapKey(region.Region.EndKey))) } } return splitKeyMap diff --git a/pkg/restore/util.go b/pkg/restore/util.go index 39af185e0..b11db57f2 100644 --- a/pkg/restore/util.go +++ b/pkg/restore/util.go @@ -25,6 +25,7 @@ import ( "github.com/pingcap/br/pkg/glue" "github.com/pingcap/br/pkg/rtree" "github.com/pingcap/br/pkg/summary" + "github.com/pingcap/br/pkg/utils" ) var recordPrefixSep = []byte("_r") @@ -119,14 +120,14 @@ func GetSSTMetaFromFile( if bytes.Compare(rangeStart, rangeEnd) > 0 { log.Fatal("range start exceed range end", - zap.Binary("start", rangeStart), - zap.Binary("end", rangeEnd)) + zap.Stringer("start", utils.WrapKey(rangeStart)), + zap.Stringer("end", utils.WrapKey(rangeEnd))) } log.Debug("get sstMeta", - zap.Stringer("file", file), - zap.Binary("rangeStart", rangeStart), - zap.Binary("rangeEnd", rangeEnd)) + utils.ZapFile(file), + zap.Stringer("rangeStart", utils.WrapKey(rangeStart)), + zap.Stringer("rangeEnd", utils.WrapKey(rangeEnd))) return import_sstpb.SSTMeta{ Uuid: id, @@ -183,14 +184,14 @@ func MapTableToFiles(files []*backup.File) map[int64][]*backup.File { if tableID != tableEndID { log.Panic("key range spread between many files.", zap.String("file name", file.Name), - zap.Binary("start key", file.GetStartKey()), - zap.Binary("end key", file.GetEndKey())) + zap.Stringer("start key", utils.WrapKey(file.GetStartKey())), + zap.Stringer("end key", utils.WrapKey(file.GetEndKey()))) } if tableID == 0 { log.Panic("invalid table key of file", zap.String("file name", file.Name), - zap.Binary("start key", file.GetStartKey()), - zap.Binary("end key", file.GetEndKey())) + zap.Stringer("start key", utils.WrapKey(file.GetStartKey())), + zap.Stringer("end key", utils.WrapKey(file.GetEndKey()))) } result[tableID] = append(result[tableID], file) } @@ -262,7 +263,7 @@ func validateAndGetFileRange(file *backup.File, rules *RewriteRules) (rtree.Rang log.Error("table ids mismatch", zap.Int64("startID", startID), zap.Int64("endID", endID), - zap.Stringer("file", file)) + utils.ZapFile(file)) return rtree.Range{}, errors.New("table ids mismatch") } r := rtree.Range{StartKey: file.GetStartKey(), EndKey: file.GetEndKey()} @@ -286,8 +287,8 @@ func AttachFilesToRanges( }) if rg == nil { log.Fatal("range not found", - zap.Binary("startKey", f.GetStartKey()), - zap.Binary("endKey", f.GetEndKey())) + zap.Stringer("startKey", utils.WrapKey(f.GetStartKey())), + zap.Stringer("endKey", utils.WrapKey(f.GetEndKey()))) } file := *f rg.Files = append(rg.Files, &file) @@ -310,7 +311,7 @@ func ValidateFileRewriteRule(file *backup.File, rewriteRules *RewriteRules) erro log.Error( "cannot find rewrite rule for file start key", zap.Int64("tableID", tableID), - zap.Stringer("file", file), + utils.ZapFile(file), ) return errors.Errorf("cannot find rewrite rule") } @@ -321,7 +322,7 @@ func ValidateFileRewriteRule(file *backup.File, rewriteRules *RewriteRules) erro log.Error( "cannot find rewrite rule for file end key", zap.Int64("tableID", tableID), - zap.Stringer("file", file), + utils.ZapFile(file), ) return errors.Errorf("cannot find rewrite rule") } @@ -335,7 +336,7 @@ func ValidateFileRewriteRule(file *backup.File, rewriteRules *RewriteRules) erro zap.Int64("endTableID", endTableID), zap.Stringer("startRule", startRule), zap.Stringer("endRule", endRule), - zap.Stringer("file", file), + utils.ZapFile(file), ) return errors.Errorf("unexpected rewrite rules") } @@ -422,7 +423,7 @@ func rewriteFileKeys(file *backup.File, rewriteRules *RewriteRules) (startKey, e startKey, rule = rewriteRawKey(file.GetStartKey(), rewriteRules) if rewriteRules != nil && rule == nil { log.Error("cannot find rewrite rule", - zap.Binary("startKey", file.GetStartKey()), + zap.Stringer("startKey", utils.WrapKey(file.GetStartKey())), zap.Reflect("rewrite table", rewriteRules.Table), zap.Reflect("rewrite data", rewriteRules.Data)) err = errors.New("cannot find rewrite rule for start key") @@ -437,8 +438,8 @@ func rewriteFileKeys(file *backup.File, rewriteRules *RewriteRules) (startKey, e log.Error("table ids dont matched", zap.Int64("startID", startID), zap.Int64("endID", endID), - zap.Binary("startKey", startKey), - zap.Binary("endKey", endKey)) + zap.Stringer("startKey", utils.WrapKey(startKey)), + zap.Stringer("endKey", utils.WrapKey(endKey))) err = errors.New("illegal table id") } return @@ -503,7 +504,7 @@ func hasRejectStorePeer( } retryTimes := ctx.Value(retryTimes).(int) if retryTimes > 10 { - log.Warn("get region info", zap.Stringer("region", regionInfo.Region)) + log.Warn("get region info", utils.ZapRegion(regionInfo.Region)) } return false, nil } @@ -521,7 +522,7 @@ func waitForRemoveRejectStores( ok, err := hasRejectStorePeer(ctx1, client, regionID, rejectStores) if err != nil { log.Warn("wait for rejecting store failed", - zap.Stringer("region", regionInfo.Region), + utils.ZapRegion(regionInfo.Region), zap.Error(err)) return false } diff --git a/pkg/rtree/rtree.go b/pkg/rtree/rtree.go index 5744083b3..688b91c1a 100644 --- a/pkg/rtree/rtree.go +++ b/pkg/rtree/rtree.go @@ -10,6 +10,8 @@ import ( "github.com/pingcap/kvproto/pkg/backup" "github.com/pingcap/log" "go.uber.org/zap" + + "github.com/pingcap/br/pkg/utils" ) // Range represents a backup response. @@ -132,8 +134,8 @@ func (rangeTree *RangeTree) Update(rg Range) { // Range has backuped, overwrite overlapping range. for _, item := range overlaps { log.Info("delete overlapping range", - zap.Binary("StartKey", item.StartKey), - zap.Binary("EndKey", item.EndKey), + zap.Stringer("StartKey", utils.WrapKey(item.StartKey)), + zap.Stringer("EndKey", utils.WrapKey(item.EndKey)), ) rangeTree.Delete(item) } diff --git a/pkg/utils/logging.go b/pkg/utils/logging.go new file mode 100644 index 000000000..aa68c7b1e --- /dev/null +++ b/pkg/utils/logging.go @@ -0,0 +1,116 @@ +// Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0. + +package utils + +import ( + "encoding/hex" + "fmt" + "strings" + + "github.com/google/uuid" + "github.com/pingcap/kvproto/pkg/backup" + "github.com/pingcap/kvproto/pkg/import_sstpb" + "github.com/pingcap/kvproto/pkg/metapb" + "github.com/pingcap/tidb/kv" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +type zapMarshalFileMixIn struct{ *backup.File } + +func (file zapMarshalFileMixIn) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddString("name", file.GetName()) + enc.AddString("CF", file.GetCf()) + enc.AddString("sha256", hex.EncodeToString(file.GetSha256())) + enc.AddString("startKey", WrapKey(file.GetStartKey()).String()) + enc.AddString("endKey", WrapKey(file.GetEndKey()).String()) + enc.AddUint64("startVersion", file.GetStartVersion()) + enc.AddUint64("endVersion", file.GetEndVersion()) + enc.AddUint64("totalKvs", file.GetTotalKvs()) + enc.AddUint64("totalBytes", file.GetTotalBytes()) + enc.AddUint64("CRC64Xor", file.GetCrc64Xor()) + return nil +} + +type zapMarshalRewriteRuleMixIn struct{ *import_sstpb.RewriteRule } + +func (rewriteRule zapMarshalRewriteRuleMixIn) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddString("oldKeyPrefix", hex.EncodeToString(rewriteRule.GetOldKeyPrefix())) + enc.AddString("newKeyPrefix", hex.EncodeToString(rewriteRule.GetNewKeyPrefix())) + enc.AddUint64("newTimestamp", rewriteRule.GetNewTimestamp()) + return nil +} + +type zapMarshalRegionMixIn struct{ *metapb.Region } + +func (region zapMarshalRegionMixIn) MarshalLogObject(enc zapcore.ObjectEncoder) error { + peers := make([]string, 0, len(region.GetPeers())) + for _, peer := range region.GetPeers() { + peers = append(peers, peer.String()) + } + enc.AddUint64("ID", region.Id) + enc.AddString("startKey", WrapKey(region.GetStartKey()).String()) + enc.AddString("endKey", WrapKey(region.GetEndKey()).String()) + enc.AddString("epoch", region.GetRegionEpoch().String()) + enc.AddString("peers", strings.Join(peers, ",")) + return nil +} + +type zapMarshalSSTMetaMixIn struct{ *import_sstpb.SSTMeta } + +func (sstMeta zapMarshalSSTMetaMixIn) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddString("CF", sstMeta.GetCfName()) + enc.AddBool("endKeyExclusive", sstMeta.EndKeyExclusive) + enc.AddUint32("CRC32", sstMeta.Crc32) + enc.AddUint64("length", sstMeta.Length) + enc.AddUint64("regionID", sstMeta.RegionId) + enc.AddString("regionEpoch", sstMeta.RegionEpoch.String()) + enc.AddString("rangeStart", WrapKey(sstMeta.GetRange().GetStart()).String()) + enc.AddString("rangeEnd", WrapKey(sstMeta.GetRange().GetEnd()).String()) + + sstUUID, err := uuid.FromBytes(sstMeta.GetUuid()) + if err != nil { + return err + } + enc.AddString("UUID", sstUUID.String()) + return nil +} + +type zapArrayMarshalKeysMixIn [][]byte + +func (keys zapArrayMarshalKeysMixIn) MarshalLogArray(enc zapcore.ArrayEncoder) error { + for _, key := range keys { + enc.AppendString(WrapKey(key).String()) + } + return nil +} + +// WrapKey wrap a key as a Stringer that can print proper upper hex format. +func WrapKey(key []byte) fmt.Stringer { + return kv.Key(key) +} + +// WrapKeys wrap keys as an ArrayMarshaler that can print proper upper hex format. +func WrapKeys(keys [][]byte) zapcore.ArrayMarshaler { + return zapArrayMarshalKeysMixIn(keys) +} + +// ZapRewriteRule make the zap fields for a rewrite rule. +func ZapRewriteRule(rewriteRule *import_sstpb.RewriteRule) zapcore.Field { + return zap.Object("rewriteRule", zapMarshalRewriteRuleMixIn{rewriteRule}) +} + +// ZapRegion make the zap fields for a region. +func ZapRegion(region *metapb.Region) zapcore.Field { + return zap.Object("region", zapMarshalRegionMixIn{region}) +} + +// ZapFile make the zap fields for a file. +func ZapFile(file *backup.File) zapcore.Field { + return zap.Object("file", zapMarshalFileMixIn{file}) +} + +// ZapSSTMeta make the zap fields for a SST meta. +func ZapSSTMeta(sstMeta *import_sstpb.SSTMeta) zapcore.Field { + return zap.Object("sstMeta", zapMarshalSSTMetaMixIn{sstMeta}) +}