forked from marcus-crane/spanner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
81 lines (73 loc) · 2.46 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/vmihailenco/msgpack/v5"
)
// Span represents information about a single HTTP request.
// It reflects a single unit of work and metadata about that
// work unit such as how long it took, whether it succeeded
// and other useful metrics and tags to report.
type Span struct {
Service string `msgpack:"service"`
Name string `msgpack:"name"`
Resource string `msgpack:"resource"`
TraceID uint64 `msgpack:"trace_id"`
SpanID uint64 `msgpack:"span_id"`
ParentID uint64 `msgpack:"parent_id"`
Start int64 `msgpack:"start"`
Duration int64 `msgpack:"duration"`
Error int32 `msgpack:"error"`
Meta map[string]string `msgpack:"meta"`
Metrics map[string]float64 `msgpack:"metrics"`
Type string `msgpack:"types"`
}
// Trace is a group of spans that share the same trace ID.
// They may reflect multiple units of work within a single
// service or units of work across multiple services
type Trace []Span
// Traces are what we receive from the APM agents. Each
// APM agent will bundle up multiple traces together
// and send them off to an instance of the Datadog agent.
// This happens around every 10 seconds or so.
type Traces []Trace
func main() {
verbose := flag.Bool("verbose", false, "verbose mode outputs all information available for each span")
nameFilter := flag.String("name", "", "filter spans by name (must include the given string value). Not usable with verbose mode.")
flag.Parse()
traceHandler := func(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
if len(body) == 1 {
log.Printf("Received initial connection from %s on %s", r.UserAgent(), r.RemoteAddr)
return
}
var traces Traces
err = msgpack.Unmarshal(body, &traces)
if err != nil {
log.Println("Failed to unpack traces")
}
if *verbose {
log.Println(spew.Sdump(traces))
} else {
for _, trace := range traces {
for _, span := range trace {
if *nameFilter == "" || strings.Contains(span.Name, *nameFilter) {
log.Printf("%s\n\033[34m%s\033[0m\n", span.Name, span.Resource)
}
}
}
}
fmt.Fprintf(w, "OK")
}
http.HandleFunc("/", traceHandler)
log.Print("Spanner is listening on 127.0.0.1:8126")
log.Fatal(http.ListenAndServe(":8126", nil))
}