Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d74a7fb
start adding support for units
vesari Nov 26, 2023
5d8c6de
do not assume units for now
vesari Nov 30, 2023
f78b666
again, do not assume units
vesari Nov 30, 2023
e876012
assume the units
vesari Dec 2, 2023
b1f5a86
add units in more places
vesari Dec 2, 2023
788d53b
fix dependencies in go.mod
vesari Dec 2, 2023
1692495
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Jan 19, 2024
5971215
Update version of common in go.mod
vesari Jan 20, 2024
efb64f3
Start modifying handler
vesari Jan 27, 2024
fafe45b
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Feb 14, 2024
51861d5
Use different common
vesari Mar 7, 2024
1362436
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Mar 7, 2024
a2bfd3a
Use the newly named func for OM encoding
vesari Mar 14, 2024
7900714
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Mar 14, 2024
19d7102
Fix examples and comments
vesari Mar 14, 2024
031e0d3
Fix go.mod
vesari Mar 14, 2024
fd60a57
Adapt go.mod as much as possible
vesari Mar 14, 2024
f7e2848
Use go 1.20
vesari Mar 15, 2024
5f58996
Use go 1.21
vesari Mar 15, 2024
ac9d1d8
Upgrade github workflows to go 1.21 needed for common
vesari Mar 15, 2024
3db440e
Delete test funcs which are unused according to lint
vesari Mar 15, 2024
7752d37
Upgrade to Go 1.21 in Makefile and workflows for tests
vesari Mar 15, 2024
47c8cf1
Upgrade Go version to 1.21 in tutorial
vesari Mar 15, 2024
7312bd5
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Apr 13, 2024
3644321
Adapt to forthcoming new handlers options, reinstate support for old Go
vesari Apr 22, 2024
dca67a5
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Apr 22, 2024
ab34546
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari May 7, 2024
717d3d3
Update prometheus/promhttp/http.go
vesari May 9, 2024
5b5c4be
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Oct 17, 2025
a635a5a
small cleanup
vesari Oct 17, 2025
e5f8851
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Nov 9, 2025
9eac68e
Make desc funcs variadic
vesari Nov 16, 2025
3441cb0
Adjust http to have unit and test accordingly
vesari Nov 19, 2025
52eb82d
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Nov 19, 2025
99ae579
Update prometheus/metric.go
vesari Dec 14, 2025
1d93cb8
Update prometheus/promhttp/http.go
vesari Dec 14, 2025
00d2201
Merge remote-tracking branch 'prometheus/main' into add-unit
vesari Dec 14, 2025
5a07918
Fix formatting
vesari Dec 14, 2025
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
1 change: 1 addition & 0 deletions examples/exemplars/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func main() {
requestDurations := prometheus.NewHistogram(prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "A histogram of the HTTP request durations in seconds.",
Unit: "seconds",
Buckets: prometheus.ExponentialBuckets(0.1, 1.5, 5),
})

