From fa0f4a4d5918e880e3c6dcde4c09b95536dd2cb2 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Fri, 26 May 2017 14:57:26 +0100 Subject: [PATCH] add copyreport utility useful for codec and report structure experiments --- extras/copyreport/Makefile | 19 ++++++++++ extras/copyreport/main.go | 26 ++++++++++++++ report/marshal.go | 73 +++++++++++++++++++++++++++++--------- 3 files changed, 102 insertions(+), 16 deletions(-) create mode 100644 extras/copyreport/Makefile create mode 100644 extras/copyreport/main.go diff --git a/extras/copyreport/Makefile b/extras/copyreport/Makefile new file mode 100644 index 000000000..70334ba49 --- /dev/null +++ b/extras/copyreport/Makefile @@ -0,0 +1,19 @@ +.PHONY: all vet lint build test clean + +all: build test vet lint + +vet: + go vet ./... + +lint: + golint . + +build: + go build + +test: + go test + +clean: + go clean + diff --git a/extras/copyreport/main.go b/extras/copyreport/main.go new file mode 100644 index 000000000..07e47d067 --- /dev/null +++ b/extras/copyreport/main.go @@ -0,0 +1,26 @@ +// Copy a report, decoding and re-encoding it. +package main + +import ( + "compress/gzip" + "flag" + "log" + + "github.com/weaveworks/scope/report" +) + +func main() { + flag.Parse() + + if len(flag.Args()) != 2 { + log.Fatal("usage: copyreport src.(json|msgpack)[.gz] dst.(json|msgpack)[.gz]") + } + + rpt, err := report.MakeFromFile(flag.Arg(0)) + if err != nil { + log.Fatal(err) + } + if err = rpt.WriteToFile(flag.Arg(1), gzip.DefaultCompression); err != nil { + log.Fatal(err) + } +} diff --git a/report/marshal.go b/report/marshal.go index 6ebe044f1..36c7d2d0d 100644 --- a/report/marshal.go +++ b/report/marshal.go @@ -1,6 +1,7 @@ package report import ( + "bufio" "bytes" "compress/gzip" "fmt" @@ -133,22 +134,9 @@ func MakeFromFile(path string) (rpt Report, _ error) { } defer f.Close() - var ( - handle codec.Handle - gzipped bool - ) - fileType := filepath.Ext(path) - if fileType == ".gz" { - gzipped = true - fileType = filepath.Ext(strings.TrimSuffix(path, fileType)) - } - switch fileType { - case ".json": - handle = &codec.JsonHandle{} - case ".msgpack": - handle = &codec.MsgpackHandle{} - default: - return rpt, fmt.Errorf("Unsupported file extension: %v", fileType) + handle, gzipped, err := handlerFromFileType(path) + if err != nil { + return rpt, err } var buf []byte @@ -168,3 +156,56 @@ func MakeFromFile(path string) (rpt Report, _ error) { return rpt, err } + +// WriteToFile writes a Report to a file. The encoding is determined +// by the file extension (".msgpack" or ".json", with an optional +// ".gz"). +func (rep *Report) WriteToFile(path string, compressionLevel int) error { + f, err := os.Create(path) + if err != nil { + return err + } + defer f.Close() + + handle, gzipped, err := handlerFromFileType(path) + if err != nil { + return err + } + + var w io.Writer + bufwriter := bufio.NewWriter(f) + defer bufwriter.Flush() + w = bufwriter + if gzipped { + gzwriter, err := gzip.NewWriterLevel(w, compressionLevel) + if err != nil { + return err + } + defer gzwriter.Close() + w = gzwriter + } + + if err = codec.NewEncoder(w, handle).Encode(rep); err != nil { + return err + } + + return nil + +} + +func handlerFromFileType(path string) (codec.Handle, bool, error) { + fileType := filepath.Ext(path) + gzipped := false + if fileType == ".gz" { + gzipped = true + fileType = filepath.Ext(strings.TrimSuffix(path, fileType)) + } + switch fileType { + case ".json": + return &codec.JsonHandle{}, gzipped, nil + case ".msgpack": + return &codec.MsgpackHandle{}, gzipped, nil + default: + return nil, false, fmt.Errorf("Unsupported file extension: %v", fileType) + } +}