From e11780e4d491e85ef0b694d64b14117b81316751 Mon Sep 17 00:00:00 2001 From: Tommy Reilly Date: Mon, 26 Jan 2026 16:03:55 -0600 Subject: [PATCH] Use metrics for sample type counts --- reporter/parca_reporter.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/reporter/parca_reporter.go b/reporter/parca_reporter.go index 67bce3d0b8..22c6a48b45 100644 --- a/reporter/parca_reporter.go +++ b/reporter/parca_reporter.go @@ -133,6 +133,12 @@ type ParcaReporter struct { debuginfoUploadRequestBytes prometheus.Counter emptySamples prometheus.Counter + // Pre-created sample counters by type (avoid WithLabelValues allocations) + cpuSamples prometheus.Counter + gpuSamples prometheus.Counter + offcpuSamples prometheus.Counter + memorySamples prometheus.Counter + offlineModeConfig *OfflineModeConfig // Protects the log file, @@ -260,12 +266,12 @@ func (r *ParcaReporter) ReportTraceEvent(trace *libpf.Trace, case support.TraceOriginSampling: writeSample(1, time.Second.Nanoseconds(), 1e9/int64(r.samplesPerSecond), "parca_agent", "samples", "count", "cpu", "nanoseconds") r.sampleWriter.Temporality.AppendString("delta") + r.cpuSamples.Inc() case support.TraceOriginOffCPU: writeSample(meta.OffTime, time.Second.Nanoseconds(), 1e9/int64(r.samplesPerSecond), "parca_agent", "wallclock", "nanoseconds", "samples", "count") r.sampleWriter.Temporality.AppendString("delta") + r.offcpuSamples.Inc() case support.TraceOriginMemory: - // This shouldn't happen too much so an info log is fine, revisit when we do continuous memory profiling. - log.Infof("Received memory trace event for TID %d, PID %d, comm %s", meta.TID, meta.PID, meta.Comm) // TODO: this isn't necessarily correct and should be extracted from the Go process somehow. memPeriod := int64(512 * 1024) // 512 KiB // Write 4 memory samples @@ -287,9 +293,11 @@ func (r *ParcaReporter) ReportTraceEvent(trace *libpf.Trace, r.sampleWriter.Temporality.AppendNull() writeSample(int64(meta.AllocBytes), 0, memPeriod, "memory", "alloc_space", "bytes", "space", "bytes") } + r.memorySamples.Inc() case support.TraceOriginCuda: writeSample(meta.OffTime, time.Second.Nanoseconds(), 1e9/int64(r.samplesPerSecond), "parca_agent", "cuda", "nanoseconds", "cuda", "nanoseconds") r.sampleWriter.Temporality.AppendString("delta") + r.gpuSamples.Inc() } return nil @@ -629,11 +637,17 @@ func New( Help: "The number of empty samples reported to the Parca reporter", }) + samplesByType := prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "parca_reporter_samples_total", + Help: "Total number of samples by type", + }, []string{"type"}) + reg.MustRegister(sampleWriteRequestBytes) reg.MustRegister(sampleWrites) reg.MustRegister(stacktraceWriteRequestBytes) reg.MustRegister(debuginfoUploadRequestBytes) reg.MustRegister(emptySamples) + reg.MustRegister(samplesByType) r := &ParcaReporter{ stopSignal: make(chan libpf.Void), @@ -663,6 +677,10 @@ func New( emptySamples: emptySamples, stacktraceWriteRequestBytes: stacktraceWriteRequestBytes, debuginfoUploadRequestBytes: debuginfoUploadRequestBytes, + cpuSamples: samplesByType.WithLabelValues("cpu"), + gpuSamples: samplesByType.WithLabelValues("gpu"), + offcpuSamples: samplesByType.WithLabelValues("offcpu"), + memorySamples: samplesByType.WithLabelValues("memory"), offlineModeConfig: offlineModeConfig, offlineModeLoggedStacks: loggedStacks, } @@ -1067,7 +1085,7 @@ func (r *ParcaReporter) reportDataToBackend(ctx context.Context, buf *bytes.Buff return err } - log.Infof("[reporter] sending %d samples (%d bytes) to server", record.NumRows(), buf.Len()) + log.Debugf("Sending profile with %d samples (%d bytes)", record.NumRows(), buf.Len()) client, err := r.client.Write(ctx) if err != nil {