forked from pingcap/tidb
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
store/tikv,util/logutil: add a function to convert proto.Message to h…
…ex format (pingcap#11550)
- Loading branch information
1 parent
d51a3e0
commit 31a8e21
Showing
4 changed files
with
149 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright 2019 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by aprettyPrintlicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package logutil | ||
|
||
import ( | ||
"bytes" | ||
"encoding/hex" | ||
"fmt" | ||
"io" | ||
"reflect" | ||
"strings" | ||
|
||
"github.com/golang/protobuf/proto" | ||
) | ||
|
||
// Hex defines a fmt.Stringer for proto.Message. | ||
// We can't define the String() method on proto.Message, but we can wrap it. | ||
func Hex(msg proto.Message) fmt.Stringer { | ||
return hexStringer{msg} | ||
} | ||
|
||
type hexStringer struct { | ||
proto.Message | ||
} | ||
|
||
func (h hexStringer) String() string { | ||
val := reflect.ValueOf(h.Message) | ||
var w bytes.Buffer | ||
prettyPrint(&w, val) | ||
return w.String() | ||
} | ||
|
||
func prettyPrint(w io.Writer, val reflect.Value) { | ||
tp := val.Type() | ||
switch val.Kind() { | ||
case reflect.Slice: | ||
elemType := tp.Elem() | ||
if elemType.Kind() == reflect.Uint8 { | ||
fmt.Fprintf(w, "%s", hex.EncodeToString(val.Bytes())) | ||
} else { | ||
fmt.Fprintf(w, "%s", val.Interface()) | ||
} | ||
case reflect.Struct: | ||
fmt.Fprintf(w, "{") | ||
for i := 0; i < val.NumField(); i++ { | ||
fv := val.Field(i) | ||
ft := tp.Field(i) | ||
if strings.HasPrefix(ft.Name, "XXX_") { | ||
continue | ||
} | ||
if i != 0 { | ||
fmt.Fprintf(w, " ") | ||
} | ||
fmt.Fprintf(w, "%s:", ft.Name) | ||
prettyPrint(w, fv) | ||
} | ||
fmt.Fprintf(w, "}") | ||
case reflect.Ptr: | ||
if val.IsNil() { | ||
fmt.Fprintf(w, "%v", val.Interface()) | ||
} else { | ||
prettyPrint(w, reflect.Indirect(val)) | ||
} | ||
default: | ||
fmt.Fprintf(w, "%v", val.Interface()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Copyright 2017 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package logutil_test | ||
|
||
import ( | ||
"bytes" | ||
"encoding/hex" | ||
"reflect" | ||
|
||
. "github.com/pingcap/check" | ||
"github.com/pingcap/kvproto/pkg/metapb" | ||
"github.com/pingcap/tidb/kv" | ||
"github.com/pingcap/tidb/util/logutil" | ||
) | ||
|
||
var _ = Suite(&testHexSuite{}) | ||
|
||
type testHexSuite struct{} | ||
|
||
func (s *testHexSuite) SetUpSuite(c *C) {} | ||
|
||
func (s *testHexSuite) SetUpTest(c *C) {} | ||
|
||
func (s *testHexSuite) TestHex(c *C) { | ||
var region metapb.Region | ||
region.Id = 6662 | ||
region.StartKey = []byte{'t', 200, '\\', 000, 000, 000, '\\', 000, 000, 000, 37, '-', 000, 000, 000, 000, 000, 000, 000, 37} | ||
region.EndKey = []byte("3asg3asd") | ||
|
||
c.Assert(logutil.Hex(®ion).String(), Equals, "{Id:6662 StartKey:74c85c0000005c000000252d0000000000000025 EndKey:3361736733617364 RegionEpoch:<nil> Peers:[]}") | ||
} | ||
|
||
func (s *testHexSuite) TestPrettyPrint(c *C) { | ||
var buf bytes.Buffer | ||
|
||
byteSlice := []byte("asd2fsdafs中文3af") | ||
logutil.PrettyPrint(&buf, reflect.ValueOf(byteSlice)) | ||
c.Assert(buf.String(), Equals, "61736432667364616673e4b8ade69687336166") | ||
c.Assert(buf.String(), Equals, hex.EncodeToString(byteSlice)) | ||
buf.Reset() | ||
|
||
// Go reflect can't distinguish uint8 from byte! | ||
intSlice := []uint8{1, 2, 3, uint8('a'), uint8('b'), uint8('c'), uint8('\'')} | ||
logutil.PrettyPrint(&buf, reflect.ValueOf(intSlice)) | ||
c.Assert(buf.String(), Equals, "01020361626327") | ||
buf.Reset() | ||
|
||
var ran kv.KeyRange | ||
ran.StartKey = kv.Key("_txxey23_i263") | ||
ran.EndKey = nil | ||
logutil.PrettyPrint(&buf, reflect.ValueOf(ran)) | ||
c.Assert(buf.String(), Equals, "{StartKey:5f747878657932335f69323633 EndKey:}") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters