Skip to content

Commit

Permalink
ddtrace/tracer: add Datadog-Container-ID when information is available (
Browse files Browse the repository at this point in the history
#472)

This change adds the container ID as a transport header, when the
information is available and can be extracted as part of the
/proc/self/cgroup file.
  • Loading branch information
gbbr authored Jul 18, 2019
1 parent 6ad7549 commit 71b316f
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
32 changes: 32 additions & 0 deletions ddtrace/tracer/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
package tracer

import (
"bufio"
"fmt"
"io"
"net"
"net/http"
"os"
"regexp"
"runtime"
"strconv"
"strings"
Expand Down Expand Up @@ -90,6 +92,13 @@ func newHTTPTransport(addr string, roundTripper http.RoundTripper) *httpTranspor
"Datadog-Meta-Tracer-Version": version.Tag,
"Content-Type": "application/msgpack",
}
f, err := os.Open("/proc/self/cgroup")
if err == nil {
if id, ok := readContainerID(f); ok {
defaultHeaders["Datadog-Container-ID"] = id
}
f.Close()
}
return &httpTransport{
traceURL: fmt.Sprintf("http://%s/v0.4/traces", resolveAddr(addr)),
client: &http.Client{
Expand All @@ -100,6 +109,29 @@ func newHTTPTransport(addr string, roundTripper http.RoundTripper) *httpTranspor
}
}

var (
// expLine matches a line in the /proc/self/cgroup file. It has a submatch for the last element (path), which contains the container ID.
expLine = regexp.MustCompile(`^\d+:[^:]*:(.+)$`)
// expContainerID matches contained IDs and sources. Source: https://github.com/Qard/container-info/blob/master/index.js
expContainerID = regexp.MustCompile(`([0-9a-f]{8}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{12}|[0-9a-f]{64})(?:.scope)?$`)
)

// readContainerID finds the first container ID reading from r and returns it.
func readContainerID(r io.Reader) (id string, ok bool) {
scn := bufio.NewScanner(r)
for scn.Scan() {
path := expLine.FindStringSubmatch(scn.Text())
if len(path) != 2 {
// invalid entry, continue
continue
}
if id := expContainerID.FindString(path[1]); id != "" {
return id, true
}
}
return "", false
}

func (t *httpTransport) send(p *payload) (body io.ReadCloser, err error) {
// prepare the client and send the payload
req, err := http.NewRequest("POST", t.traceURL, p)
Expand Down
29 changes: 29 additions & 0 deletions ddtrace/tracer/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,35 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}

func TestReadContainerID(t *testing.T) {
for in, out := range map[string]string{
`other_line
10:hugetlb:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa
9:cpuset:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa
8:pids:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa
7:freezer:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa
6:cpu,cpuacct:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa
5:perf_event:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa
4:blkio:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa
3:devices:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa
2:net_cls,net_prio:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa`: "8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa",
"10:hugetlb:/kubepods/burstable/podfd52ef25-a87d-11e9-9423-0800271a638e/8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa": "8c046cb0b72cd4c99f51b5591cd5b095967f58ee003710a45280c28ee1a9c7fa",
"10:hugetlb:/kubepods": "",
} {
id, ok := readContainerID(strings.NewReader(in))
if id != out {
t.Fatalf("%q -> %q", in, out)
}
if out == "" {
if ok {
t.Fatalf("%q: got ok=true", in)
}
} else if !ok {
t.Fatalf("%q: got ok=false", in)
}
}
}

// getTestSpan returns a Span with different fields set
func getTestSpan() *span {
return &span{
Expand Down

0 comments on commit 71b316f

Please sign in to comment.