Skip to content

Commit

Permalink
profiler: record Orchestrion, activation information (#2814)
Browse files Browse the repository at this point in the history
For tracking adoption of SSI for profiling, record whether the profiler
was added using Orchestrion and how the profiler was activated,
following the internal "Adding SSI information to profiles" RFC.
  • Loading branch information
nsrip-dd authored Sep 10, 2024
1 parent 4574919 commit 0ffa615
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
31 changes: 31 additions & 0 deletions profiler/profiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig"
"gopkg.in/DataDog/dd-trace-go.v1/internal/httpmem"
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
"gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion"
"gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof"
"gopkg.in/DataDog/dd-trace-go.v1/internal/version"

Expand Down Expand Up @@ -748,3 +749,33 @@ func TestUDSDefault(t *testing.T) {

<-profiles
}

func TestOrchestrionProfileInfo(t *testing.T) {
testCases := []struct {
env string
want string
}{
{want: "manual"},
{env: "1", want: "manual"},
{env: "true", want: "manual"},
{env: "auto", want: "auto"},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("env=\"%s\"", tc.env), func(t *testing.T) {
t.Setenv("DD_PROFILING_ENABLED", tc.env)
p := doOneShortProfileUpload(t)
info := p.event.Info.Profiler
t.Logf("%+v", info)
if got := info.Activation; got != tc.want {
t.Errorf("wanted profiler activation \"%s\", got %s", tc.want, got)
}
want := "none"
if orchestrion.Enabled() {
want = "orchestrion"
}
if got := info.SSI.Mechanism; got != want {
t.Errorf("wanted profiler injected = %v, got %v", want, got)
}
})
}
}
32 changes: 32 additions & 0 deletions profiler/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import (
"mime/multipart"
"net/http"
"net/textproto"
"os"
"strings"
"time"

"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
"gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion"
)

// maxRetries specifies the maximum number of retries to have when an error occurs.
Expand Down Expand Up @@ -144,6 +146,20 @@ type uploadEvent struct {
Version string `json:"version"`
EndpointCounts map[string]uint64 `json:"endpoint_counts,omitempty"`
CustomAttributes []string `json:"custom_attributes,omitempty"`
Info struct {
Profiler profilerInfo `json:"profiler"`
} `json:"info"`
}

// profilerInfo holds profiler-specific information which should be attached to
// the event for backend consumption
type profilerInfo struct {
SSI struct {
Mechanism string `json:"mechanism,omitempty"`
} `json:"ssi"`
// Activation distinguishes how the profiler was enabled, either "auto"
// (env var set via admission controller) or "manual"
Activation string `json:"activation"`
}

// encode encodes the profile as a multipart mime request.
Expand All @@ -167,6 +183,22 @@ func encode(bat batch, tags []string) (contentType string, body io.Reader, err e
CustomAttributes: bat.customAttributes,
}

// DD_PROFILING_ENABLED is only used to enable profiling when added with
// Orchestrion. The "auto" value comes from the Datadog Kubernetes
// admission controller. Otherwise, the client library doesn't care
// about the value and assumes it was something "truthy", or this code
// wouldn't run. We just track it to be consistent with other languages
if os.Getenv("DD_PROFILING_ENABLED") == "auto" {
event.Info.Profiler.Activation = "auto"
} else {
event.Info.Profiler.Activation = "manual"
}
if orchestrion.Enabled() {
event.Info.Profiler.SSI.Mechanism = "orchestrion"
} else {
event.Info.Profiler.SSI.Mechanism = "none"
}

for _, p := range bat.profiles {
event.Attachments = append(event.Attachments, p.name)
f, err := mw.CreateFormFile(p.name, p.name)
Expand Down

0 comments on commit 0ffa615

Please sign in to comment.