Skip to content

Commit 9ec502d

Browse files
Add json output format (#168)
* Support output format as json * Add -output.format flag to caller * Add -input.format flag to trex * Use travis-pro for coverage target * Build generate-schemas in Dockerfile * Rename HopAnnotation2 type and schema * Make file extension configurable * Set extension based on output format * Generalize ptr and waitprobe options for traceroutes * Update flags for ptr and waitprobe
1 parent fd359ff commit 9ec502d

File tree

21 files changed

+448
-407
lines changed

21 files changed

+448
-407
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ script:
1818
after_success:
1919
# Coveralls
2020
# Upload coverage information for unit tests.
21-
- $GOPATH/bin/goveralls -coverprofile=_coverage.cov -service=travis-ci
21+
- $GOPATH/bin/goveralls -coverprofile=_coverage.cov -service=travis-pro

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ RUN go get -v . && \
99
go install -v -ldflags "-X github.com/m-lab/go/prometheusx.GitShortCommit=$(git log -1 --format=%h)" . && \
1010
chmod -R a+rx /go/bin/traceroute-caller
1111

12+
RUN go install -v ./cmd/generate-schemas && \
13+
chmod -R a+rx /go/bin/generate-schemas
14+
1215
# Build and install the tools that are called by traceroute-caller.
1316
FROM ubuntu:22.04 as build_tracers
1417
RUN apt-get update && \
@@ -38,6 +41,7 @@ RUN mkdir -p /var/empty && \
3841
chmod 555 /var/empty
3942
# Copy the statically-linked traceroute-caller binary.
4043
COPY --from=build_caller /go/bin/traceroute-caller /
44+
COPY --from=build_caller /go/bin/generate-schemas /
4145
# Copy the dynamically-linked scamper binary and its associated libraries.
4246
COPY --from=build_tracers /scamper /usr/local
4347

caller.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,12 @@ var (
3333
Options: []string{"mda", "regular"},
3434
Value: "mda",
3535
}
36-
scamperTracelbPTR = flag.Bool("scamper.tracelb-ptr", true, "mda traceroute option: Look up DNS pointer records for IP addresses.")
37-
scamperTracelbW = flag.Int("scamper.tracelb-W", 25, "mda traceroute option: Wait time in 1/100ths of seconds between probes (min 15, max 200).")
36+
outputFormat = flagx.Enum{
37+
Options: []string{"jsonl", "json"},
38+
Value: "jsonl",
39+
}
40+
scamperTracePTR = flag.Bool("scamper.ptr", true, "traceroute option: Look up DNS pointer records for IP addresses.")
41+
scamperTraceWait = flag.Int("scamper.waitprobe", 25, "traceroute option: Wait time in 1/100ths of seconds between probes (min 15, max 200).")
3842
tracerouteOutput = flag.String("traceroute-output", "/var/spool/scamper1", "The path to store traceroute output.")
3943
hopAnnotationOutput = flag.String("hopannotation-output", "/var/spool/hopannotation1", "The path to store hop annotation output.")
4044
// Keeping IP cache flags capitalized for backward compatibility.
@@ -52,6 +56,7 @@ var (
5256

5357
func init() {
5458
flag.Var(&scamperTraceType, "scamper.trace-type", "Specify the type of traceroute (mda or regular) to run.")
59+
flag.Var(&outputFormat, "output.format", "Specify the output format of traces (jsonl or json).")
5560
}
5661

5762
func main() {
@@ -80,14 +85,13 @@ func main() {
8085

8186
// 1. The traceroute tool (scamper).
8287
scamperCfg := tracer.ScamperConfig{
83-
Binary: *scamperBin,
84-
OutputPath: *tracerouteOutput,
85-
Timeout: *scamperTimeout,
86-
TraceType: scamperTraceType.Value,
87-
}
88-
if scamperCfg.TraceType == "mda" {
89-
scamperCfg.TracelbPTR = *scamperTracelbPTR
90-
scamperCfg.TracelbWaitProbe = *scamperTracelbW
88+
Binary: *scamperBin,
89+
OutputPath: *tracerouteOutput,
90+
Timeout: *scamperTimeout,
91+
TracePTR: *scamperTracePTR,
92+
TraceWaitProbe: *scamperTraceWait,
93+
TraceType: scamperTraceType.Value,
94+
Extension: outputFormat.Value,
9195
}
9296
scamper, err := tracer.NewScamper(scamperCfg)
9397
if err != nil {
@@ -103,7 +107,7 @@ func main() {
103107
ScanPeriod: *ipcScanPeriod,
104108
}
105109
// 3. The traceroute parser.
106-
newParser, err := parser.New(scamperTraceType.Value)
110+
newParser, err := parser.New(scamperTraceType.Value, outputFormat.Value)
107111
if err != nil {
108112
logFatal(err)
109113
}

caller_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func TestMainFunc(t *testing.T) {
7373
for _, arg := range []strFlag{
7474
{"-scamper.bin", "/bin/echo"},
7575
{"-scamper.trace-type", "mda"},
76-
{"-scamper.tracelb-W", "15"},
76+
{"-scamper.waitprobe", "15"},
7777
{"-prometheusx.listen-address", ":0"},
7878
{"-tcpinfo.eventsocket", sockPath},
7979
{"-traceroute-output", testDir},
@@ -107,7 +107,7 @@ func TestMainEventSocket(t *testing.T) {
107107
for _, arg := range []strFlag{
108108
{"-scamper.bin", "/bin/echo"},
109109
{"-scamper.trace-type", "mda"},
110-
{"-scamper.tracelb-W", "15"},
110+
{"-scamper.waitprobe", "15"},
111111
{"-prometheusx.listen-address", ":0"},
112112
{"-tcpinfo.eventsocket", ""}, // should cause failure
113113
{"-traceroute-output", testDir},
@@ -133,7 +133,7 @@ func TestMainScamper(t *testing.T) {
133133
ctx, cancel = context.WithCancel(context.Background())
134134
for _, arg := range []strFlag{
135135
{"-scamper.bin", "/bin/echo"},
136-
{"-scamper.tracelb-W", "10"}, // should cause failure (15 <= valid <= 200)
136+
{"-scamper.waitprobe", "10"}, // should cause failure (15 <= valid <= 200)
137137
{"-prometheusx.listen-address", ":0"},
138138
{"-tcpinfo.eventsocket", sockPath},
139139
{"-traceroute-output", testDir},
@@ -160,7 +160,7 @@ func TestMainNewHandler(t *testing.T) {
160160
for _, arg := range []strFlag{
161161
{"-scamper.bin", "/bin/echo"},
162162
{"-scamper.trace-type", "mda"},
163-
{"-scamper.tracelb-W", "15"},
163+
{"-scamper.waitprobe", "15"},
164164
{"-prometheusx.listen-address", ":0"},
165165
{"-tcpinfo.eventsocket", sockPath},
166166
{"-traceroute-output", testDir},

cmd/generate-schemas/main.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"os"
6+
7+
"github.com/m-lab/go/cloud/bqx"
8+
"github.com/m-lab/go/rtx"
9+
"github.com/m-lab/traceroute-caller/hopannotation"
10+
"github.com/m-lab/traceroute-caller/parser"
11+
12+
"cloud.google.com/go/bigquery"
13+
)
14+
15+
var (
16+
scamper2schema string
17+
hop2schema string
18+
)
19+
20+
func init() {
21+
flag.StringVar(&scamper2schema, "scamper2", "/var/spool/datatypes/scamper2.json", "filename to write scamper2 schema")
22+
flag.StringVar(&hop2schema, "hopannotation2", "/var/spool/datatypes/hopannotation2.json", "filename to write hopannotation2 schema")
23+
}
24+
25+
func main() {
26+
flag.Parse()
27+
// TODO(soltesz): parser.Schema1 does not natively support BigQuery schema inference.
28+
29+
// Generate and save hopannotation2 schema for autoloading.
30+
hop2 := hopannotation.HopAnnotation2{}
31+
sch, err := bigquery.InferSchema(hop2)
32+
rtx.Must(err, "failed to generate hopannotation2 schema")
33+
sch = bqx.RemoveRequired(sch)
34+
b, err := sch.ToJSONFields()
35+
rtx.Must(err, "failed to marshal schema")
36+
os.WriteFile(hop2schema, b, 0o644)
37+
38+
// Generate and save scamper2 schema for autoloading.
39+
row2 := parser.Scamper2{}
40+
sch, err = bigquery.InferSchema(row2)
41+
rtx.Must(err, "failed to generate scamper2 schema")
42+
sch = bqx.RemoveRequired(sch)
43+
b, err = sch.ToJSONFields()
44+
rtx.Must(err, "failed to marshal schema")
45+
os.WriteFile(scamper2schema, b, 0o644)
46+
}

cmd/trex/main.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@ import (
99
"path/filepath"
1010
"sort"
1111

12+
"github.com/m-lab/go/flagx"
1213
"github.com/m-lab/traceroute-caller/parser"
1314
)
1415

1516
var (
16-
prComplete = flag.Bool("c", false, "print flow IDs and file names of traceroutes that completed (\"--\" for incomplete traceroutes)")
17-
duration = flag.Uint("d", 0, "print times and file names of traceroutes that took more than the specified duration")
18-
verbose = flag.Bool("v", false, "enable verbose mode (mostly for debugging)")
19-
flagSet = make(map[string]bool)
17+
prComplete = flag.Bool("c", false, "print flow IDs and file names of traceroutes that completed (\"--\" for incomplete traceroutes)")
18+
duration = flag.Uint("d", 0, "print times and file names of traceroutes that took more than the specified duration")
19+
verbose = flag.Bool("v", false, "enable verbose mode (mostly for debugging)")
20+
flagSet = make(map[string]bool)
21+
inputFormat = flagx.Enum{
22+
Options: []string{"jsonl", "json"},
23+
Value: "jsonl",
24+
}
2025

2126
// Statistics printed before exiting.
2227
nFilesFound uint32 // files found
@@ -31,6 +36,10 @@ var (
3136
totDuration uint64 // total duration of all traceroutes
3237
)
3338

39+
func init() {
40+
flag.Var(&inputFormat, "input.format", "Specify the input format of traces (jsonl or json).")
41+
}
42+
3443
// Hop defines a hop.
3544
type Hop struct {
3645
addr string // hop's IP address in string format
@@ -145,7 +154,7 @@ func parseFile(fileName string) *parser.Scamper1 {
145154
nReadErrors++
146155
return nil
147156
}
148-
mdaParser, err := parser.New("mda")
157+
mdaParser, err := parser.New("mda", inputFormat.Value)
149158
if err != nil {
150159
fmt.Fprintf(os.Stderr, "%v\n", err)
151160
return nil

docker-compose.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ services:
7272
- -scamper.trace-type=mda
7373
- -traceroute-output=/local/scamper1
7474
- -scamper.timeout=30m
75-
- -scamper.tracelb-W=15
76-
- -scamper.tracelb-ptr=true
75+
- -scamper.waitprobe=15
76+
- -scamper.ptr=true
7777

7878
trc-scamper2:
7979
profiles:
@@ -101,3 +101,6 @@ services:
101101
- -scamper.trace-type=regular
102102
- -traceroute-output=/local/scamper2
103103
- -scamper.timeout=10m
104+
- -scamper.waitprobe=15
105+
- -scamper.ptr=true
106+
- -output.format=json

go.mod

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,64 @@
11
module github.com/m-lab/traceroute-caller
22

3-
go 1.21
3+
go 1.20
44

55
require (
6+
cloud.google.com/go/bigquery v1.49.0
67
github.com/go-test/deep v1.0.7
7-
github.com/m-lab/go v0.1.66
8+
github.com/m-lab/go v0.1.75
89
github.com/m-lab/tcp-info v1.5.3
910
github.com/m-lab/uuid-annotator v0.4.7
1011
github.com/prometheus/client_golang v1.12.2
1112
)
1213

1314
require (
14-
cloud.google.com/go v0.102.0 // indirect
15-
cloud.google.com/go/compute v1.6.1 // indirect
16-
cloud.google.com/go/iam v0.3.0 // indirect
17-
cloud.google.com/go/storage v1.22.1 // indirect
15+
cloud.google.com/go v0.110.0 // indirect
16+
cloud.google.com/go/compute v1.18.0 // indirect
17+
cloud.google.com/go/compute/metadata v0.2.3 // indirect
18+
cloud.google.com/go/iam v0.12.0 // indirect
19+
cloud.google.com/go/storage v1.29.0 // indirect
20+
github.com/andybalholm/brotli v1.0.4 // indirect
21+
github.com/apache/arrow/go/v11 v11.0.0 // indirect
22+
github.com/apache/thrift v0.16.0 // indirect
1823
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
1924
github.com/beorn7/perks v1.0.1 // indirect
20-
github.com/cespare/xxhash/v2 v2.1.2 // indirect
25+
github.com/cespare/xxhash/v2 v2.2.0 // indirect
26+
github.com/goccy/go-json v0.9.11 // indirect
2127
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
2228
github.com/golang/protobuf v1.5.2 // indirect
23-
github.com/google/go-cmp v0.5.8 // indirect
29+
github.com/golang/snappy v0.0.4 // indirect
30+
github.com/google/flatbuffers v2.0.8+incompatible // indirect
31+
github.com/google/go-cmp v0.5.9 // indirect
2432
github.com/google/uuid v1.3.0 // indirect
25-
github.com/googleapis/gax-go/v2 v2.4.0 // indirect
26-
github.com/googleapis/go-type-adapters v1.0.0 // indirect
33+
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
34+
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
2735
github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720 // indirect
36+
github.com/klauspost/asmfmt v1.3.2 // indirect
37+
github.com/klauspost/compress v1.15.9 // indirect
38+
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
2839
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
40+
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect
41+
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 // indirect
2942
github.com/oschwald/geoip2-golang v1.7.0 // indirect
3043
github.com/oschwald/maxminddb-golang v1.9.0 // indirect
44+
github.com/pierrec/lz4/v4 v4.1.15 // indirect
3145
github.com/prometheus/client_model v0.2.0 // indirect
3246
github.com/prometheus/common v0.34.0 // indirect
3347
github.com/prometheus/procfs v0.7.3 // indirect
34-
go.opencensus.io v0.23.0 // indirect
48+
github.com/zeebo/xxh3 v1.0.2 // indirect
49+
go.opencensus.io v0.24.0 // indirect
50+
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
3551
golang.org/x/net v0.7.0 // indirect
36-
golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 // indirect
52+
golang.org/x/oauth2 v0.5.0 // indirect
53+
golang.org/x/sync v0.1.0 // indirect
3754
golang.org/x/sys v0.5.0 // indirect
3855
golang.org/x/text v0.7.0 // indirect
39-
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
40-
google.golang.org/api v0.81.0 // indirect
56+
golang.org/x/tools v0.1.12 // indirect
57+
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
58+
google.golang.org/api v0.111.0 // indirect
4159
google.golang.org/appengine v1.6.7 // indirect
42-
google.golang.org/genproto v0.0.0-20220525015930-6ca3db687a9d // indirect
43-
google.golang.org/grpc v1.46.2 // indirect
44-
google.golang.org/protobuf v1.28.0 // indirect
60+
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
61+
google.golang.org/grpc v1.53.0 // indirect
62+
google.golang.org/protobuf v1.28.1 // indirect
63+
gopkg.in/yaml.v2 v2.4.0 // indirect
4564
)

0 commit comments

Comments
 (0)