contrib/net/http
Those integrations are enabled by having the
following import
in the project’s orchestrion.tool.go
file:
import (
_ "github.com/DataDog/orchestrion"
_ "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http" // integration
//...
)
gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http
HTTP stack implementation.
Transport.DD__tracer_internal
Definition of
http.Transport
Transport.DD__tracer_internal=true
All of
- Struct literal
http.Transport
- Pointer or Value
- One of
- Import path
gopkg.in/
DataDog/ dd-trace-go.v1/ ddtrace/ tracer - Import path
gopkg.in/
DataDog/ dd-trace-go.v1/ profiler
Replace the expression using the template:
{{- .AST.Type -}}{
DD__tracer_internal: true,
{{ range .AST.Elts }}{{ . }},
{{ end }}
}
Transport.RoundTrip
Function body
- Function declaration
- Function name
RoundTrip
- Is method of
*http.Transport
Introduce new declarations:
// Using the following synthetic imports:
import (
context "context"
ddtrace "gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
os "os"
)
//go:linkname __dd_appsec_RASPEnabled gopkg.in/DataDog/dd-trace-go.v1/internal/appsec.RASPEnabled
func __dd_appsec_RASPEnabled() bool
//go:linkname __dd_httpsec_ProtectRoundTrip gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec.ProtectRoundTrip
func __dd_httpsec_ProtectRoundTrip(context.Context, string) error
//go:linkname __dd_tracer_SpanType gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.SpanType
func __dd_tracer_SpanType(string) ddtrace.StartSpanOption
//go:linkname __dd_tracer_ResourceName gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.ResourceName
func __dd_tracer_ResourceName(string) ddtrace.StartSpanOption
//go:linkname __dd_tracer_Tag gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.Tag
func __dd_tracer_Tag(string, any) ddtrace.StartSpanOption
//go:linkname __dd_tracer_StartSpanFromContext gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.StartSpanFromContext
func __dd_tracer_StartSpanFromContext(context.Context, string, ...ddtrace.StartSpanOption) (ddtrace.Span, context.Context)
//go:linkname __dd_tracer_WithError gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.WithError
func __dd_tracer_WithError(error) ddtrace.FinishOption
//go:linkname __dd_tracer_Inject gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.Inject
func __dd_tracer_Inject(ddtrace.SpanContext, any) error
//go:linkname __dd_httptrace_GetErrorCodesFromInput gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/httptrace.GetErrorCodesFromInput
func __dd_httptrace_GetErrorCodesFromInput(string) func(int) bool
//go:linkname __dd_httptrace_UrlFromRequest gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/httptrace.UrlFromRequest
func __dd_httptrace_UrlFromRequest(*Request, bool) string
//go:linkname __dd_internal_BoolEnv gopkg.in/DataDog/dd-trace-go.v1/internal.BoolEnv
func __dd_internal_BoolEnv(string, bool) bool
type __dd_tracer_HTTPHeadersCarrier Header
func (c __dd_tracer_HTTPHeadersCarrier) Set(key, val string) {
Header(c).Set(key, val)
}
var __dd_isError = func(statusCode int) bool {
// Treat HTTP 4XX as errors
return statusCode >= 400 && statusCode < 500
}
var __dd_queryStringEnabled = __dd_internal_BoolEnv("DD_TRACE_HTTP_CLIENT_TAG_QUERY_STRING", true)
func init() {
v := os.Getenv("DD_TRACE_HTTP_CLIENT_ERROR_STATUSES")
if fn := __dd_httptrace_GetErrorCodesFromInput(v); fn != nil {
__dd_isError = fn
}
}
Record link-time dependencies on:
Prepend statements produced by the following template:
// Using the following synthetic imports:
import (
ddtrace "gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
events "gopkg.in/DataDog/dd-trace-go.v1/appsec/events"
ext "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
fmt "fmt"
globalconfig "gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig"
math "math"
namingschema "gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema"
os "os"
strconv "strconv"
)
{{- /* Largely copied from https://github.com/DataDog/dd-trace-go/blob/v1.65.0-rc.2/contrib/net/http/roundtripper.go#L28-L104 */ -}}
{{- $t := .Function.Receiver -}}
{{- $req := .Function.Argument 0 -}}
{{- $res := .Function.Result 0 -}}
{{- $err := .Function.Result 1 -}}
if !{{ $t }}.DD__tracer_internal {
resourceName := fmt.Sprintf("%s %s", {{ $req }}.Method, {{ $req }}.URL.Path)
spanName := namingschema.OpName(namingschema.HTTPClient)
// Copy the URL so we don't modify the outgoing request
url := *{{ $req }}.URL
url.User = nil // Don't include userinfo in the http.url tag
opts := []ddtrace.StartSpanOption{
__dd_tracer_SpanType(ext.SpanTypeHTTP),
__dd_tracer_ResourceName(resourceName),
__dd_tracer_Tag(ext.HTTPMethod, {{ $req }}.Method),
__dd_tracer_Tag(ext.HTTPURL, __dd_httptrace_UrlFromRequest({{ $req }}, __dd_queryStringEnabled)),
__dd_tracer_Tag(ext.Component, "net/http"),
__dd_tracer_Tag(ext.SpanKind, ext.SpanKindClient),
__dd_tracer_Tag(ext.NetworkDestinationName, url.Hostname()),
}
if analyticsRate := globalconfig.AnalyticsRate(); !math.IsNaN(analyticsRate) {
opts = append(opts, __dd_tracer_Tag(ext.EventSampleRate, analyticsRate))
}
if port, err := strconv.Atoi(url.Port()); err == nil {
opts = append(opts, __dd_tracer_Tag(ext.NetworkDestinationPort, port))
}
span, ctx := __dd_tracer_StartSpanFromContext({{ $req }}.Context(), spanName, opts...)
{{ $req }} = {{ $req }}.Clone(ctx)
defer func() {
if !events.IsSecurityError({{ $err }}) {
span.Finish(__dd_tracer_WithError({{ $err }}))
} else {
span.Finish()
}
}()
if {{ $err }} = __dd_tracer_Inject(span.Context(), __dd_tracer_HTTPHeadersCarrier({{ $req }}.Header)); {{ $err }} != nil {
fmt.Fprintf(os.Stderr, "contrib/net/http.Roundtrip: failed to inject http headers: %v\n", {{ $err }})
}
if __dd_appsec_RASPEnabled() {
if err := __dd_httpsec_ProtectRoundTrip(ctx, {{ $req }}.URL.String()); err != nil {
return nil, err
}
}
defer func() {
if {{ $err }} != nil {
span.SetTag("http.errors", {{ $err }}.Error())
span.SetTag(ext.Error, {{ $err }})
} else {
span.SetTag(ext.HTTPCode, strconv.Itoa({{ $res }}.StatusCode))
if __dd_isError({{ $res }}.StatusCode) {
span.SetTag("http.errors", {{ $res }}.Status)
span.SetTag(ext.Error, fmt.Errorf("%d: %s", {{ $res }}.StatusCode, StatusText({{ $res }}.StatusCode)))
}
}
}()
}
Get|Head|Post|PostForm
All of
- Not
- Import path
net/
http
- One of
- Call to
http.Get
- Call to
http.Head
- Call to
http.Post
- Call to
http.PostForm
Replace the expression using the template:
// Using the following synthetic imports:
import (
client "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http/client"
)
{{- $ctx := .Function.ArgumentOfType "context.Context" -}}
{{- $req := .Function.ArgumentOfType "*net/http.Request" }}
{{- if $ctx -}}
client.{{ .AST.Fun.Name }}(
{{ $ctx }},
{{ range .AST.Args }}{{ . }},
{{ end }}
)
{{- else if $req -}}
client.{{ .AST.Fun.Name }}(
{{ $req }}.Context(),
{{ range .AST.Args }}{{ . }},
{{ end }}
)
{{- else -}}
{{ . }}
{{- end -}}
Server.Serve
Function body
- Function declaration
- Is method of
*http.Server
- Function name
Serve
Introduce new declarations:
//go:linkname __dd_contrib_net_http_internal_orchestrion_WrapHandler gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http/internal/orchestrion.WrapHandler
func __dd_contrib_net_http_internal_orchestrion_WrapHandler(Handler) Handler
Record link-time dependencies on:
Prepend statements produced by the following template:
{{- $srv := .Function.Receiver -}}
if {{ $srv }}.Handler == nil {
{{ $srv }}.Handler = __dd_contrib_net_http_internal_orchestrion_WrapHandler(DefaultServeMux)
} else {
{{ $srv }}.Handler = __dd_contrib_net_http_internal_orchestrion_WrapHandler({{ $srv }}.Handler)
}
gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http.Client
HTTP client implementation.
Transport.DD__tracer_internal
Definition of
http.Transport
Transport.DD__tracer_internal=true
All of
- Struct literal
http.Transport
- Pointer or Value
- One of
- Import path
gopkg.in/
DataDog/ dd-trace-go.v1/ ddtrace/ tracer - Import path
gopkg.in/
DataDog/ dd-trace-go.v1/ profiler
Replace the expression using the template:
{{- .AST.Type -}}{
DD__tracer_internal: true,
{{ range .AST.Elts }}{{ . }},
{{ end }}
}
Transport.RoundTrip
Function body
- Function declaration
- Function name
RoundTrip
- Is method of
*http.Transport
Introduce new declarations:
// Using the following synthetic imports:
import (
context "context"
ddtrace "gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
os "os"
)
//go:linkname __dd_appsec_RASPEnabled gopkg.in/DataDog/dd-trace-go.v1/internal/appsec.RASPEnabled
func __dd_appsec_RASPEnabled() bool
//go:linkname __dd_httpsec_ProtectRoundTrip gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec.ProtectRoundTrip
func __dd_httpsec_ProtectRoundTrip(context.Context, string) error
//go:linkname __dd_tracer_SpanType gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.SpanType
func __dd_tracer_SpanType(string) ddtrace.StartSpanOption
//go:linkname __dd_tracer_ResourceName gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.ResourceName
func __dd_tracer_ResourceName(string) ddtrace.StartSpanOption
//go:linkname __dd_tracer_Tag gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.Tag
func __dd_tracer_Tag(string, any) ddtrace.StartSpanOption
//go:linkname __dd_tracer_StartSpanFromContext gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.StartSpanFromContext
func __dd_tracer_StartSpanFromContext(context.Context, string, ...ddtrace.StartSpanOption) (ddtrace.Span, context.Context)
//go:linkname __dd_tracer_WithError gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.WithError
func __dd_tracer_WithError(error) ddtrace.FinishOption
//go:linkname __dd_tracer_Inject gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer.Inject
func __dd_tracer_Inject(ddtrace.SpanContext, any) error
//go:linkname __dd_httptrace_GetErrorCodesFromInput gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/httptrace.GetErrorCodesFromInput
func __dd_httptrace_GetErrorCodesFromInput(string) func(int) bool
//go:linkname __dd_httptrace_UrlFromRequest gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/httptrace.UrlFromRequest
func __dd_httptrace_UrlFromRequest(*Request, bool) string
//go:linkname __dd_internal_BoolEnv gopkg.in/DataDog/dd-trace-go.v1/internal.BoolEnv
func __dd_internal_BoolEnv(string, bool) bool
type __dd_tracer_HTTPHeadersCarrier Header
func (c __dd_tracer_HTTPHeadersCarrier) Set(key, val string) {
Header(c).Set(key, val)
}
var __dd_isError = func(statusCode int) bool {
// Treat HTTP 4XX as errors
return statusCode >= 400 && statusCode < 500
}
var __dd_queryStringEnabled = __dd_internal_BoolEnv("DD_TRACE_HTTP_CLIENT_TAG_QUERY_STRING", true)
func init() {
v := os.Getenv("DD_TRACE_HTTP_CLIENT_ERROR_STATUSES")
if fn := __dd_httptrace_GetErrorCodesFromInput(v); fn != nil {
__dd_isError = fn
}
}
Record link-time dependencies on:
Prepend statements produced by the following template:
// Using the following synthetic imports:
import (
ddtrace "gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
events "gopkg.in/DataDog/dd-trace-go.v1/appsec/events"
ext "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
fmt "fmt"
globalconfig "gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig"
math "math"
namingschema "gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema"
os "os"
strconv "strconv"
)
{{- /* Largely copied from https://github.com/DataDog/dd-trace-go/blob/v1.65.0-rc.2/contrib/net/http/roundtripper.go#L28-L104 */ -}}
{{- $t := .Function.Receiver -}}
{{- $req := .Function.Argument 0 -}}
{{- $res := .Function.Result 0 -}}
{{- $err := .Function.Result 1 -}}
if !{{ $t }}.DD__tracer_internal {
resourceName := fmt.Sprintf("%s %s", {{ $req }}.Method, {{ $req }}.URL.Path)
spanName := namingschema.OpName(namingschema.HTTPClient)
// Copy the URL so we don't modify the outgoing request
url := *{{ $req }}.URL
url.User = nil // Don't include userinfo in the http.url tag
opts := []ddtrace.StartSpanOption{
__dd_tracer_SpanType(ext.SpanTypeHTTP),
__dd_tracer_ResourceName(resourceName),
__dd_tracer_Tag(ext.HTTPMethod, {{ $req }}.Method),
__dd_tracer_Tag(ext.HTTPURL, __dd_httptrace_UrlFromRequest({{ $req }}, __dd_queryStringEnabled)),
__dd_tracer_Tag(ext.Component, "net/http"),
__dd_tracer_Tag(ext.SpanKind, ext.SpanKindClient),
__dd_tracer_Tag(ext.NetworkDestinationName, url.Hostname()),
}
if analyticsRate := globalconfig.AnalyticsRate(); !math.IsNaN(analyticsRate) {
opts = append(opts, __dd_tracer_Tag(ext.EventSampleRate, analyticsRate))
}
if port, err := strconv.Atoi(url.Port()); err == nil {
opts = append(opts, __dd_tracer_Tag(ext.NetworkDestinationPort, port))
}
span, ctx := __dd_tracer_StartSpanFromContext({{ $req }}.Context(), spanName, opts...)
{{ $req }} = {{ $req }}.Clone(ctx)
defer func() {
if !events.IsSecurityError({{ $err }}) {
span.Finish(__dd_tracer_WithError({{ $err }}))
} else {
span.Finish()
}
}()
if {{ $err }} = __dd_tracer_Inject(span.Context(), __dd_tracer_HTTPHeadersCarrier({{ $req }}.Header)); {{ $err }} != nil {
fmt.Fprintf(os.Stderr, "contrib/net/http.Roundtrip: failed to inject http headers: %v\n", {{ $err }})
}
if __dd_appsec_RASPEnabled() {
if err := __dd_httpsec_ProtectRoundTrip(ctx, {{ $req }}.URL.String()); err != nil {
return nil, err
}
}
defer func() {
if {{ $err }} != nil {
span.SetTag("http.errors", {{ $err }}.Error())
span.SetTag(ext.Error, {{ $err }})
} else {
span.SetTag(ext.HTTPCode, strconv.Itoa({{ $res }}.StatusCode))
if __dd_isError({{ $res }}.StatusCode) {
span.SetTag("http.errors", {{ $res }}.Status)
span.SetTag(ext.Error, fmt.Errorf("%d: %s", {{ $res }}.StatusCode, StatusText({{ $res }}.StatusCode)))
}
}
}()
}
Get|Head|Post|PostForm
All of
- Not
- Import path
net/
http
- One of
- Call to
http.Get
- Call to
http.Head
- Call to
http.Post
- Call to
http.PostForm
Replace the expression using the template:
// Using the following synthetic imports:
import (
client "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http/client"
)
{{- $ctx := .Function.ArgumentOfType "context.Context" -}}
{{- $req := .Function.ArgumentOfType "*net/http.Request" }}
{{- if $ctx -}}
client.{{ .AST.Fun.Name }}(
{{ $ctx }},
{{ range .AST.Args }}{{ . }},
{{ end }}
)
{{- else if $req -}}
client.{{ .AST.Fun.Name }}(
{{ $req }}.Context(),
{{ range .AST.Args }}{{ . }},
{{ end }}
)
{{- else -}}
{{ . }}
{{- end -}}
gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http.Server
HTTP server implementation.
Server.Serve
Function body
- Function declaration
- Is method of
*http.Server
- Function name
Serve
Introduce new declarations:
//go:linkname __dd_contrib_net_http_internal_orchestrion_WrapHandler gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http/internal/orchestrion.WrapHandler
func __dd_contrib_net_http_internal_orchestrion_WrapHandler(Handler) Handler
Record link-time dependencies on:
Prepend statements produced by the following template:
{{- $srv := .Function.Receiver -}}
if {{ $srv }}.Handler == nil {
{{ $srv }}.Handler = __dd_contrib_net_http_internal_orchestrion_WrapHandler(DefaultServeMux)
} else {
{{ $srv }}.Handler = __dd_contrib_net_http_internal_orchestrion_WrapHandler({{ $srv }}.Handler)
}