Skip to content

Commit

Permalink
Merge pull request cockroachdb#7649 from petermattis/pmattis/keys-pre…
Browse files Browse the repository at this point in the history
…tty-print

keys: pretty-print timeseries keys
  • Loading branch information
petermattis authored Jul 7, 2016
2 parents 98b248e + 3052748 commit 8ce5a00
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 9 deletions.
14 changes: 14 additions & 0 deletions keys/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import (
"github.com/cockroachdb/cockroach/util/uuid"
)

// PrettyPrintTimeseriesKey is a hook for pretty printing a timeseries key. The
// timeseries key prefix will already have been stripped off.
var PrettyPrintTimeseriesKey func(key roachpb.Key) string

type dictEntry struct {
name string
prefix roachpb.Key
Expand Down Expand Up @@ -105,6 +109,10 @@ var (
ppFunc: decodeKeyPrint,
psFunc: parseUnsupported,
},
{name: "/tsd", prefix: TimeseriesPrefix,
ppFunc: decodeTimeseriesKey,
psFunc: parseUnsupported,
},
}},
{name: "/Table", start: TableDataMin, end: TableDataMax, entries: []dictEntry{
{name: "", prefix: nil, ppFunc: decodeKeyPrint,
Expand Down Expand Up @@ -143,6 +151,8 @@ var (
{name: "RangeLastVerificationTimestamp", suffix: LocalRangeLastVerificationTimestampSuffix},
{name: "RangeLeaderLease", suffix: LocalRangeLeaderLeaseSuffix},
{name: "RangeStats", suffix: LocalRangeStatsSuffix},
{name: "RangeFrozenStatus", suffix: LocalRangeFrozenStatusSuffix},
{name: "RangeLastGC", suffix: LocalRangeLastGCSuffix},
}

rangeSuffixDict = []struct {
Expand Down Expand Up @@ -408,6 +418,10 @@ func decodeKeyPrint(key roachpb.Key) string {
return encoding.PrettyPrintValue(key, "/")
}

func decodeTimeseriesKey(key roachpb.Key) string {
return PrettyPrintTimeseriesKey(key)
}

// prettyPrintInternal parse key with prefix in keyDict,
// if the key don't march any prefix in keyDict, return its byte value with quotation and false,
// or else return its human readable value and true.
Expand Down
2 changes: 2 additions & 0 deletions keys/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ func TestPrettyPrint(t *testing.T) {
{RaftTruncatedStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RaftTruncatedState"},
{RangeLeaderLeaseKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeLeaderLease"},
{RangeStatsKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeStats"},
{RangeFrozenStatusKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeFrozenStatus"},
{RangeLastGCKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeLastGC"},

{RaftHardStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RaftHardState"},
{RaftLastIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RaftLastIndex"},
Expand Down
22 changes: 21 additions & 1 deletion ts/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package ts

import (
"bytes"
"fmt"
"time"

"github.com/cockroachdb/cockroach/keys"
"github.com/cockroachdb/cockroach/roachpb"
Expand Down Expand Up @@ -81,8 +83,13 @@ func DecodeDataKey(key roachpb.Key) (string, string, Resolution, int64, error) {
}
remainder = remainder[len(keys.TimeseriesPrefix):]

return decodeDataKeySuffix(remainder)
}

// decodeDataKeySuffix decodes a time series key into its components.
func decodeDataKeySuffix(key roachpb.Key) (string, string, Resolution, int64, error) {
// Decode series name.
remainder, name, err := encoding.DecodeBytesAscending(remainder, nil)
remainder, name, err := encoding.DecodeBytesAscending(key, nil)
if err != nil {
return "", "", 0, 0, err
}
Expand All @@ -103,3 +110,16 @@ func DecodeDataKey(key roachpb.Key) (string, string, Resolution, int64, error) {

return string(name), string(source), resolution, timestamp, nil
}

func prettyPrintKey(key roachpb.Key) string {
name, source, resolution, timestamp, err := decodeDataKeySuffix(key)
if err != nil {
return "/" + err.Error()
}
return fmt.Sprintf("/%s/%s/%s/%s", name, source, resolution,
time.Unix(0, timestamp).UTC().Format(time.RFC3339Nano))
}

func init() {
keys.PrettyPrintTimeseriesKey = prettyPrintKey
}
23 changes: 15 additions & 8 deletions ts/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,42 +28,46 @@ import (
func TestDataKeys(t *testing.T) {
defer leaktest.AfterTest(t)()
testCases := []struct {
name string
source string
timestamp int64
resolution Resolution
expectedLen int
name string
source string
timestamp int64
resolution Resolution
expectedLen int
expectedPretty string
}{
{
"test.metric",
"testsource",
0,
Resolution10s,
30,
"/System/tsd/test.metric/testsource/10s/1970-01-01T00:00:00Z",
},
{
"test.no.source",
"",
1429114700000000000,
Resolution10s,
26,
"/System/tsd/test.no.source//10s/2015-04-15T16:00:00Z",
},
{
"",
"",
-1429114700000000000,
Resolution10s,
12,
"/System/tsd///10s/1924-09-18T08:00:00Z",
},
}

for i, tc := range testCases {
encoded := MakeDataKey(tc.name, tc.source, tc.resolution, tc.timestamp)
if !bytes.HasPrefix(encoded, keys.TimeseriesPrefix) {
t.Errorf("case %d, encoded key %v did not have time series data prefix", i, encoded)
t.Errorf("%d: encoded key %v did not have time series data prefix", i, encoded)
}
if a, e := len(encoded), tc.expectedLen; a != e {
t.Errorf("case %d, encoded length %d did not match expected %d", i, a, e)
t.Errorf("%d: encoded length %d did not match expected %d", i, a, e)
}

// Normalize timestamp of test case; we expect MakeDataKey to
Expand All @@ -78,7 +82,10 @@ func TestDataKeys(t *testing.T) {
t.Fatal(err)
}
if !reflect.DeepEqual(d, tc) {
t.Errorf("case %d, decoded values %v did not match expected %v", i, d, tc)
t.Errorf("%d: decoded values %v did not match expected %v", i, d, tc)
}
if pretty := keys.PrettyPrint(encoded); tc.expectedPretty != pretty {
t.Errorf("%d: expected %s, but got %s", i, tc.expectedPretty, pretty)
}
}
}
10 changes: 10 additions & 0 deletions ts/resolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ import (
// Cockroach.
type Resolution int64

func (r Resolution) String() string {
switch r {
case Resolution10s:
return "10s"
case resolution1ns:
return "1ns"
}
return fmt.Sprintf("%d", r)
}

// Resolution enumeration values are directly serialized and persisted into
// system keys; these values must never be altered or reordered.
const (
Expand Down

0 comments on commit 8ce5a00

Please sign in to comment.