From 766635220f8ef52d91ccf1b84a9d508301e74037 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Fri, 7 Sep 2018 15:22:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0Dump=E5=88=B0STDOUT=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20=E8=AF=AD=E6=B3=95:=20rdr=20dump=20FILE1?= =?UTF-8?q?=20[FILE2]=20[FILE3]...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/main.go b/main.go index 9b128e0..f973ad2 100644 --- a/main.go +++ b/main.go @@ -28,6 +28,7 @@ import ( "github.com/elazarl/go-bindata-assetfs" "github.com/julienschmidt/httprouter" "github.com/xueqiu/rdr/static" + "encoding/json" ) //go:generate go-bindata -prefix "static/" -o=static/static.go -pkg=static -ignore static.go static/... @@ -50,6 +51,71 @@ func decode(c *cli.Context, decoder *Decoder, filepath string) { var counters = NewSafeMap() +func getData(filename string, cnt *Counter) map[string]interface{} { + data := make(map[string]interface{}) + data["CurrentInstance"] = filename + data["LargestKeys"] = cnt.GetLargestEntries(100) + + largestKeyPrefixesByType := map[string][]*PrefixEntry{} + for _, entry := range cnt.GetLargestKeyPrefixes() { + // if mem usage is less than 1M, and the list is long enough, then it's unnecessary to add it. + if entry.Bytes < 1000*1000 && len(largestKeyPrefixesByType[entry.Type]) > 50 { + continue + } + largestKeyPrefixesByType[entry.Type] = append(largestKeyPrefixesByType[entry.Type], entry) + } + data["LargestKeyPrefixes"] = largestKeyPrefixesByType + + data["TypeBytes"] = cnt.typeBytes + data["TypeNum"] = cnt.typeNum + totalNum := uint64(0) + for _, v := range cnt.typeNum { + totalNum += v + } + totalBytes := uint64(0) + for _, v := range cnt.typeBytes { + totalBytes += v + } + data["TotleNum"] = totalNum + data["TotleBytes"] = totalBytes + + lenLevelCount := map[string][]*PrefixEntry{} + for _, entry := range cnt.GetLenLevelCount() { + lenLevelCount[entry.Type] = append(lenLevelCount[entry.Type], entry) + } + data["LenLevelCount"] = lenLevelCount + return data +} + +// dump rdb file statistical information to STDOUT. +func dump(cli *cli.Context) { + if cli.NArg() < 1 { + fmt.Fprintln(cli.App.ErrWriter, " requires at least 1 argument") + return + } + + // parse rdbfile + fmt.Fprintln(cli.App.Writer, "[") + nargs := cli.NArg() + for i := 0; i < nargs; i++ { + file := cli.Args().Get(i) + decoder := NewDecoder() + go decode(cli, decoder, file) + cnt := NewCounter() + cnt.Count(decoder.Entries) + filename := filepath.Base(file) + data := getData(filename, cnt) + jsonBytes, _ := json.MarshalIndent(data, "", " ") + fmt.Fprint(cli.App.Writer, string(jsonBytes)) + if i == nargs-1 { + fmt.Fprintln(cli.App.Writer) + } else { + fmt.Fprintln(cli.App.Writer, ",") + } + } + fmt.Fprintln(cli.App.Writer, "]") +} + // show parse rdbfile(s) and show statistical information by html func show(c *cli.Context) { if c.NArg() < 1 { @@ -119,6 +185,12 @@ func main() { app.Writer = os.Stdout app.ErrWriter = os.Stderr app.Commands = []cli.Command{ + cli.Command{ + Name: "dump", + Usage: "dump statistical information of rdbfile to STDOUT", + ArgsUsage: "FILE1 [FILE2] [FILE3]...", + Action: dump, + }, cli.Command{ Name: "show", Usage: "show statistical information of rdbfile by webpage", @@ -145,3 +217,4 @@ func main() { } app.Run(os.Args) } +