Integrate BACKBEAT SDK and resolve KACHING license validation
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>
This commit is contained in:
@@ -1,210 +0,0 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Logger interface for CHORUS logging
|
||||
type Logger interface {
|
||||
Info(msg string, args ...interface{})
|
||||
Warn(msg string, args ...interface{})
|
||||
Error(msg string, args ...interface{})
|
||||
Debug(msg string, args ...interface{})
|
||||
}
|
||||
|
||||
// ContainerLogger provides structured logging optimized for container environments
|
||||
// All logs go to stdout/stderr for collection by container runtime (Docker, K8s, etc.)
|
||||
type ContainerLogger struct {
|
||||
name string
|
||||
level LogLevel
|
||||
format LogFormat
|
||||
}
|
||||
|
||||
// LogLevel represents logging levels
|
||||
type LogLevel int
|
||||
|
||||
const (
|
||||
DEBUG LogLevel = iota
|
||||
INFO
|
||||
WARN
|
||||
ERROR
|
||||
)
|
||||
|
||||
// LogFormat represents log output formats
|
||||
type LogFormat int
|
||||
|
||||
const (
|
||||
STRUCTURED LogFormat = iota // JSON structured logging
|
||||
HUMAN // Human-readable logging
|
||||
)
|
||||
|
||||
// LogEntry represents a structured log entry
|
||||
type LogEntry struct {
|
||||
Timestamp string `json:"timestamp"`
|
||||
Level string `json:"level"`
|
||||
Service string `json:"service"`
|
||||
Message string `json:"message"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// NewContainerLogger creates a new container-optimized logger
|
||||
func NewContainerLogger(serviceName string) *ContainerLogger {
|
||||
level := INFO
|
||||
format := STRUCTURED
|
||||
|
||||
// Parse log level from environment
|
||||
if levelStr := os.Getenv("LOG_LEVEL"); levelStr != "" {
|
||||
switch levelStr {
|
||||
case "debug":
|
||||
level = DEBUG
|
||||
case "info":
|
||||
level = INFO
|
||||
case "warn":
|
||||
level = WARN
|
||||
case "error":
|
||||
level = ERROR
|
||||
}
|
||||
}
|
||||
|
||||
// Parse log format from environment
|
||||
if formatStr := os.Getenv("LOG_FORMAT"); formatStr == "human" {
|
||||
format = HUMAN
|
||||
}
|
||||
|
||||
return &ContainerLogger{
|
||||
name: serviceName,
|
||||
level: level,
|
||||
format: format,
|
||||
}
|
||||
}
|
||||
|
||||
// Info logs informational messages
|
||||
func (l *ContainerLogger) Info(msg string, args ...interface{}) {
|
||||
if l.level <= INFO {
|
||||
l.log(INFO, msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Warn logs warning messages
|
||||
func (l *ContainerLogger) Warn(msg string, args ...interface{}) {
|
||||
if l.level <= WARN {
|
||||
l.log(WARN, msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Error logs error messages to stderr
|
||||
func (l *ContainerLogger) Error(msg string, args ...interface{}) {
|
||||
if l.level <= ERROR {
|
||||
l.logToStderr(ERROR, msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Debug logs debug messages (only when DEBUG level is enabled)
|
||||
func (l *ContainerLogger) Debug(msg string, args ...interface{}) {
|
||||
if l.level <= DEBUG {
|
||||
l.log(DEBUG, msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// log writes log entries to stdout
|
||||
func (l *ContainerLogger) log(level LogLevel, msg string, args ...interface{}) {
|
||||
entry := l.createLogEntry(level, msg, args...)
|
||||
|
||||
switch l.format {
|
||||
case STRUCTURED:
|
||||
l.writeJSON(os.Stdout, entry)
|
||||
case HUMAN:
|
||||
l.writeHuman(os.Stdout, entry)
|
||||
}
|
||||
}
|
||||
|
||||
// logToStderr writes log entries to stderr (for errors)
|
||||
func (l *ContainerLogger) logToStderr(level LogLevel, msg string, args ...interface{}) {
|
||||
entry := l.createLogEntry(level, msg, args...)
|
||||
|
||||
switch l.format {
|
||||
case STRUCTURED:
|
||||
l.writeJSON(os.Stderr, entry)
|
||||
case HUMAN:
|
||||
l.writeHuman(os.Stderr, entry)
|
||||
}
|
||||
}
|
||||
|
||||
// createLogEntry creates a structured log entry
|
||||
func (l *ContainerLogger) createLogEntry(level LogLevel, msg string, args ...interface{}) LogEntry {
|
||||
return LogEntry{
|
||||
Timestamp: time.Now().UTC().Format(time.RFC3339Nano),
|
||||
Level: l.levelToString(level),
|
||||
Service: l.name,
|
||||
Message: fmt.Sprintf(msg, args...),
|
||||
Data: make(map[string]interface{}),
|
||||
}
|
||||
}
|
||||
|
||||
// writeJSON writes the log entry as JSON
|
||||
func (l *ContainerLogger) writeJSON(output *os.File, entry LogEntry) {
|
||||
if jsonData, err := json.Marshal(entry); err == nil {
|
||||
fmt.Fprintln(output, string(jsonData))
|
||||
}
|
||||
}
|
||||
|
||||
// writeHuman writes the log entry in human-readable format
|
||||
func (l *ContainerLogger) writeHuman(output *os.File, entry LogEntry) {
|
||||
fmt.Fprintf(output, "[%s] [%s] [%s] %s\n",
|
||||
entry.Timestamp,
|
||||
entry.Level,
|
||||
entry.Service,
|
||||
entry.Message,
|
||||
)
|
||||
}
|
||||
|
||||
// levelToString converts LogLevel to string
|
||||
func (l *ContainerLogger) levelToString(level LogLevel) string {
|
||||
switch level {
|
||||
case DEBUG:
|
||||
return "DEBUG"
|
||||
case INFO:
|
||||
return "INFO"
|
||||
case WARN:
|
||||
return "WARN"
|
||||
case ERROR:
|
||||
return "ERROR"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
// WithData creates a logger that includes additional structured data in log entries
|
||||
func (l *ContainerLogger) WithData(data map[string]interface{}) Logger {
|
||||
// Return a new logger instance that includes the data
|
||||
// This is useful for request-scoped logging with context
|
||||
return &dataLogger{
|
||||
base: l,
|
||||
data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// dataLogger is a wrapper that adds structured data to log entries
|
||||
type dataLogger struct {
|
||||
base Logger
|
||||
data map[string]interface{}
|
||||
}
|
||||
|
||||
func (d *dataLogger) Info(msg string, args ...interface{}) {
|
||||
d.base.Info(msg, args...)
|
||||
}
|
||||
|
||||
func (d *dataLogger) Warn(msg string, args ...interface{}) {
|
||||
d.base.Warn(msg, args...)
|
||||
}
|
||||
|
||||
func (d *dataLogger) Error(msg string, args ...interface{}) {
|
||||
d.base.Error(msg, args...)
|
||||
}
|
||||
|
||||
func (d *dataLogger) Debug(msg string, args ...interface{}) {
|
||||
d.base.Debug(msg, args...)
|
||||
}
|
||||
Reference in New Issue
Block a user