Expand Down
3 changes: 3 additions & 0 deletions prometheus/counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func NewCounter(opts CounterOpts) Counter {
opts.Help,
nil,
opts.ConstLabels,
opts.Unit,
)
if opts.now == nil {
opts.now = time.Now
Expand Down Expand Up @@ -203,6 +204,7 @@ func (v2) NewCounterVec(opts CounterVecOpts) *CounterVec {
desc := V2.NewDesc(
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
opts.Help,
// opts.Unit, // QUESTION: shall I put this for last?
Copy link
Member

Choose a reason for hiding this comment

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

I think here is ok, or even after name.

opts.VariableLabels,
opts.ConstLabels,
)
Expand Down Expand Up @@ -354,5 +356,6 @@ func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc {
opts.Help,
nil,
opts.ConstLabels,
opts.Unit,
), CounterValue, function)
}
22 changes: 17 additions & 5 deletions prometheus/desc.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ type Desc struct {
fqName string
// help provides some helpful information about this metric.
help string
// unit provides the unit of this metric.
Copy link
Member

Choose a reason for hiding this comment

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

unit string
// constLabelPairs contains precalculated DTO label pairs based on
// the constant labels.
constLabelPairs []*dto.LabelPair
Expand All @@ -66,6 +68,13 @@ type Desc struct {
err error
}

func optionalUnitValue(unit ...string) string {
if len(unit) > 0 {
return unit[0]
}
return ""
}

// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc
// and will be reported on registration time. variableLabels and constLabels can
// be nil if no such labels should be set. fqName must not be empty.
Expand All @@ -75,8 +84,8 @@ type Desc struct {
//
// For constLabels, the label values are constant. Therefore, they are fully
// specified in the Desc. See the Collector example for a usage pattern.
func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *Desc {
return V2.NewDesc(fqName, help, UnconstrainedLabels(variableLabels), constLabels)
func NewDesc(fqName, help string, variableLabels []string, constLabels Labels, unit ...string) *Desc {
Copy link
Member

Choose a reason for hiding this comment

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

Nice! I was about to comment we can't break compatibility, but you found a way.

I am not a fan as it's a very one-time hack (:

Some alternatives:

A. Do descOpts variadic parameter so we are flexible.
B. Don't change NewDesc but instead use V2.NewDesc everywhere internally. This should suffice for all usages, no?

return V2.NewDesc(fqName, help, UnconstrainedLabels(variableLabels), constLabels, optionalUnitValue(unit...))
}

// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc
Expand All @@ -89,11 +98,12 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
//
// For constLabels, the label values are constant. Therefore, they are fully
// specified in the Desc. See the Collector example for a usage pattern.
func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, constLabels Labels) *Desc {
func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, constLabels Labels, unit ...string) *Desc {
Copy link
Member

Choose a reason for hiding this comment

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

Here, I wonder if we don't want to break compatibility. 🤔 It's V2 and I wished we marked it as experimental somewhere visibility (it was meant to experiment on a new API). However, I bet downstream ecosystem already started using it.

I'd suggest, (see A, B options in https://github.com/prometheus/client_golang/pull/1392/files#r2580668173)

  • For NewDesc we do (B)
  • For V2 we do (A) ?

d := &Desc{
fqName: fqName,
help: help,
variableLabels: variableLabels.compile(),
unit: optionalUnitValue(unit...),
}
//nolint:staticcheck // TODO: Don't use deprecated model.NameValidationScheme.
if !model.NameValidationScheme.IsValidMetricName(fqName) {
Expand Down Expand Up @@ -150,10 +160,11 @@ func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, const
d.id = xxh.Sum64()
// Sort labelNames so that order doesn't matter for the hash.
sort.Strings(labelNames)
// Now hash together (in this order) the help string and the sorted
// Now hash together (in this order) the help string, the unit string and the sorted
// label names.
xxh.Reset()
xxh.WriteString(help)
xxh.WriteString(optionalUnitValue(unit...))
Copy link
Member

Choose a reason for hiding this comment

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

let's eval unit as soon as we have it from descV2Opts or something

xxh.Write(separatorByteSlice)
for _, labelName := range labelNames {
xxh.WriteString(labelName)
Expand Down Expand Up @@ -211,9 +222,10 @@ func (d *Desc) String() string {
}
}
return fmt.Sprintf(
"Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: {%s}}",
"Desc{fqName: %q, help: %q, unit: %q, constLabels: {%s}, variableLabels: {%s}}",
Copy link
Member

Choose a reason for hiding this comment

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

ditto, optionally print it?

d.fqName,
d.help,
d.unit,
strings.Join(lpStrings, ","),
strings.Join(vlStrings, ","),
)
Expand Down
17 changes: 15 additions & 2 deletions prometheus/desc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestNewDescWithNilLabelValues_String(t *testing.T) {
nil,
nil,
)
if desc.String() != `Desc{fqName: "sample_label", help: "sample label", constLabels: {}, variableLabels: {}}` {
if desc.String() != `Desc{fqName: "sample_label", help: "sample label", unit: "", constLabels: {}, variableLabels: {}}` {
t.Errorf("String: unexpected output: %s", desc.String())
}
}
Expand All @@ -71,7 +71,20 @@ func TestNewInvalidDesc_String(t *testing.T) {
desc := NewInvalidDesc(
nil,
)
if desc.String() != `Desc{fqName: "", help: "", constLabels: {}, variableLabels: {}}` {
if desc.String() != `Desc{fqName: "", help: "", unit: "", constLabels: {}, variableLabels: {}}` {
t.Errorf("String: unexpected output: %s", desc.String())
}
}

func TestNewDescWithUnit_String(t *testing.T) {
desc := NewDesc(
"sample_metric_bytes",
"sample metric with unit",
nil,
nil,
"bytes",
)
if desc.String() != `Desc{fqName: "sample_metric_bytes", help: "sample metric with unit", unit: "bytes", constLabels: {}, variableLabels: {}}` {
t.Errorf("String: unexpected output:\ngot: %s\nwant: %s", desc.String(), desc.String())
}
}
8 changes: 6 additions & 2 deletions prometheus/example_metricvec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ type InfoVec struct {
*prometheus.MetricVec
}

func NewInfoVec(name, help string, labelNames []string) *InfoVec {
desc := prometheus.NewDesc(name, help, labelNames, nil)
func NewInfoVec(name, help string, labelNames []string, unit ...string) *InfoVec {
var u string
if len(unit) > 0 {
u = unit[0]
}
desc := prometheus.NewDesc(name, help, labelNames, nil, u)
return &InfoVec{
MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric {
if len(lvs) != len(labelNames) {
Expand Down
12 changes: 9 additions & 3 deletions prometheus/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ func ExampleRegister() {

// Output:
// taskCounter registered.
// taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: {worker_id}} has different label names or a different help string
// taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", unit: "", constLabels: {}, variableLabels: {worker_id}} has different label names or a different help string
// taskCounter unregistered.
// taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: {worker_id}} has different label names or a different help string
// taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", unit: "", constLabels: {}, variableLabels: {worker_id}} has different label names or a different help string
// taskCounterVec registered.
// Worker initialization failed: inconsistent label cardinality: expected 1 label values but got 2 in []string{"42", "spurious arg"}
// notMyCounter is nil.
Expand Down Expand Up @@ -386,6 +386,7 @@ func ExampleNewConstSummary() {
"A summary of the HTTP request durations.",
[]string{"code", "method"},
prometheus.Labels{"owner": "example"},
"seconds",
)

// Create a constant summary from values we got from a 3rd party telemetry system.
Expand Down Expand Up @@ -440,7 +441,8 @@ func ExampleHistogram() {
temps := prometheus.NewHistogram(prometheus.HistogramOpts{
Name: "pond_temperature_celsius",
Help: "The temperature of the frog pond.", // Sorry, we can't measure how badly it smells.
Buckets: prometheus.LinearBuckets(20, 5, 5), // 5 buckets, each 5 centigrade wide.
Unit: "celsius",
Buckets: prometheus.LinearBuckets(20, 5, 5), // 5 buckets, each 5 centigrade wide.
})

// Simulate some observations.
Expand All @@ -466,6 +468,7 @@ func ExampleNewConstHistogram() {
"A histogram of the HTTP request durations.",
[]string{"code", "method"},
prometheus.Labels{"owner": "example"},
"seconds",
)

// Create a constant histogram from values we got from a 3rd party telemetry system.
Expand Down Expand Up @@ -521,6 +524,7 @@ func ExampleNewConstHistogram_withExemplar() {
"A histogram of the HTTP request durations.",
[]string{"code", "method"},
prometheus.Labels{"owner": "example"},
"seconds",
)

// Create a constant histogram from values we got from a 3rd party telemetry system.
Expand Down Expand Up @@ -690,6 +694,7 @@ func ExampleNewMetricWithTimestamp() {
"temperature_kelvin",
"Current temperature in Kelvin.",
nil, nil,
"kelvin",
)

// Create a constant gauge from values we got from an external
Expand Down Expand Up @@ -723,6 +728,7 @@ func ExampleNewConstMetricWithCreatedTimestamp() {
"time_since_epoch_seconds",
"Current epoch time in seconds.",
nil, nil,
"seconds",
)

timeSinceEpochReportedByExternalSystem := time.Date(2009, time.November, 10, 23, 0, 0, 12345678, time.UTC)
Expand Down
3 changes: 3 additions & 0 deletions prometheus/gauge.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func NewGauge(opts GaugeOpts) Gauge {
opts.Help,
nil,
opts.ConstLabels,
opts.Unit,
)
result := &gauge{desc: desc, labelPairs: desc.constLabelPairs}
result.init(result) // Init self-collection.
Expand Down Expand Up @@ -163,6 +164,7 @@ func (v2) NewGaugeVec(opts GaugeVecOpts) *GaugeVec {
opts.Help,
opts.VariableLabels,
opts.ConstLabels,
opts.Unit,
)
return &GaugeVec{
MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
Expand Down Expand Up @@ -307,5 +309,6 @@ func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc {
opts.Help,
nil,
opts.ConstLabels,
opts.Unit,
), GaugeValue, function)
}
2 changes: 1 addition & 1 deletion prometheus/gauge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func TestGaugeFunc(t *testing.T) {
func() float64 { return 3.1415 },
)

if expected, got := `Desc{fqName: "test_name", help: "test help", constLabels: {a="1",b="2"}, variableLabels: {}}`, gf.Desc().String(); expected != got {
if expected, got := `Desc{fqName: "test_name", help: "test help", unit: "", constLabels: {a="1",b="2"}, variableLabels: {}}`, gf.Desc().String(); expected != got {
t.Errorf("expected %q, got %q", expected, got)
}

Expand Down
9 changes: 7 additions & 2 deletions prometheus/go_collector_latest.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ type goCollector struct {
// snapshot is always produced by Collect.
mu sync.Mutex

// Contains all samples that has to retrieved from runtime/metrics (not all of them will be exposed).
// Contains all samples that have to be retrieved from runtime/metrics (not all of them will be exposed).
sampleBuf []metrics.Sample
// sampleMap allows lookup for MemStats metrics and runtime/metrics histograms for exact sums.
sampleMap map[string]*metrics.Sample
Expand Down Expand Up @@ -210,16 +210,19 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name})
sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1]

// Extract unit from the runtime/metrics name (e.g., "/gc/heap/allocs:bytes" -> "bytes")
Copy link
Member

Choose a reason for hiding this comment

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

That's nice!

unit := d.Name[strings.IndexRune(d.Name, ':')+1:]

var m collectorMetric
if d.Kind == metrics.KindFloat64Histogram {
_, hasSum := opt.RuntimeMetricSumForHist[d.Name]
unit := d.Name[strings.IndexRune(d.Name, ':')+1:]
m = newBatchHistogram(
NewDesc(
BuildFQName(namespace, subsystem, name),
help,
nil,
nil,
unit,
),
internal.RuntimeMetricsBucketsForUnit(bucketsMap[d.Name], unit),
hasSum,
Expand All @@ -230,6 +233,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
Subsystem: subsystem,
Name: name,
Help: help,
Unit: unit,
},
)
} else {
Expand All @@ -238,6 +242,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {
Subsystem: subsystem,
Name: name,
Help: help,
Unit: unit,
})
}
metricSet = append(metricSet, m)
Expand Down
5 changes: 5 additions & 0 deletions prometheus/histogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ type HistogramOpts struct {
// string.
Help string

// Unit provides the unit of this Histogram.
Unit string

// ConstLabels are used to attach fixed labels to this metric. Metrics
// with the same fully-qualified name must have the same label names in
// their ConstLabels.
Expand Down Expand Up @@ -527,6 +530,7 @@ func NewHistogram(opts HistogramOpts) Histogram {
opts.Help,
nil,
opts.ConstLabels,
opts.Unit,
),
opts,
)
Expand Down Expand Up @@ -1190,6 +1194,7 @@ func (v2) NewHistogramVec(opts HistogramVecOpts) *HistogramVec {
opts.Help,
opts.VariableLabels,
opts.ConstLabels,
opts.Unit,
)
return &HistogramVec{
MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
Expand Down
3 changes: 3 additions & 0 deletions prometheus/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ type Opts struct {
// string.
Help string

// Unit provides the unit of this metric as per https://prometheus.io/docs/specs/om
Unit string

// ConstLabels are used to attach fixed labels to this metric. Metrics
// with the same fully-qualified name must have the same label names in
// their ConstLabels.
Expand Down
4 changes: 2 additions & 2 deletions prometheus/metric_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestWithExemplarsMetric(t *testing.T) {
t.Run("histogram", func(t *testing.T) {
// Create a constant histogram from values we got from a 3rd party telemetry system.
h := MustNewConstHistogram(
NewDesc("http_request_duration_seconds", "A histogram of the HTTP request durations.", nil, nil),
NewDesc("http_request_duration_seconds", "A histogram of the HTTP request durations.", nil, nil, "seconds"),
4711, 403.34,
// Four buckets, but we expect five as the +Inf bucket will be created if we see value outside of those buckets.
map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233},
Expand Down Expand Up @@ -99,7 +99,7 @@ func TestWithExemplarsNativeHistogramMetric(t *testing.T) {
t.Run("native histogram single exemplar", func(t *testing.T) {
// Create a constant histogram from values we got from a 3rd party telemetry system.
h := MustNewConstNativeHistogram(
NewDesc("http_request_duration_seconds", "A histogram of the HTTP request durations.", nil, nil),
NewDesc("http_request_duration_seconds", "A histogram of the HTTP request durations.", nil, nil, "seconds"),
10, 12.1, map[int]int64{1: 7, 2: 1, 3: 2}, map[int]int64{}, 0, 2, 0.2, time.Date(
2009, 11, 17, 20, 34, 58, 651387237, time.UTC))
m := &withExemplarsMetric{Metric: h, exemplars: []*dto.Exemplar{
Expand Down
16 changes: 12 additions & 4 deletions prometheus/promhttp/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,17 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO
rsp.Header().Set(contentEncodingHeader, encodingHeader)
}

var enc expfmt.Encoder
var (
enc expfmt.Encoder
encOpts []expfmt.EncoderOption
)
if opts.EnableOpenMetricsTextCreatedSamples {
enc = expfmt.NewEncoder(w, contentType, expfmt.WithCreatedLines())
} else {
enc = expfmt.NewEncoder(w, contentType)
encOpts = append(encOpts, expfmt.WithCreatedLines())
}
if opts.EnableOpenMetricsUnit {
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this manual flag?

Why can't we simply add UNIT line if someone enabled OM? Shouldn't this be safe?

Copy link
Member

Choose a reason for hiding this comment

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

We added flag for EnableOpenMetricsTextCreatedSamples because we believe CT line is potentially breaking to the ecosystem (lot's of problems). But with UNIT metadata, I'd expect OM compatible parsers to either ignore it or parse. Even TEXT formats should work, because it's just a # .. comment.

The only potential risk is the slight increase of payload size, but this is actually limited by the user who need to manually add Unit: <....> fields to their metric definitions, no?

encOpts = append(encOpts, expfmt.WithUnit())
Copy link
Member

Choose a reason for hiding this comment

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

I wonder, does this print UNIT line if UNIT is unknown (empty string?)

Can we ensure this does NOT add UNIT if it's unknown? Just to safe space and limit the risks mentioned in https://github.com/prometheus/client_golang/pull/1392/files#r2580622660

}
enc = expfmt.NewEncoder(w, contentType, encOpts...)

// handleError handles the error according to opts.ErrorHandling
// and returns true if we have to abort after the handling.
Expand Down Expand Up @@ -461,6 +466,9 @@ type HandlerOpts struct {
// Prometheus introduced the feature flag 'created-timestamp-zero-ingestion'
// in version 2.50.0 to handle this situation.
EnableOpenMetricsTextCreatedSamples bool
// EnableOpenMetricsUnit enables unit metadata in the OpenMetrics output format.
// This is only applicable when OpenMetrics format is negotiated.
EnableOpenMetricsUnit bool
Copy link
Member

Choose a reason for hiding this comment

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

again, I wonder if we could skip this (reduce complexity and effort for everyone, users already need to manually add Unit field).

// ProcessStartTime allows setting process start timevalue that will be exposed
// with "Process-Start-Time-Unix" response header along with the metrics
// payload. This allow callers to have efficient transformations to cumulative
Expand Down
Loading
Loading