 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>
		
			
				
	
	
		
			283 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			283 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package log
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"math"
 | |
| )
 | |
| 
 | |
| type fieldType int
 | |
| 
 | |
| const (
 | |
| 	stringType fieldType = iota
 | |
| 	boolType
 | |
| 	intType
 | |
| 	int32Type
 | |
| 	uint32Type
 | |
| 	int64Type
 | |
| 	uint64Type
 | |
| 	float32Type
 | |
| 	float64Type
 | |
| 	errorType
 | |
| 	objectType
 | |
| 	lazyLoggerType
 | |
| 	noopType
 | |
| )
 | |
| 
 | |
| // Field instances are constructed via LogBool, LogString, and so on.
 | |
| // Tracing implementations may then handle them via the Field.Marshal
 | |
| // method.
 | |
| //
 | |
| // "heavily influenced by" (i.e., partially stolen from)
 | |
| // https://github.com/uber-go/zap
 | |
| type Field struct {
 | |
| 	key          string
 | |
| 	fieldType    fieldType
 | |
| 	numericVal   int64
 | |
| 	stringVal    string
 | |
| 	interfaceVal interface{}
 | |
| }
 | |
| 
 | |
| // String adds a string-valued key:value pair to a Span.LogFields() record
 | |
| func String(key, val string) Field {
 | |
| 	return Field{
 | |
| 		key:       key,
 | |
| 		fieldType: stringType,
 | |
| 		stringVal: val,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Bool adds a bool-valued key:value pair to a Span.LogFields() record
 | |
| func Bool(key string, val bool) Field {
 | |
| 	var numericVal int64
 | |
| 	if val {
 | |
| 		numericVal = 1
 | |
| 	}
 | |
| 	return Field{
 | |
| 		key:        key,
 | |
| 		fieldType:  boolType,
 | |
| 		numericVal: numericVal,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Int adds an int-valued key:value pair to a Span.LogFields() record
 | |
| func Int(key string, val int) Field {
 | |
| 	return Field{
 | |
| 		key:        key,
 | |
| 		fieldType:  intType,
 | |
| 		numericVal: int64(val),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Int32 adds an int32-valued key:value pair to a Span.LogFields() record
 | |
| func Int32(key string, val int32) Field {
 | |
| 	return Field{
 | |
| 		key:        key,
 | |
| 		fieldType:  int32Type,
 | |
| 		numericVal: int64(val),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Int64 adds an int64-valued key:value pair to a Span.LogFields() record
 | |
| func Int64(key string, val int64) Field {
 | |
| 	return Field{
 | |
| 		key:        key,
 | |
| 		fieldType:  int64Type,
 | |
| 		numericVal: val,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Uint32 adds a uint32-valued key:value pair to a Span.LogFields() record
 | |
| func Uint32(key string, val uint32) Field {
 | |
| 	return Field{
 | |
| 		key:        key,
 | |
| 		fieldType:  uint32Type,
 | |
| 		numericVal: int64(val),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Uint64 adds a uint64-valued key:value pair to a Span.LogFields() record
 | |
| func Uint64(key string, val uint64) Field {
 | |
| 	return Field{
 | |
| 		key:        key,
 | |
| 		fieldType:  uint64Type,
 | |
| 		numericVal: int64(val),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Float32 adds a float32-valued key:value pair to a Span.LogFields() record
 | |
| func Float32(key string, val float32) Field {
 | |
| 	return Field{
 | |
| 		key:        key,
 | |
| 		fieldType:  float32Type,
 | |
| 		numericVal: int64(math.Float32bits(val)),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Float64 adds a float64-valued key:value pair to a Span.LogFields() record
 | |
| func Float64(key string, val float64) Field {
 | |
| 	return Field{
 | |
| 		key:        key,
 | |
| 		fieldType:  float64Type,
 | |
| 		numericVal: int64(math.Float64bits(val)),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Error adds an error with the key "error.object" to a Span.LogFields() record
 | |
| func Error(err error) Field {
 | |
| 	return Field{
 | |
| 		key:          "error.object",
 | |
| 		fieldType:    errorType,
 | |
| 		interfaceVal: err,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Object adds an object-valued key:value pair to a Span.LogFields() record
 | |
| // Please pass in an immutable object, otherwise there may be concurrency issues.
 | |
| // Such as passing in the map, log.Object may result in "fatal error: concurrent map iteration and map write".
 | |
| // Because span is sent asynchronously, it is possible that this map will also be modified.
 | |
| func Object(key string, obj interface{}) Field {
 | |
| 	return Field{
 | |
| 		key:          key,
 | |
| 		fieldType:    objectType,
 | |
| 		interfaceVal: obj,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Event creates a string-valued Field for span logs with key="event" and value=val.
 | |
| func Event(val string) Field {
 | |
| 	return String("event", val)
 | |
| }
 | |
| 
 | |
| // Message creates a string-valued Field for span logs with key="message" and value=val.
 | |
| func Message(val string) Field {
 | |
| 	return String("message", val)
 | |
| }
 | |
| 
 | |
| // LazyLogger allows for user-defined, late-bound logging of arbitrary data
 | |
| type LazyLogger func(fv Encoder)
 | |
| 
 | |
| // Lazy adds a LazyLogger to a Span.LogFields() record; the tracing
 | |
| // implementation will call the LazyLogger function at an indefinite time in
 | |
| // the future (after Lazy() returns).
 | |
| func Lazy(ll LazyLogger) Field {
 | |
| 	return Field{
 | |
| 		fieldType:    lazyLoggerType,
 | |
| 		interfaceVal: ll,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Noop creates a no-op log field that should be ignored by the tracer.
 | |
| // It can be used to capture optional fields, for example those that should
 | |
| // only be logged in non-production environment:
 | |
| //
 | |
| //     func customerField(order *Order) log.Field {
 | |
| //          if os.Getenv("ENVIRONMENT") == "dev" {
 | |
| //              return log.String("customer", order.Customer.ID)
 | |
| //          }
 | |
| //          return log.Noop()
 | |
| //     }
 | |
| //
 | |
| //     span.LogFields(log.String("event", "purchase"), customerField(order))
 | |
| //
 | |
| func Noop() Field {
 | |
| 	return Field{
 | |
| 		fieldType: noopType,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Encoder allows access to the contents of a Field (via a call to
 | |
| // Field.Marshal).
 | |
| //
 | |
| // Tracer implementations typically provide an implementation of Encoder;
 | |
| // OpenTracing callers typically do not need to concern themselves with it.
 | |
| type Encoder interface {
 | |
| 	EmitString(key, value string)
 | |
| 	EmitBool(key string, value bool)
 | |
| 	EmitInt(key string, value int)
 | |
| 	EmitInt32(key string, value int32)
 | |
| 	EmitInt64(key string, value int64)
 | |
| 	EmitUint32(key string, value uint32)
 | |
| 	EmitUint64(key string, value uint64)
 | |
| 	EmitFloat32(key string, value float32)
 | |
| 	EmitFloat64(key string, value float64)
 | |
| 	EmitObject(key string, value interface{})
 | |
| 	EmitLazyLogger(value LazyLogger)
 | |
| }
 | |
| 
 | |
| // Marshal passes a Field instance through to the appropriate
 | |
| // field-type-specific method of an Encoder.
 | |
| func (lf Field) Marshal(visitor Encoder) {
 | |
| 	switch lf.fieldType {
 | |
| 	case stringType:
 | |
| 		visitor.EmitString(lf.key, lf.stringVal)
 | |
| 	case boolType:
 | |
| 		visitor.EmitBool(lf.key, lf.numericVal != 0)
 | |
| 	case intType:
 | |
| 		visitor.EmitInt(lf.key, int(lf.numericVal))
 | |
| 	case int32Type:
 | |
| 		visitor.EmitInt32(lf.key, int32(lf.numericVal))
 | |
| 	case int64Type:
 | |
| 		visitor.EmitInt64(lf.key, int64(lf.numericVal))
 | |
| 	case uint32Type:
 | |
| 		visitor.EmitUint32(lf.key, uint32(lf.numericVal))
 | |
| 	case uint64Type:
 | |
| 		visitor.EmitUint64(lf.key, uint64(lf.numericVal))
 | |
| 	case float32Type:
 | |
| 		visitor.EmitFloat32(lf.key, math.Float32frombits(uint32(lf.numericVal)))
 | |
| 	case float64Type:
 | |
| 		visitor.EmitFloat64(lf.key, math.Float64frombits(uint64(lf.numericVal)))
 | |
| 	case errorType:
 | |
| 		if err, ok := lf.interfaceVal.(error); ok {
 | |
| 			visitor.EmitString(lf.key, err.Error())
 | |
| 		} else {
 | |
| 			visitor.EmitString(lf.key, "<nil>")
 | |
| 		}
 | |
| 	case objectType:
 | |
| 		visitor.EmitObject(lf.key, lf.interfaceVal)
 | |
| 	case lazyLoggerType:
 | |
| 		visitor.EmitLazyLogger(lf.interfaceVal.(LazyLogger))
 | |
| 	case noopType:
 | |
| 		// intentionally left blank
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Key returns the field's key.
 | |
| func (lf Field) Key() string {
 | |
| 	return lf.key
 | |
| }
 | |
| 
 | |
| // Value returns the field's value as interface{}.
 | |
| func (lf Field) Value() interface{} {
 | |
| 	switch lf.fieldType {
 | |
| 	case stringType:
 | |
| 		return lf.stringVal
 | |
| 	case boolType:
 | |
| 		return lf.numericVal != 0
 | |
| 	case intType:
 | |
| 		return int(lf.numericVal)
 | |
| 	case int32Type:
 | |
| 		return int32(lf.numericVal)
 | |
| 	case int64Type:
 | |
| 		return int64(lf.numericVal)
 | |
| 	case uint32Type:
 | |
| 		return uint32(lf.numericVal)
 | |
| 	case uint64Type:
 | |
| 		return uint64(lf.numericVal)
 | |
| 	case float32Type:
 | |
| 		return math.Float32frombits(uint32(lf.numericVal))
 | |
| 	case float64Type:
 | |
| 		return math.Float64frombits(uint64(lf.numericVal))
 | |
| 	case errorType, objectType, lazyLoggerType:
 | |
| 		return lf.interfaceVal
 | |
| 	case noopType:
 | |
| 		return nil
 | |
| 	default:
 | |
| 		return nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // String returns a string representation of the key and value.
 | |
| func (lf Field) String() string {
 | |
| 	return fmt.Sprint(lf.key, ":", lf.Value())
 | |
| }
 |