Skip to content

Commit 2e7d26c

Browse files
committed
Add missing PRO functionality and improve license protection
1 parent abbd249 commit 2e7d26c

15 files changed

+520
-307
lines changed

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ vendor
1111
hey
1212

1313
*.bin
14-
14+
lib/
15+
output/
1516
*.gz
1617
*.zip
18+
.aider*
1719

1820
*.class
1921

@@ -32,4 +34,4 @@ goreplay
3234
corpus
3335
crashers
3436
suppressions
35-
dist
37+
dist

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Copyright (c) 2011-present Leonid Bugaev
33
Portions of this software are licensed as follows:
44

55
* All content residing under the "doc/" directory of this repository is licensed under "Creative Commons: CC BY-SA 4.0 license".
6-
* Files with the following names "pro.go", "s3_reader.go", "output_s3.go" are released under the commercial license specified in "COMM-LICENSE" file.
6+
* The file "pro.go" and all files ending with the "_pro.go" suffix are released under the commercial license specified in the "COMM-LICENSE" file.
77
* Content outside of the above mentioned directories or restrictions above is available under the "LGPLv3" license as defined below.
88

99

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,4 @@ bash:
158158
$(RUN) /bin/bash
159159

160160
dist:
161-
mkdir -p $(DIST_PATH)
161+
mkdir -p $(DIST_PATH)

