diff --git a/pkg/metric/profiling_metric.go b/pkg/metric/profiling_metric.go index aa321077e..c66ce60d5 100644 --- a/pkg/metric/profiling_metric.go +++ b/pkg/metric/profiling_metric.go @@ -99,6 +99,9 @@ type ProfilingMetricsWriter interface { // WriteString from the io.StringWriter interface. io.StringWriter + // Truncate truncates the underlying writer, if possible. + Truncate(size int64) error + // Close closes the writer. Close() error } @@ -198,6 +201,13 @@ func StartProfilingMetrics[T ProfilingMetricsWriter](opts ProfilingMetricsOption s.ringbuffer[i] = make([]uint64, snapshotBufferSize*(numMetrics+1)) } + // Truncate the underlying sink if possible to delete any past profiling + // data in the file, if any, as it makes no sense to concatenate them or + // to overwrite them in-place. + // We ignore errors here because the sink may not be truncatable, + // e.g. when it is pointing to the stdout FD. + _ = opts.Sink.Truncate(0) + stopProfilingMetrics = atomicbitops.FromBool(false) doneProfilingMetrics = make(chan bool, 1) writeCh := make(chan writeReq, snapshotRingbufferSize) @@ -377,6 +387,11 @@ func (w *bufferedWriter[T]) Flush() { w.buf.Reset() } +// Truncate implements bufferedMetricsWriter.Truncate. +func (w *bufferedWriter[T]) Truncate(size int64) error { + return w.underlying.Truncate(size) +} + // Close implements bufferedMetricsWriter.Close. func (w *bufferedWriter[T]) Close() error { w.Flush() @@ -479,6 +494,11 @@ func (w *lossyBufferedWriter[T]) NewLine() { } } +// Truncate implements bufferedMetricsWriter.Truncate. +func (w *lossyBufferedWriter[T]) Truncate(size int64) error { + return w.underlying.Truncate(size) +} + // Close implements bufferedMetricsWriter.Close. // It writes the checksum of the data written to the underlying writer. func (w *lossyBufferedWriter[T]) Close() error {