 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>
		
			
				
	
	
		
			170 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) 2016 Uber Technologies, Inc.
 | |
| //
 | |
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 | |
| // of this software and associated documentation files (the "Software"), to deal
 | |
| // in the Software without restriction, including without limitation the rights
 | |
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | |
| // copies of the Software, and to permit persons to whom the Software is
 | |
| // furnished to do so, subject to the following conditions:
 | |
| //
 | |
| // The above copyright notice and this permission notice shall be included in
 | |
| // all copies or substantial portions of the Software.
 | |
| //
 | |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | |
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | |
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | |
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | |
| // THE SOFTWARE.
 | |
| 
 | |
| package zap
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"fmt"
 | |
| 	"log"
 | |
| 	"os"
 | |
| 	"sync"
 | |
| 
 | |
| 	"go.uber.org/zap/zapcore"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	_stdLogDefaultDepth      = 1
 | |
| 	_loggerWriterDepth       = 2
 | |
| 	_programmerErrorTemplate = "You've found a bug in zap! Please file a bug at " +
 | |
| 		"https://github.com/uber-go/zap/issues/new and reference this error: %v"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	_globalMu sync.RWMutex
 | |
| 	_globalL  = NewNop()
 | |
| 	_globalS  = _globalL.Sugar()
 | |
| )
 | |
| 
 | |
| // L returns the global Logger, which can be reconfigured with ReplaceGlobals.
 | |
| // It's safe for concurrent use.
 | |
| func L() *Logger {
 | |
| 	_globalMu.RLock()
 | |
| 	l := _globalL
 | |
| 	_globalMu.RUnlock()
 | |
| 	return l
 | |
| }
 | |
| 
 | |
| // S returns the global SugaredLogger, which can be reconfigured with
 | |
| // ReplaceGlobals. It's safe for concurrent use.
 | |
| func S() *SugaredLogger {
 | |
| 	_globalMu.RLock()
 | |
| 	s := _globalS
 | |
| 	_globalMu.RUnlock()
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // ReplaceGlobals replaces the global Logger and SugaredLogger, and returns a
 | |
| // function to restore the original values. It's safe for concurrent use.
 | |
| func ReplaceGlobals(logger *Logger) func() {
 | |
| 	_globalMu.Lock()
 | |
| 	prev := _globalL
 | |
| 	_globalL = logger
 | |
| 	_globalS = logger.Sugar()
 | |
| 	_globalMu.Unlock()
 | |
| 	return func() { ReplaceGlobals(prev) }
 | |
| }
 | |
| 
 | |
| // NewStdLog returns a *log.Logger which writes to the supplied zap Logger at
 | |
| // InfoLevel. To redirect the standard library's package-global logging
 | |
| // functions, use RedirectStdLog instead.
 | |
| func NewStdLog(l *Logger) *log.Logger {
 | |
| 	logger := l.WithOptions(AddCallerSkip(_stdLogDefaultDepth + _loggerWriterDepth))
 | |
| 	f := logger.Info
 | |
| 	return log.New(&loggerWriter{f}, "" /* prefix */, 0 /* flags */)
 | |
| }
 | |
| 
 | |
| // NewStdLogAt returns *log.Logger which writes to supplied zap logger at
 | |
| // required level.
 | |
| func NewStdLogAt(l *Logger, level zapcore.Level) (*log.Logger, error) {
 | |
| 	logger := l.WithOptions(AddCallerSkip(_stdLogDefaultDepth + _loggerWriterDepth))
 | |
| 	logFunc, err := levelToFunc(logger, level)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return log.New(&loggerWriter{logFunc}, "" /* prefix */, 0 /* flags */), nil
 | |
| }
 | |
| 
 | |
| // RedirectStdLog redirects output from the standard library's package-global
 | |
| // logger to the supplied logger at InfoLevel. Since zap already handles caller
 | |
| // annotations, timestamps, etc., it automatically disables the standard
 | |
| // library's annotations and prefixing.
 | |
| //
 | |
| // It returns a function to restore the original prefix and flags and reset the
 | |
| // standard library's output to os.Stderr.
 | |
| func RedirectStdLog(l *Logger) func() {
 | |
| 	f, err := redirectStdLogAt(l, InfoLevel)
 | |
| 	if err != nil {
 | |
| 		// Can't get here, since passing InfoLevel to redirectStdLogAt always
 | |
| 		// works.
 | |
| 		panic(fmt.Sprintf(_programmerErrorTemplate, err))
 | |
| 	}
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| // RedirectStdLogAt redirects output from the standard library's package-global
 | |
| // logger to the supplied logger at the specified level. Since zap already
 | |
| // handles caller annotations, timestamps, etc., it automatically disables the
 | |
| // standard library's annotations and prefixing.
 | |
| //
 | |
| // It returns a function to restore the original prefix and flags and reset the
 | |
| // standard library's output to os.Stderr.
 | |
| func RedirectStdLogAt(l *Logger, level zapcore.Level) (func(), error) {
 | |
| 	return redirectStdLogAt(l, level)
 | |
| }
 | |
| 
 | |
| func redirectStdLogAt(l *Logger, level zapcore.Level) (func(), error) {
 | |
| 	flags := log.Flags()
 | |
| 	prefix := log.Prefix()
 | |
| 	log.SetFlags(0)
 | |
| 	log.SetPrefix("")
 | |
| 	logger := l.WithOptions(AddCallerSkip(_stdLogDefaultDepth + _loggerWriterDepth))
 | |
| 	logFunc, err := levelToFunc(logger, level)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	log.SetOutput(&loggerWriter{logFunc})
 | |
| 	return func() {
 | |
| 		log.SetFlags(flags)
 | |
| 		log.SetPrefix(prefix)
 | |
| 		log.SetOutput(os.Stderr)
 | |
| 	}, nil
 | |
| }
 | |
| 
 | |
| func levelToFunc(logger *Logger, lvl zapcore.Level) (func(string, ...Field), error) {
 | |
| 	switch lvl {
 | |
| 	case DebugLevel:
 | |
| 		return logger.Debug, nil
 | |
| 	case InfoLevel:
 | |
| 		return logger.Info, nil
 | |
| 	case WarnLevel:
 | |
| 		return logger.Warn, nil
 | |
| 	case ErrorLevel:
 | |
| 		return logger.Error, nil
 | |
| 	case DPanicLevel:
 | |
| 		return logger.DPanic, nil
 | |
| 	case PanicLevel:
 | |
| 		return logger.Panic, nil
 | |
| 	case FatalLevel:
 | |
| 		return logger.Fatal, nil
 | |
| 	}
 | |
| 	return nil, fmt.Errorf("unrecognized level: %q", lvl)
 | |
| }
 | |
| 
 | |
| type loggerWriter struct {
 | |
| 	logFunc func(msg string, fields ...Field)
 | |
| }
 | |
| 
 | |
| func (l *loggerWriter) Write(p []byte) (int, error) {
 | |
| 	p = bytes.TrimSpace(p)
 | |
| 	l.logFunc(string(p))
 | |
| 	return len(p), nil
 | |
| }
 |