Added integration support for DataDog APM Tracing
This commit is contained in:
parent
ba8c9295ac
commit
3192307d59
61 changed files with 9999 additions and 5 deletions
120
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go
generated
vendored
Normal file
120
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
package tracer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var tracerVersion = "v1.0"
|
||||
|
||||
const (
|
||||
defaultHostname = "localhost"
|
||||
defaultPort = "8126"
|
||||
defaultAddress = defaultHostname + ":" + defaultPort
|
||||
defaultHTTPTimeout = time.Second // defines the current timeout before giving up with the send process
|
||||
traceCountHeader = "X-Datadog-Trace-Count" // header containing the number of traces in the payload
|
||||
)
|
||||
|
||||
// Transport is an interface for span submission to the agent.
|
||||
type transport interface {
|
||||
send(p *payload) error
|
||||
}
|
||||
|
||||
// newTransport returns a new Transport implementation that sends traces to a
|
||||
// trace agent running on the given hostname and port. If the zero values for
|
||||
// hostname and port are provided, the default values will be used ("localhost"
|
||||
// for hostname, and "8126" for port).
|
||||
//
|
||||
// In general, using this method is only necessary if you have a trace agent
|
||||
// running on a non-default port or if it's located on another machine.
|
||||
func newTransport(addr string) transport {
|
||||
return newHTTPTransport(addr)
|
||||
}
|
||||
|
||||
// newDefaultTransport return a default transport for this tracing client
|
||||
func newDefaultTransport() transport {
|
||||
return newHTTPTransport(defaultAddress)
|
||||
}
|
||||
|
||||
type httpTransport struct {
|
||||
traceURL string // the delivery URL for traces
|
||||
client *http.Client // the HTTP client used in the POST
|
||||
headers map[string]string // the Transport headers
|
||||
}
|
||||
|
||||
// newHTTPTransport returns an httpTransport for the given endpoint
|
||||
func newHTTPTransport(addr string) *httpTransport {
|
||||
// initialize the default EncoderPool with Encoder headers
|
||||
defaultHeaders := map[string]string{
|
||||
"Datadog-Meta-Lang": "go",
|
||||
"Datadog-Meta-Lang-Version": strings.TrimPrefix(runtime.Version(), "go"),
|
||||
"Datadog-Meta-Lang-Interpreter": runtime.Compiler + "-" + runtime.GOARCH + "-" + runtime.GOOS,
|
||||
"Datadog-Meta-Tracer-Version": tracerVersion,
|
||||
"Content-Type": "application/msgpack",
|
||||
}
|
||||
host, port, _ := net.SplitHostPort(addr)
|
||||
if host == "" {
|
||||
host = defaultHostname
|
||||
}
|
||||
if port == "" {
|
||||
port = defaultPort
|
||||
}
|
||||
addr = fmt.Sprintf("%s:%s", host, port)
|
||||
return &httpTransport{
|
||||
traceURL: fmt.Sprintf("http://%s/v0.3/traces", addr),
|
||||
client: &http.Client{
|
||||
// We copy the transport to avoid using the default one, as it might be
|
||||
// augmented with tracing and we don't want these calls to be recorded.
|
||||
// See https://golang.org/pkg/net/http/#DefaultTransport .
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
},
|
||||
Timeout: defaultHTTPTimeout,
|
||||
},
|
||||
headers: defaultHeaders,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *httpTransport) send(p *payload) error {
|
||||
// prepare the client and send the payload
|
||||
req, err := http.NewRequest("POST", t.traceURL, p)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot create http request: %v", err)
|
||||
}
|
||||
for header, value := range t.headers {
|
||||
req.Header.Set(header, value)
|
||||
}
|
||||
req.Header.Set(traceCountHeader, strconv.Itoa(p.itemCount()))
|
||||
req.Header.Set("Content-Length", strconv.Itoa(p.size()))
|
||||
response, err := t.client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
if code := response.StatusCode; code >= 400 {
|
||||
// error, check the body for context information and
|
||||
// return a nice error.
|
||||
msg := make([]byte, 1000)
|
||||
n, _ := response.Body.Read(msg)
|
||||
txt := http.StatusText(code)
|
||||
if n > 0 {
|
||||
return fmt.Errorf("%s (Status: %s)", msg[:n], txt)
|
||||
}
|
||||
return fmt.Errorf("%s", txt)
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue