Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timeline #55

Merged
merged 7 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cli_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ var (
argProbabilisticInterval time.Duration
argPprofAddr string
argSaveCPUProfile bool
argTimeline bool

// "internal" flag variables.
// Flag variables that are configured in "internal" builds will have to be assigned
Expand Down Expand Up @@ -161,6 +162,7 @@ func parseArgs() error {
saveCPUProfileHelp)
fs.IntVar(&argSamplesPerSecond, "samples-per-second", defaultArgSamplesPerSecond,
samplesPerSecondHelp)
fs.BoolVar(&argTimeline, "timeline", false, "Enable timeline feature.")

fs.Usage = func() {
fs.PrintDefaults()
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ func mainWithExitCode() exitCode {
FallbackSymbolsMaxQueue: 1024,
DisableTLS: argDisableTLS,
MaxGRPCRetries: 5,
Timeline: argTimeline,
SamplesPerSecond: conf.SamplesPerSecond,
SaveCPUProfile: argSaveCPUProfile,
Times: times,
Expand Down
3 changes: 3 additions & 0 deletions reporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ type Config struct {

SaveCPUProfile bool

// Whether to include timestamps on samples for the timeline feature
Timeline bool

Times Times

// gRPCInterceptor is the client gRPC interceptor, e.g., for sending gRPC metadata.
Expand Down
32 changes: 26 additions & 6 deletions reporter/datadog_reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"os"
"path"
"runtime"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -49,6 +50,8 @@ type DatadogReporter struct {

agentAddr string

timeline bool

samplingPeriod uint64

saveCPUProfile bool
Expand Down Expand Up @@ -255,6 +258,7 @@ func StartDatadog(mainCtx context.Context, cfg *Config) (Reporter, error) {
agentAddr: cfg.CollAgentAddr,
samplingPeriod: 1000000000 / uint64(cfg.SamplesPerSecond),
saveCPUProfile: cfg.SaveCPUProfile,
timeline: cfg.Timeline,
fallbackSymbols: fallbackSymbols,
executables: executables,
frames: frames,
Expand Down Expand Up @@ -512,17 +516,21 @@ func (r *DatadogReporter) getPprofProfile() (profile *pprofile.Profile,
// location with the kernel as the function name.
execPath = "kernel"
}
baseExec := path.Base(execPath)

if execPath != "" {
base := path.Base(execPath)
loc := createPProfLocation(profile, 0)
m := createPprofFunctionEntry(funcMap, profile, base, execPath)
m := createPprofFunctionEntry(funcMap, profile, baseExec, execPath)
loc.Line = append(loc.Line, pprofile.Line{Function: m})
sample.Location = append(sample.Location, loc)
}

sample.Label = make(map[string][]string)
addTraceLabels(sample.Label, traceKey)
var timestamps []uint64
if r.timeline {
timestamps = traceInfo.timestamps
}
addTraceLabels(sample.Label, &traceKey, baseExec, timestamps) //nolint:gomemory

count := int64(len(traceInfo.timestamps))
sample.Value = append(sample.Value, count, count*int64(r.samplingPeriod))
Expand Down Expand Up @@ -564,12 +572,11 @@ func createPprofFunctionEntry(funcMap map[funcInfo]*pprofile.Function,
return function
}

//nolint:gocritic
func addTraceLabels(labels map[string][]string, k traceAndMetaKey) {
func addTraceLabels(labels map[string][]string, k *traceAndMetaKey,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the traceAndMetaKey to a pointer, highlighting in case there was any thought put into this earlier

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially kept it as a variable to avoid having to deal with #55 (comment) since this code is not on the hot path anyway for the copy to be too expensive (only called once per minute). Also wanted to keep the code closer to the upstream OTLP reporter. But this works for me as well, no strong opinions 👍

baseExec string, timestamps []uint64) {
if k.comm != "" {
labels["thread_name"] = append(labels["thread_name"], k.comm)
}

if k.podName != "" {
labels["pod_name"] = append(labels["pod_name"], k.podName)
}
Expand All @@ -596,6 +603,19 @@ func addTraceLabels(labels map[string][]string, k traceAndMetaKey) {
// This is also consistent with ddprof.
labels["thread id"] = append(labels["thread id"], fmt.Sprintf("%d", k.tid))
}

if baseExec != "" {
labels["process_name"] = append(labels["process_name"], baseExec)
}

if len(timestamps) > 0 {
timestampStrs := make([]string, 0, len(timestamps))
for _, ts := range timestamps {
timestampStrs = append(timestampStrs, strconv.FormatUint(ts, 10))
}
// Assign all timestamps as a single label entry
labels["end_timestamp_ns"] = timestampStrs
}
}

// getDummyMappingIndex inserts or looks up a dummy entry for interpreted FileIDs.
Expand Down
Loading