1// Copyright 2019, OpenTelemetry Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package metric 16 17import ( 18 "bytes" 19 "sync" 20 21 "go.opentelemetry.io/otel/api/core" 22 export "go.opentelemetry.io/otel/sdk/export/metric" 23) 24 25type defaultLabelEncoder struct { 26 // pool is a pool of labelset builders. The buffers in this 27 // pool grow to a size that most label encodings will not 28 // allocate new memory. This pool reduces the number of 29 // allocations per new LabelSet to 3, typically, as seen in 30 // the benchmarks. (It should be 2--one for the LabelSet 31 // object and one for the buffer.String() here--see the extra 32 // allocation in the call to sort.Stable). 33 pool sync.Pool // *bytes.Buffer 34} 35 36var _ export.LabelEncoder = &defaultLabelEncoder{} 37 38func NewDefaultLabelEncoder() export.LabelEncoder { 39 return &defaultLabelEncoder{ 40 pool: sync.Pool{ 41 New: func() interface{} { 42 return &bytes.Buffer{} 43 }, 44 }, 45 } 46} 47 48func (d *defaultLabelEncoder) Encode(labels []core.KeyValue) string { 49 buf := d.pool.Get().(*bytes.Buffer) 50 defer d.pool.Put(buf) 51 buf.Reset() 52 53 for i, kv := range labels { 54 if i > 0 { 55 _, _ = buf.WriteRune(',') 56 } 57 _, _ = buf.WriteString(string(kv.Key)) 58 _, _ = buf.WriteRune('=') 59 _, _ = buf.WriteString(kv.Value.Emit()) 60 } 61 return buf.String() 62} 63