ce.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//go:build !pro
2+
3+
package goreplay
4+
5+
import (
6+
"fmt"
7+
)
8+
9+
// PRO this value indicates if goreplay is running in PRO mode.
10+
var PRO = false
11+
12+
func SettingsHook(settings *AppSettings) {
13+
if settings.RecognizeTCPSessions {
14+
settings.RecognizeTCPSessions = false
15+
fmt.Println("[ERROR] TCP session recognition is not supported in the open-source version of GoReplay")
16+
}
17+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/buger/goreplay
22

3-
go 1.19
3+
go 1.21
44

55
require (
66
github.com/Shopify/sarama v1.38.1

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
55
github.com/Shopify/sarama v1.38.1 h1:lqqPUPQZ7zPqYlWpTh+LQ9bhYNu2xJL6k1SJN4WVe2A=
66
github.com/Shopify/sarama v1.38.1/go.mod h1:iwv9a67Ha8VNa+TifujYoWGxWnu2kNVAQdSdZ4X2o5g=
77
github.com/Shopify/toxiproxy/v2 v2.5.0 h1:i4LPT+qrSlKNtQf5QliVjdP08GyAH8+BUIc9gT0eahc=
8+
github.com/Shopify/toxiproxy/v2 v2.5.0/go.mod h1:yhM2epWtAmel9CB8r2+L+PCmhH6yH2pITaPAo7jxJl0=
89
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
910
github.com/araddon/gou v0.0.0-20211019181548-e7d08105776c h1:XUqw//RExYoxW4Eie8MuKp8sEDAZI1gMHX/daUFgZww=
1011
github.com/araddon/gou v0.0.0-20211019181548-e7d08105776c/go.mod h1:ikc1XA58M+Rx7SEbf0bLJCfBkwayZ8T5jBo5FXK8Uz8=
@@ -47,6 +48,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m
4748
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
4849
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
4950
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
51+
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
5052
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
5153
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
5254
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
@@ -58,6 +60,7 @@ github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En
5860
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
5961
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
6062
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
63+
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
6164
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
6265
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
6366
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -96,6 +99,7 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
9699
github.com/google/gopacket v1.1.20-0.20210429153827-3eaba0894325 h1:YmIcZ5Var3BAQ64AW98Iiys5Ih4fiU0xK41+8isC5Ec=
97100
github.com/google/gopacket v1.1.20-0.20210429153827-3eaba0894325/go.mod h1:riddUzxTSBpJXk3qBHtYr4qOhFhT6k/1c0E3qkQjQpA=
98101
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
102+
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
99103
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
100104
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
101105
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -143,6 +147,7 @@ github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs
143147
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
144148
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
145149
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
150+
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
146151
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
147152
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
148153
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -159,7 +164,9 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
159164
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
160165
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
161166
github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
167+
github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
162168
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
169+
github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
163170
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
164171
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
165172
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -170,12 +177,14 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X
170177
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
171178
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
172179
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
180+
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
173181
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
174182
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
175183
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
176184
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
177185
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
178186
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
187+
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
179188
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
180189
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
181190
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@@ -253,6 +262,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
253262
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
254263
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
255264
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
265+
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
256266
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
257267
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
258268
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -302,6 +312,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
302312
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
303313
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
304314
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
315+
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
305316
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
306317
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
307318
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

input_file.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,16 @@ func NewFileInput(path string, loop bool, readDepth int, maxWait time.Duration,
238238
return
239239
}
240240

241+
func parseS3Url(path string) (bucket, key string) {
242+
path = path[5:] // stripping `s3://`
243+
sep := strings.IndexByte(path, '/')
244+
245+
bucket = path[:sep]
246+
key = path[sep+1:]
247+
248+
return bucket, key
249+
}
250+
241251
func (i *FileInput) init() (err error) {
242252
defer i.mu.Unlock()
243253
i.mu.Lock()

output_binary.go

Lines changed: 13 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
//go:build !pro
2+
13
package goreplay
24

35
import (
4-
"github.com/buger/goreplay/internal/size"
5-
"sync/atomic"
6+
"errors"
67
"time"
8+
9+
"github.com/buger/goreplay/internal/size"
710
)
811

12+
var _ PluginWriter = (*BinaryOutput)(nil)
13+
914
// BinaryOutputConfig struct for holding binary output configuration
1015
type BinaryOutputConfig struct {
1116
Workers int `json:"output-binary-workers"`
@@ -19,155 +24,30 @@ type BinaryOutputConfig struct {
1924
// By default workers pool is dynamic and starts with 10 workers
2025
// You can specify fixed number of workers using `--output-tcp-workers`
2126
type BinaryOutput struct {
22-
// Keep this as first element of struct because it guarantees 64bit
23-
// alignment. atomic.* functions crash on 32bit machines if operand is not
24-
// aligned at 64bit. See https://github.com/golang/go/issues/599
25-
activeWorkers int64
26-
address string
27-
queue chan *Message
28-
responses chan response
29-
needWorker chan int
30-
quit chan struct{}
31-
config *BinaryOutputConfig
32-
queueStats *GorStat
27+
address string
3328
}
3429

3530
// NewBinaryOutput constructor for BinaryOutput
3631
// Initialize workers
3732
func NewBinaryOutput(address string, config *BinaryOutputConfig) PluginReadWriter {
38-
o := new(BinaryOutput)
39-
40-
o.address = address
41-
o.config = config
42-
43-
o.queue = make(chan *Message, 1000)
44-
o.responses = make(chan response, 1000)
45-
o.needWorker = make(chan int, 1)
46-
o.quit = make(chan struct{})
47-
48-
// Initial workers count
49-
if o.config.Workers == 0 {
50-
o.needWorker <- initialDynamicWorkers
51-
} else {
52-
o.needWorker <- o.config.Workers
53-
}
54-
55-
go o.workerMaster()
56-
57-
return o
58-
}
59-
60-
func (o *BinaryOutput) workerMaster() {
61-
for {
62-
newWorkers := <-o.needWorker
63-
for i := 0; i < newWorkers; i++ {
64-
go o.startWorker()
65-
}
66-
67-
// Disable dynamic scaling if workers poll fixed size
68-
if o.config.Workers != 0 {
69-
return
70-
}
71-
}
33+
return &BinaryOutput{address: address}
7234
}
7335

74-
func (o *BinaryOutput) startWorker() {
75-
client := NewTCPClient(o.address, &TCPClientConfig{
76-
Debug: o.config.Debug,
77-
Timeout: o.config.Timeout,
78-
ResponseBufferSize: int(o.config.BufferSize),
79-
})
80-
81-
deathCount := 0
82-
83-
atomic.AddInt64(&o.activeWorkers, 1)
84-
85-
for {
86-
select {
87-
case msg := <-o.queue:
88-
o.sendRequest(client, msg)
89-
deathCount = 0
90-
case <-time.After(time.Millisecond * 100):
91-
// When dynamic scaling enabled workers die after 2s of inactivity
92-
if o.config.Workers == 0 {
93-
deathCount++
94-
} else {
95-
continue
96-
}
97-
98-
if deathCount > 20 {
99-
workersCount := atomic.LoadInt64(&o.activeWorkers)
100-
101-
// At least 1 startWorker should be alive
102-
if workersCount != 1 {
103-
atomic.AddInt64(&o.activeWorkers, -1)
104-
return
105-
}
106-
}
107-
}
108-
}
109-
}
110-
111-
// PluginWrite writes a message tothis plugin
36+
// PluginWrite writes a message to this plugin
11237
func (o *BinaryOutput) PluginWrite(msg *Message) (n int, err error) {
113-
if !isRequestPayload(msg.Meta) {
114-
return len(msg.Data), nil
115-
}
116-
117-
o.queue <- msg
118-
119-
if o.config.Workers == 0 {
120-
workersCount := atomic.LoadInt64(&o.activeWorkers)
121-
122-
if len(o.queue) > int(workersCount) {
123-
o.needWorker <- len(o.queue)
124-
}
125-
}
126-
127-
return len(msg.Data) + len(msg.Meta), nil
38+
return 0, errors.New("binary output is only available in PRO version")
12839
}
12940

13041
// PluginRead reads a message from this plugin
13142
func (o *BinaryOutput) PluginRead() (*Message, error) {
132-
var resp response
133-
var msg Message
134-
select {
135-
case <-o.quit:
136-
return nil, ErrorStopped
137-
case resp = <-o.responses:
138-
}
139-
msg.Data = resp.payload
140-
msg.Meta = payloadHeader(ReplayedResponsePayload, resp.uuid, resp.startedAt, resp.roundTripTime)
141-
142-
return &msg, nil
143-
}
144-
145-
func (o *BinaryOutput) sendRequest(client *TCPClient, msg *Message) {
146-
if !isRequestPayload(msg.Meta) {
147-
return
148-
}
149-
150-
uuid := payloadID(msg.Meta)
151-
152-
start := time.Now()
153-
resp, err := client.Send(msg.Data)
154-
stop := time.Now()
155-
156-
if err != nil {
157-
Debug(1, "Request error:", err)
158-
}
159-
160-
if o.config.TrackResponses {
161-
o.responses <- response{resp, uuid, start.UnixNano(), stop.UnixNano() - start.UnixNano()}
162-
}
43+
return nil, errors.New("binary output is only available in PRO version")
16344
}
16445

16546
func (o *BinaryOutput) String() string {
166-
return "Binary output: " + o.address
47+
return "Binary output: " + o.address + " (PRO version required)"
16748
}
16849

16950
// Close closes this plugin for reading
17051
func (o *BinaryOutput) Close() error {
171-
close(o.quit)
17252
return nil
17353
}

0 commit comments

Comments
 (0)