From a971d8a8430557c595c731a2452ad93a96ed3860 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Tue, 18 Aug 2015 15:48:42 +0300 Subject: [PATCH] Change file format to be text based --- Makefile | 2 +- input_dummy.go | 7 +++++-- input_file.go | 50 ++++++++++++++++++++++++++++++++++---------------- output_file.go | 18 ++++-------------- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/Makefile b/Makefile index 11ce2c6..c051a84 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ drun: docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go run $(SOURCE) --input-dummy=0 --output-http="http://localhost:9000" --input-http :9000 --verbose drecord: - docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go run $(SOURCE) --input-dummy=0 --output-file=requests.bin --verbose + docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go run $(SOURCE) --input-dummy=0 --output-file=requests.gor --verbose dreplay: docker run -v `pwd`:$(SOURCE_PATH) -t -i gor go run $(SOURCE) --input-file=requests.bin --output-tcp=:9000 --verbose -h diff --git a/input_dummy.go b/input_dummy.go index f439179..4c14830 100644 --- a/input_dummy.go +++ b/input_dummy.go @@ -21,9 +21,12 @@ func NewDummyInput(options string) (di *DummyInput) { func (i *DummyInput) Read(data []byte) (int, error) { buf := <-i.data - copy(data, buf) - return len(buf), nil + header := payloadHeader(RequestPayload, uuid(), time.Now().UnixNano()) + copy(data[0:len(header)], header) + copy(data[len(header):], buf) + + return len(buf) + len(header), nil } func (i *DummyInput) emit() { diff --git a/input_file.go b/input_file.go index 60c93ec..0a38428 100644 --- a/input_file.go +++ b/input_file.go @@ -1,9 +1,11 @@ package main import ( - "encoding/gob" "log" "os" + "bufio" + "bytes" + "strconv" "time" ) @@ -11,7 +13,7 @@ import ( type FileInput struct { data chan []byte path string - decoder *gob.Decoder + file *os.File speedFactor float64 } @@ -35,7 +37,7 @@ func (i *FileInput) init(path string) { log.Fatal(i, "Cannot open file %q. Error: %s", path, err) } - i.decoder = gob.NewDecoder(file) + i.file = file } func (i *FileInput) Read(data []byte) (int, error) { @@ -49,30 +51,46 @@ func (i *FileInput) String() string { return "File input: " + i.path } +func scanSeparator(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + + if i := bytes.Index(data, []byte(fileSeparator)); i >= 0 { + // We have a full newline-terminated line. + return i + len(fileSeparator), data[0:i], nil + } + + if atEOF { + return len(data), data, nil + } + return 0, nil, nil +} + func (i *FileInput) emit() { var lastTime int64 - for { - raw := new(RawRequest) - err := i.decoder.Decode(raw) + // reader := bufio.NewReader(conn) + scanner := bufio.NewScanner(i.file) + scanner.Split(scanSeparator) - if err != nil { - return - } + for scanner.Scan() { + buf := scanner.Bytes() + meta := payloadMeta(buf) - if lastTime != 0 { - timeDiff := raw.Timestamp - lastTime + if meta[0][0] == '1' && lastTime != 0 { + ts, _ := strconv.ParseInt(string(meta[2]), 10, 64) + timeDiff := ts - lastTime - // We can speedup or slowdown execution based on speedFactor if i.speedFactor != 1 { - timeDiff = int64(float64(raw.Timestamp-lastTime) / i.speedFactor) + timeDiff = int64(float64(timeDiff) / i.speedFactor) } time.Sleep(time.Duration(timeDiff)) + + lastTime = ts } - lastTime = raw.Timestamp - - i.data <- raw.Request + i.data <- buf } } diff --git a/output_file.go b/output_file.go index fab2210..d01f05f 100644 --- a/output_file.go +++ b/output_file.go @@ -1,23 +1,14 @@ package main import ( - "encoding/gob" "io" "log" "os" - "time" ) -// RawRequest stores original start time and request payload -type RawRequest struct { - Timestamp int64 - Request []byte -} - // FileOutput output plugin type FileOutput struct { path string - encoder *gob.Encoder file *os.File } @@ -38,18 +29,17 @@ func (o *FileOutput) init(path string) { if err != nil { log.Fatal(o, "Cannot open file %q. Error: %s", path, err) } - - o.encoder = gob.NewEncoder(o.file) } +var fileSeparator = "\nšŸµšŸ™ˆšŸ™‰\n" + func (o *FileOutput) Write(data []byte) (n int, err error) { if !isOriginPayload(data) { return len(data), nil } - raw := RawRequest{time.Now().UnixNano(), data} - - o.encoder.Encode(raw) + o.file.Write(data) + o.file.Write([]byte(fileSeparator)) return len(data), nil }