Skip to content

Commit

Permalink
Encode labels once during checkpoint (#572)
Browse files Browse the repository at this point in the history
The `checkpoint` function is executed in a single thread so we can do
the encoding lazily before passing the encoded version of labels to
the exporter. This is a cheap and quick way to avoid encoding the
labels on every collection interval.

Co-authored-by: Rahul Patel <[email protected]>
  • Loading branch information
krnowak and rghetia authored Mar 20, 2020
1 parent f7df68b commit cc756f6
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions sdk/metric/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ type (
// cachedValue contains a `reflect.Value` of the `ordered`
// member
cachedValue reflect.Value
// cachedEncoded contains an encoded version of the
// `ordered` member
cachedEncoded string
}

// mapkey uniquely describes a metric instrument in terms of
Expand Down Expand Up @@ -379,6 +382,14 @@ func (ls *labels) computeOrdered(kvs []core.KeyValue) {
ls.cachedValue = reflect.ValueOf(ls.ordered)
}

func (ls *labels) ensureEncoded(encoder export.LabelEncoder) {
if ls.cachedEncoded != "" {
return
}
iter := export.NewLabelIterator(ls)
ls.cachedEncoded = encoder.Encode(iter)
}

func computeOrderedFixed(kvs []core.KeyValue) orderedLabels {
switch len(kvs) {
case 1:
Expand Down Expand Up @@ -556,12 +567,8 @@ func (m *SDK) checkpoint(ctx context.Context, descriptor *metric.Descriptor, rec
}
recorder.Checkpoint(ctx, descriptor)

// TODO Labels are encoded once per collection interval,
// instead of once per bound instrument lifetime. This can be
// addressed similarly to OTEP 78, see
// https://github.com/jmacd/opentelemetry-go/blob/8bed2e14df7f9f4688fbab141924bb786dc9a3a1/api/context/internal/set.go#L89
iter := export.NewLabelIterator(labels)
exportLabels := export.NewLabels(labels, m.labelEncoder.Encode(iter), m.labelEncoder)
labels.ensureEncoded(m.labelEncoder)
exportLabels := export.NewLabels(labels, labels.cachedEncoded, m.labelEncoder)
exportRecord := export.NewRecord(descriptor, exportLabels, recorder)
err := m.batcher.Process(ctx, exportRecord)
if err != nil {
Expand Down

0 comments on commit cc756f6

Please sign in to comment.