 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			147 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright The OpenTelemetry Authors
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License");
 | |
| // you may not use this file except in compliance with the License.
 | |
| // You may obtain a copy of the License at
 | |
| //
 | |
| //     http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS,
 | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| // See the License for the specific language governing permissions and
 | |
| // limitations under the License.
 | |
| 
 | |
| package attribute // import "go.opentelemetry.io/otel/attribute"
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"sync"
 | |
| 	"sync/atomic"
 | |
| )
 | |
| 
 | |
| type (
 | |
| 	// Encoder is a mechanism for serializing an attribute set into a specific
 | |
| 	// string representation that supports caching, to avoid repeated
 | |
| 	// serialization. An example could be an exporter encoding the attribute
 | |
| 	// set into a wire representation.
 | |
| 	Encoder interface {
 | |
| 		// Encode returns the serialized encoding of the attribute set using
 | |
| 		// its Iterator. This result may be cached by a attribute.Set.
 | |
| 		Encode(iterator Iterator) string
 | |
| 
 | |
| 		// ID returns a value that is unique for each class of attribute
 | |
| 		// encoder. Attribute encoders allocate these using `NewEncoderID`.
 | |
| 		ID() EncoderID
 | |
| 	}
 | |
| 
 | |
| 	// EncoderID is used to identify distinct Encoder
 | |
| 	// implementations, for caching encoded results.
 | |
| 	EncoderID struct {
 | |
| 		value uint64
 | |
| 	}
 | |
| 
 | |
| 	// defaultAttrEncoder uses a sync.Pool of buffers to reduce the number of
 | |
| 	// allocations used in encoding attributes. This implementation encodes a
 | |
| 	// comma-separated list of key=value, with '/'-escaping of '=', ',', and
 | |
| 	// '\'.
 | |
| 	defaultAttrEncoder struct {
 | |
| 		// pool is a pool of attribute set builders. The buffers in this pool
 | |
| 		// grow to a size that most attribute encodings will not allocate new
 | |
| 		// memory.
 | |
| 		pool sync.Pool // *bytes.Buffer
 | |
| 	}
 | |
| )
 | |
| 
 | |
| // escapeChar is used to ensure uniqueness of the attribute encoding where
 | |
| // keys or values contain either '=' or ','.  Since there is no parser needed
 | |
| // for this encoding and its only requirement is to be unique, this choice is
 | |
| // arbitrary.  Users will see these in some exporters (e.g., stdout), so the
 | |
| // backslash ('\') is used as a conventional choice.
 | |
| const escapeChar = '\\'
 | |
| 
 | |
| var (
 | |
| 	_ Encoder = &defaultAttrEncoder{}
 | |
| 
 | |
| 	// encoderIDCounter is for generating IDs for other attribute encoders.
 | |
| 	encoderIDCounter uint64
 | |
| 
 | |
| 	defaultEncoderOnce     sync.Once
 | |
| 	defaultEncoderID       = NewEncoderID()
 | |
| 	defaultEncoderInstance *defaultAttrEncoder
 | |
| )
 | |
| 
 | |
| // NewEncoderID returns a unique attribute encoder ID. It should be called
 | |
| // once per each type of attribute encoder. Preferably in init() or in var
 | |
| // definition.
 | |
| func NewEncoderID() EncoderID {
 | |
| 	return EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)}
 | |
| }
 | |
| 
 | |
| // DefaultEncoder returns an attribute encoder that encodes attributes in such
 | |
| // a way that each escaped attribute's key is followed by an equal sign and
 | |
| // then by an escaped attribute's value. All key-value pairs are separated by
 | |
| // a comma.
 | |
| //
 | |
| // Escaping is done by prepending a backslash before either a backslash, equal
 | |
| // sign or a comma.
 | |
| func DefaultEncoder() Encoder {
 | |
| 	defaultEncoderOnce.Do(func() {
 | |
| 		defaultEncoderInstance = &defaultAttrEncoder{
 | |
| 			pool: sync.Pool{
 | |
| 				New: func() interface{} {
 | |
| 					return &bytes.Buffer{}
 | |
| 				},
 | |
| 			},
 | |
| 		}
 | |
| 	})
 | |
| 	return defaultEncoderInstance
 | |
| }
 | |
| 
 | |
| // Encode is a part of an implementation of the AttributeEncoder interface.
 | |
| func (d *defaultAttrEncoder) Encode(iter Iterator) string {
 | |
| 	buf := d.pool.Get().(*bytes.Buffer)
 | |
| 	defer d.pool.Put(buf)
 | |
| 	buf.Reset()
 | |
| 
 | |
| 	for iter.Next() {
 | |
| 		i, keyValue := iter.IndexedAttribute()
 | |
| 		if i > 0 {
 | |
| 			_, _ = buf.WriteRune(',')
 | |
| 		}
 | |
| 		copyAndEscape(buf, string(keyValue.Key))
 | |
| 
 | |
| 		_, _ = buf.WriteRune('=')
 | |
| 
 | |
| 		if keyValue.Value.Type() == STRING {
 | |
| 			copyAndEscape(buf, keyValue.Value.AsString())
 | |
| 		} else {
 | |
| 			_, _ = buf.WriteString(keyValue.Value.Emit())
 | |
| 		}
 | |
| 	}
 | |
| 	return buf.String()
 | |
| }
 | |
| 
 | |
| // ID is a part of an implementation of the AttributeEncoder interface.
 | |
| func (*defaultAttrEncoder) ID() EncoderID {
 | |
| 	return defaultEncoderID
 | |
| }
 | |
| 
 | |
| // copyAndEscape escapes `=`, `,` and its own escape character (`\`),
 | |
| // making the default encoding unique.
 | |
| func copyAndEscape(buf *bytes.Buffer, val string) {
 | |
| 	for _, ch := range val {
 | |
| 		switch ch {
 | |
| 		case '=', ',', escapeChar:
 | |
| 			_, _ = buf.WriteRune(escapeChar)
 | |
| 		}
 | |
| 		_, _ = buf.WriteRune(ch)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Valid returns true if this encoder ID was allocated by
 | |
| // `NewEncoderID`.  Invalid encoder IDs will not be cached.
 | |
| func (id EncoderID) Valid() bool {
 | |
| 	return id.value != 0
 | |
| }
 |