875 lines
24 KiB
Go
875 lines
24 KiB
Go
package logger
|
|
|
|
import (
|
|
"api-soap-facturacion/internal/config"
|
|
"encoding/json"
|
|
"fmt"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/buffer"
|
|
"go.uber.org/zap/zapcore"
|
|
lumberjack "gopkg.in/natefinch/lumberjack.v2"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// Logger es una interfaz que define los métodos necesarios para el logging
|
|
type Logger interface {
|
|
Debug(msg string, fields ...Field)
|
|
Info(msg string, fields ...Field)
|
|
Warn(msg string, fields ...Field)
|
|
Error(msg string, fields ...Field)
|
|
Fatal(msg string, fields ...Field)
|
|
With(fields ...Field) Logger
|
|
}
|
|
|
|
// Field es un campo para agregar contexto a los logs
|
|
type Field struct {
|
|
Key string
|
|
Value interface{}
|
|
}
|
|
|
|
// zapLogger implementa la interfaz Logger usando zap
|
|
type zapLogger struct {
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// CustomEncoder implementa la interfaz zapcore.Encoder
|
|
type CustomEncoder struct {
|
|
zapcore.Encoder
|
|
pool buffer.Pool
|
|
serviceName string
|
|
}
|
|
|
|
// NewCustomEncoder crea un nuevo encoder personalizado
|
|
func NewCustomEncoder(cfg zapcore.EncoderConfig, serviceName string) zapcore.Encoder {
|
|
return &CustomEncoder{
|
|
Encoder: zapcore.NewJSONEncoder(cfg),
|
|
pool: buffer.NewPool(),
|
|
serviceName: serviceName,
|
|
}
|
|
}
|
|
|
|
// EncodeEntry implementa el formato personalizado
|
|
// EncodeEntry implementa el formato personalizado
|
|
func (e *CustomEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
|
|
line := e.pool.Get()
|
|
|
|
// Agregar nivel (INFO:, WARN:, etc.)
|
|
levelStr := entry.Level.CapitalString()
|
|
line.AppendString(levelStr)
|
|
line.AppendString(": ")
|
|
|
|
// Agregar timestamp
|
|
timestamp := entry.Time.Format("2006/01/02 15:04:05")
|
|
line.AppendString(timestamp)
|
|
line.AppendString(" ")
|
|
|
|
// Agregar información del archivo/línea si está disponible
|
|
if entry.Caller.Defined {
|
|
// Convertir la ruta a formato Unix para manejar uniformemente las barras
|
|
filePath := strings.ReplaceAll(entry.Caller.File, "\\", "/")
|
|
|
|
// Opciones para encontrar la parte relevante del path
|
|
possiblePrefixes := []string{
|
|
"/cmd/",
|
|
"/internal/",
|
|
"/pkg/",
|
|
"/api/",
|
|
"/app/",
|
|
"/src/",
|
|
}
|
|
|
|
// Buscar el prefijo más cercano al final del path
|
|
shortPath := filePath
|
|
for _, prefix := range possiblePrefixes {
|
|
if idx := strings.LastIndex(filePath, prefix); idx != -1 {
|
|
// Encontramos un prefijo estándar de Go
|
|
shortPath = filePath[idx+1:] // +1 para quitar el slash inicial
|
|
break
|
|
}
|
|
}
|
|
|
|
// Si no se encontró ningún prefijo, usar el último componente del path
|
|
if shortPath == filePath {
|
|
parts := strings.Split(filePath, "/")
|
|
if len(parts) > 0 {
|
|
shortPath = parts[len(parts)-1]
|
|
}
|
|
}
|
|
|
|
caller := fmt.Sprintf("%s:%d: ", shortPath, entry.Caller.Line)
|
|
line.AppendString(caller)
|
|
}
|
|
|
|
// Agregar nombre del servicio entre corchetes
|
|
line.AppendString("[")
|
|
line.AppendString(e.serviceName)
|
|
line.AppendString("] ")
|
|
|
|
// Agregar mensaje
|
|
line.AppendString(entry.Message)
|
|
|
|
// Procesar campos adicionales
|
|
if len(fields) > 0 {
|
|
// Usar encoder JSON para serializar los campos
|
|
encoder := zapcore.NewMapObjectEncoder()
|
|
|
|
// Agregar cada campo al encoder, excepto "service"
|
|
for _, field := range fields {
|
|
if field.Key != "service" {
|
|
field.AddTo(encoder)
|
|
}
|
|
}
|
|
|
|
// Solo mostramos los campos si hay alguno después de filtrar
|
|
if len(encoder.Fields) > 0 {
|
|
line.AppendString(" ")
|
|
fieldsJSON, err := json.Marshal(encoder.Fields)
|
|
if err == nil {
|
|
line.AppendString(string(fieldsJSON))
|
|
}
|
|
}
|
|
}
|
|
|
|
line.AppendString("\n")
|
|
return line, nil
|
|
}
|
|
|
|
//func (e *CustomEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
|
|
// line := e.pool.Get()
|
|
//
|
|
// // Agregar nivel (INFO:, WARN:, etc.)
|
|
// levelStr := entry.Level.CapitalString()
|
|
// line.AppendString(levelStr)
|
|
// line.AppendString(": ")
|
|
//
|
|
// // Agregar timestamp
|
|
// timestamp := entry.Time.Format("2006/01/02 15:04:05")
|
|
// line.AppendString(timestamp)
|
|
// line.AppendString(" ")
|
|
//
|
|
// // Agregar información del archivo/línea si está disponible
|
|
// if entry.Caller.Defined {
|
|
// // Obtener solo la parte relevante de la ruta (después del último "api-soap-facturacion")
|
|
// filePath := entry.Caller.File
|
|
// if idx := strings.LastIndex(filePath, "api-soap-facturacion"); idx != -1 {
|
|
// // Si encontramos la cadena, tomamos lo que viene después más "api-soap-facturacion"
|
|
// filePath = filePath[idx:]
|
|
// } else {
|
|
// // Si no encontramos la cadena, intentamos tomar solo el nombre del archivo
|
|
// if idx := strings.LastIndex(filePath, "/"); idx != -1 {
|
|
// filePath = filePath[idx+1:]
|
|
// } else if idx := strings.LastIndex(filePath, "\\"); idx != -1 {
|
|
// filePath = filePath[idx+1:]
|
|
// }
|
|
// }
|
|
//
|
|
// caller := fmt.Sprintf("%s:%d: ", filePath, entry.Caller.Line)
|
|
// line.AppendString(caller)
|
|
// }
|
|
// // Agregar nombre del servicio entre corchetes
|
|
// line.AppendString("[")
|
|
// line.AppendString(e.serviceName)
|
|
// line.AppendString("] ")
|
|
//
|
|
// // Agregar mensaje
|
|
// line.AppendString(entry.Message)
|
|
//
|
|
// // Procesar campos adicionales
|
|
// if len(fields) > 0 {
|
|
// // Usar encoder JSON para serializar los campos
|
|
// encoder := zapcore.NewMapObjectEncoder()
|
|
//
|
|
// // Agregar cada campo al encoder, excepto "service"
|
|
// for _, field := range fields {
|
|
// if field.Key != "service" {
|
|
// field.AddTo(encoder)
|
|
// }
|
|
// }
|
|
//
|
|
// // Solo mostramos los campos si hay alguno después de filtrar
|
|
// if len(encoder.Fields) > 0 {
|
|
// line.AppendString(" ")
|
|
// fieldsJSON, err := json.Marshal(encoder.Fields)
|
|
// if err == nil {
|
|
// line.AppendString(string(fieldsJSON))
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// line.AppendString("\n")
|
|
// return line, nil
|
|
//}
|
|
|
|
//func (e *CustomEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
|
|
// line := e.pool.Get()
|
|
//
|
|
// // Agregar nivel (INFO:, WARN:, etc.)
|
|
// levelStr := entry.Level.CapitalString()
|
|
// line.AppendString(levelStr)
|
|
// line.AppendString(": ")
|
|
//
|
|
// // Agregar timestamp
|
|
// timestamp := entry.Time.Format("2006/01/02 15:04:05")
|
|
// line.AppendString(timestamp)
|
|
// line.AppendString(" ")
|
|
//
|
|
// // Agregar información del archivo/línea si está disponible
|
|
// if entry.Caller.Defined {
|
|
// caller := fmt.Sprintf("%s:%d: ", entry.Caller.File, entry.Caller.Line)
|
|
// line.AppendString(caller)
|
|
// }
|
|
//
|
|
// // Agregar nombre del servicio entre corchetes
|
|
// line.AppendString("[")
|
|
// line.AppendString(e.serviceName)
|
|
// line.AppendString("] ")
|
|
//
|
|
// // Agregar mensaje
|
|
// line.AppendString(entry.Message)
|
|
//
|
|
// // Procesar campos adicionales
|
|
// if len(fields) > 0 {
|
|
// // Usar encoder JSON para serializar los campos
|
|
// encoder := zapcore.NewMapObjectEncoder()
|
|
//
|
|
// // Agregar cada campo al encoder, excepto "service"
|
|
// for _, field := range fields {
|
|
// if field.Key != "service" {
|
|
// field.AddTo(encoder)
|
|
// }
|
|
// }
|
|
//
|
|
// // Solo mostramos los campos si hay alguno después de filtrar
|
|
// if len(encoder.Fields) > 0 {
|
|
// line.AppendString(" ")
|
|
// fieldsJSON, err := json.Marshal(encoder.Fields)
|
|
// if err == nil {
|
|
// line.AppendString(string(fieldsJSON))
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// line.AppendString("\n")
|
|
// return line, nil
|
|
//}
|
|
|
|
// Clone implementa la interfaz Encoder
|
|
func (e *CustomEncoder) Clone() zapcore.Encoder {
|
|
return &CustomEncoder{
|
|
Encoder: e.Encoder.Clone(),
|
|
pool: e.pool,
|
|
serviceName: e.serviceName,
|
|
}
|
|
}
|
|
|
|
// NewLogger crea una nueva instancia de Logger
|
|
func NewLogger(cfg *config.Config) Logger {
|
|
// Configurar nivel de log
|
|
var level zapcore.Level
|
|
switch cfg.App.LogLevel {
|
|
case "debug":
|
|
level = zapcore.DebugLevel
|
|
case "info":
|
|
level = zapcore.InfoLevel
|
|
case "warn":
|
|
level = zapcore.WarnLevel
|
|
case "error":
|
|
level = zapcore.ErrorLevel
|
|
default:
|
|
level = zapcore.InfoLevel
|
|
}
|
|
|
|
// Configuración básica para el encoder
|
|
encoderConfig := zapcore.EncoderConfig{
|
|
TimeKey: "time",
|
|
LevelKey: "level",
|
|
NameKey: "logger",
|
|
CallerKey: "caller",
|
|
FunctionKey: zapcore.OmitKey,
|
|
MessageKey: "msg",
|
|
StacktraceKey: "stacktrace",
|
|
LineEnding: zapcore.DefaultLineEnding,
|
|
EncodeLevel: zapcore.CapitalLevelEncoder,
|
|
EncodeTime: zapcore.ISO8601TimeEncoder,
|
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
EncodeCaller: zapcore.ShortCallerEncoder,
|
|
}
|
|
|
|
// Crear el encoder personalizado
|
|
customEncoder := NewCustomEncoder(encoderConfig, cfg.App.Name)
|
|
|
|
// Configurar el output
|
|
var core zapcore.Core
|
|
if cfg.App.LogFilePath != "" {
|
|
// Si se usa archivo con lumberjack
|
|
logWriter := &lumberjack.Logger{
|
|
Filename: cfg.App.LogFilePath,
|
|
MaxSize: cfg.App.LogMaxSize,
|
|
MaxBackups: cfg.App.LogMaxBackups,
|
|
MaxAge: cfg.App.LogMaxAge,
|
|
Compress: cfg.App.LogCompress,
|
|
}
|
|
|
|
core = zapcore.NewCore(
|
|
customEncoder,
|
|
zapcore.AddSync(logWriter),
|
|
level,
|
|
)
|
|
} else {
|
|
// Solo usar stdout
|
|
core = zapcore.NewCore(
|
|
customEncoder,
|
|
zapcore.AddSync(os.Stdout),
|
|
level,
|
|
)
|
|
}
|
|
|
|
// Habilitar el caller para mostrar información del archivo y línea
|
|
zapLog := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
|
|
|
|
// Ya no agregamos el nombre del servicio como campo, ya que lo incluimos en el formato
|
|
// zapLog = zapLog.With(zap.String("service", cfg.App.Name))
|
|
|
|
return &zapLogger{logger: zapLog}
|
|
}
|
|
|
|
// NewField crea un campo para agregar a los logs
|
|
func NewField(key string, value interface{}) Field {
|
|
return Field{Key: key, Value: value}
|
|
}
|
|
|
|
// convertFields convierte nuestros campos a campos de zap
|
|
func (l *zapLogger) convertFields(fields []Field) []zap.Field {
|
|
zapFields := make([]zap.Field, len(fields))
|
|
for i, field := range fields {
|
|
zapFields[i] = zap.Any(field.Key, field.Value)
|
|
}
|
|
return zapFields
|
|
}
|
|
|
|
// Debug registra un mensaje con nivel Debug
|
|
func (l *zapLogger) Debug(msg string, fields ...Field) {
|
|
l.logger.Debug(msg, l.convertFields(fields)...)
|
|
}
|
|
|
|
// Info registra un mensaje con nivel Info
|
|
func (l *zapLogger) Info(msg string, fields ...Field) {
|
|
l.logger.Info(msg, l.convertFields(fields)...)
|
|
}
|
|
|
|
// Warn registra un mensaje con nivel Warn
|
|
func (l *zapLogger) Warn(msg string, fields ...Field) {
|
|
l.logger.Warn(msg, l.convertFields(fields)...)
|
|
}
|
|
|
|
// Error registra un mensaje con nivel Error
|
|
func (l *zapLogger) Error(msg string, fields ...Field) {
|
|
l.logger.Error(msg, l.convertFields(fields)...)
|
|
}
|
|
|
|
// Fatal registra un mensaje con nivel Fatal
|
|
func (l *zapLogger) Fatal(msg string, fields ...Field) {
|
|
l.logger.Fatal(msg, l.convertFields(fields)...)
|
|
}
|
|
|
|
// With retorna un nuevo logger con campos adicionales
|
|
func (l *zapLogger) With(fields ...Field) Logger {
|
|
return &zapLogger{
|
|
logger: l.logger.With(l.convertFields(fields)...),
|
|
}
|
|
}
|
|
|
|
//package logger
|
|
//
|
|
//import (
|
|
// "api-soap-facturacion/internal/config"
|
|
// "encoding/json"
|
|
// "fmt"
|
|
// "go.uber.org/zap"
|
|
// "go.uber.org/zap/zapcore"
|
|
// lumberjack "gopkg.in/natefinch/lumberjack.v2" // Usa este alias
|
|
// "os"
|
|
//)
|
|
//
|
|
//// Logger es una interfaz que define los métodos necesarios para el logging
|
|
//type Logger interface {
|
|
// Debug(msg string, fields ...Field)
|
|
// Info(msg string, fields ...Field)
|
|
// Warn(msg string, fields ...Field)
|
|
// Error(msg string, fields ...Field)
|
|
// Fatal(msg string, fields ...Field)
|
|
// With(fields ...Field) Logger
|
|
//}
|
|
//
|
|
//// Field es un campo para agregar contexto a los logs
|
|
//type Field struct {
|
|
// Key string
|
|
// Value interface{}
|
|
//}
|
|
//
|
|
//// zapLogger implementa la interfaz Logger usando zap
|
|
//type zapLogger struct {
|
|
// logger *zap.Logger
|
|
//}
|
|
//
|
|
//// CustomEncoder implementa la interfaz zapcore.Encoder
|
|
//type CustomEncoder struct {
|
|
// zapcore.Encoder
|
|
// pool buffer.Pool
|
|
// serviceName string
|
|
//}
|
|
//
|
|
//// NewCustomEncoder crea un nuevo encoder personalizado
|
|
//func NewCustomEncoder(cfg zapcore.EncoderConfig, serviceName string) zapcore.Encoder {
|
|
// return &CustomEncoder{
|
|
// Encoder: zapcore.NewJSONEncoder(cfg),
|
|
// pool: buffer.NewPool(),
|
|
// serviceName: serviceName,
|
|
// }
|
|
//}
|
|
//
|
|
//// EncodeEntry implementa el formato personalizado
|
|
//func (e *CustomEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
|
|
// line := e.pool.Get()
|
|
//
|
|
// // Agregar nivel (INFO:, WARN:, etc.)
|
|
// levelStr := entry.Level.CapitalString()
|
|
// line.AppendString(levelStr)
|
|
// line.AppendString(": ")
|
|
//
|
|
// // Agregar timestamp
|
|
// timestamp := entry.Time.Format("2006/01/02 15:04:05")
|
|
// line.AppendString(timestamp)
|
|
// line.AppendString(" ")
|
|
//
|
|
// // Agregar información del archivo/línea si está disponible
|
|
// if entry.Caller.Defined {
|
|
// caller := fmt.Sprintf("%s:%d: ", entry.Caller.File, entry.Caller.Line)
|
|
// line.AppendString(caller)
|
|
// }
|
|
//
|
|
// // Agregar nombre del servicio entre corchetes
|
|
// line.AppendString("[")
|
|
// line.AppendString(e.serviceName)
|
|
// line.AppendString("] ")
|
|
//
|
|
// // Agregar mensaje
|
|
// line.AppendString(entry.Message)
|
|
//
|
|
// // Procesar campos adicionales
|
|
// if len(fields) > 0 {
|
|
// line.AppendString(" ")
|
|
// fieldsMap := make(map[string]interface{})
|
|
// for _, field := range fields {
|
|
// if field.Key != "service" {
|
|
// field.AddTo(fieldsMap)
|
|
// }
|
|
// }
|
|
//
|
|
// if len(fieldsMap) > 0 {
|
|
// fieldJSON, err := json.Marshal(fieldsMap)
|
|
// if err == nil {
|
|
// line.AppendString(string(fieldJSON))
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// line.AppendString("\n")
|
|
// return line, nil
|
|
//}
|
|
//
|
|
//// Clone implementa la interfaz Encoder
|
|
//func (e *CustomEncoder) Clone() zapcore.Encoder {
|
|
// return &CustomEncoder{
|
|
// Encoder: e.Encoder.Clone(),
|
|
// pool: e.pool,
|
|
// serviceName: e.serviceName,
|
|
// }
|
|
//}
|
|
//
|
|
//// NewLogger crea una nueva instancia de Logger tipo json
|
|
////func NewLogger(cfg *config.Config) Logger {
|
|
//// // Configurar nivel de log
|
|
//// var level zapcore.Level
|
|
//// switch cfg.App.LogLevel {
|
|
//// case "debug":
|
|
//// level = zapcore.DebugLevel
|
|
//// case "info":
|
|
//// level = zapcore.InfoLevel
|
|
//// case "warn":
|
|
//// level = zapcore.WarnLevel
|
|
//// case "error":
|
|
//// level = zapcore.ErrorLevel
|
|
//// default:
|
|
//// level = zapcore.InfoLevel
|
|
//// }
|
|
////
|
|
//// // Configurar encoderConfig
|
|
//// encoderConfig := zapcore.EncoderConfig{
|
|
//// TimeKey: "time",
|
|
//// LevelKey: "level",
|
|
//// NameKey: "logger",
|
|
//// CallerKey: "caller",
|
|
//// MessageKey: "msg",
|
|
//// StacktraceKey: "stacktrace",
|
|
//// LineEnding: zapcore.DefaultLineEnding,
|
|
//// EncodeLevel: zapcore.LowercaseLevelEncoder,
|
|
//// EncodeTime: zapcore.ISO8601TimeEncoder,
|
|
//// EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
//// EncodeCaller: zapcore.ShortCallerEncoder,
|
|
//// }
|
|
////
|
|
//// // Crear escritores
|
|
//// var cores []zapcore.Core
|
|
////
|
|
//// // Siempre escribir a stdout
|
|
//// cores = append(cores, zapcore.NewCore(
|
|
//// zapcore.NewJSONEncoder(encoderConfig),
|
|
//// zapcore.AddSync(os.Stdout),
|
|
//// level,
|
|
//// ))
|
|
////
|
|
//// // Si se especificó una ruta de archivo de logs, configurar rotación
|
|
//// if cfg.App.LogFilePath != "" {
|
|
//// logWriter := &lumberjack.Logger{
|
|
//// Filename: cfg.App.LogFilePath,
|
|
//// MaxSize: cfg.App.LogMaxSize,
|
|
//// MaxBackups: cfg.App.LogMaxBackups,
|
|
//// MaxAge: cfg.App.LogMaxAge,
|
|
//// Compress: cfg.App.LogCompress,
|
|
//// }
|
|
////
|
|
//// cores = append(cores, zapcore.NewCore(
|
|
//// zapcore.NewJSONEncoder(encoderConfig),
|
|
//// zapcore.AddSync(logWriter),
|
|
//// level,
|
|
//// ))
|
|
//// }
|
|
////
|
|
//// // Combinar cores
|
|
//// core := zapcore.NewTee(cores...)
|
|
////
|
|
//// // Crear logger
|
|
//// zapLog := zap.New(core)
|
|
//// zapLog = zapLog.With(zap.String("service", cfg.App.Name))
|
|
////
|
|
//// return &zapLogger{logger: zapLog}
|
|
////}
|
|
//
|
|
//// fomato de texto mas flexible
|
|
//// NewLogger crea una nueva instancia de Logger
|
|
////func NewLogger(cfg *config.Config) Logger {
|
|
//// // Configurar nivel de log
|
|
//// var level zapcore.Level
|
|
//// switch cfg.App.LogLevel {
|
|
//// case "debug":
|
|
//// level = zapcore.DebugLevel
|
|
//// case "info":
|
|
//// level = zapcore.InfoLevel
|
|
//// case "warn":
|
|
//// level = zapcore.WarnLevel
|
|
//// case "error":
|
|
//// level = zapcore.ErrorLevel
|
|
//// default:
|
|
//// level = zapcore.InfoLevel
|
|
//// }
|
|
////
|
|
//// // Configurar encoderConfig para un formato más legible
|
|
//// encoderConfig := zapcore.EncoderConfig{
|
|
//// TimeKey: "time",
|
|
//// LevelKey: "level",
|
|
//// NameKey: "logger",
|
|
//// CallerKey: "caller",
|
|
//// FunctionKey: zapcore.OmitKey,
|
|
//// MessageKey: "msg",
|
|
//// StacktraceKey: "stacktrace",
|
|
//// LineEnding: zapcore.DefaultLineEnding,
|
|
//// EncodeLevel: zapcore.CapitalLevelEncoder, // INFO en lugar de info
|
|
//// EncodeTime: zapcore.TimeEncoderOfLayout("2006/01/02 15:04:05"), // Formato como 2025/05/15 00:13:07
|
|
//// EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
//// EncodeCaller: zapcore.ShortCallerEncoder,
|
|
//// }
|
|
////
|
|
//// // Crear un formato personalizado
|
|
//// consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
|
|
////
|
|
//// // Configurar el output final
|
|
//// var core zapcore.Core
|
|
//// if cfg.App.LogFilePath != "" && cfg.App.UseFileLogger {
|
|
//// // Si se usa archivo con lumberjack
|
|
//// logWriter := &lumberjack.Logger{
|
|
//// Filename: cfg.App.LogFilePath,
|
|
//// MaxSize: cfg.App.LogMaxSize,
|
|
//// MaxBackups: cfg.App.LogMaxBackups,
|
|
//// MaxAge: cfg.App.LogMaxAge,
|
|
//// Compress: cfg.App.LogCompress,
|
|
//// }
|
|
////
|
|
//// core = zapcore.NewCore(
|
|
//// consoleEncoder,
|
|
//// zapcore.AddSync(logWriter),
|
|
//// level,
|
|
//// )
|
|
//// } else {
|
|
//// // Solo usar stdout
|
|
//// core = zapcore.NewCore(
|
|
//// consoleEncoder,
|
|
//// zapcore.AddSync(os.Stdout),
|
|
//// level,
|
|
//// )
|
|
//// }
|
|
////
|
|
//// // Habilitar el caller para mostrar información del archivo y línea
|
|
//// zapLog := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
|
|
////
|
|
//// // Agregar nombre del servicio como prefijo constante
|
|
//// zapLog = zapLog.With(zap.String("service", cfg.App.Name))
|
|
////
|
|
//// return &zapLogger{logger: zapLog}
|
|
////}
|
|
//
|
|
//// NewLogger crea una nueva instancia de Logger
|
|
//func NewLogger(cfg *config.Config) Logger {
|
|
// // Configurar nivel de log
|
|
// var level zapcore.Level
|
|
// switch cfg.App.LogLevel {
|
|
// case "debug":
|
|
// level = zapcore.DebugLevel
|
|
// case "info":
|
|
// level = zapcore.InfoLevel
|
|
// case "warn":
|
|
// level = zapcore.WarnLevel
|
|
// case "error":
|
|
// level = zapcore.ErrorLevel
|
|
// default:
|
|
// level = zapcore.InfoLevel
|
|
// }
|
|
//
|
|
// // Configuración básica para el encoder
|
|
// encoderConfig := zapcore.EncoderConfig{
|
|
// TimeKey: "time",
|
|
// LevelKey: "level",
|
|
// NameKey: "logger",
|
|
// CallerKey: "caller",
|
|
// FunctionKey: zapcore.OmitKey,
|
|
// MessageKey: "msg",
|
|
// StacktraceKey: "stacktrace",
|
|
// LineEnding: zapcore.DefaultLineEnding,
|
|
// EncodeLevel: zapcore.CapitalLevelEncoder,
|
|
// EncodeTime: zapcore.ISO8601TimeEncoder,
|
|
// EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
// EncodeCaller: zapcore.ShortCallerEncoder,
|
|
// }
|
|
//
|
|
// // Crear el encoder personalizado
|
|
// customEncoder := NewCustomEncoder(encoderConfig, cfg.App.Name)
|
|
//
|
|
// // Configurar el output
|
|
// var core zapcore.Core
|
|
// if cfg.App.LogFilePath != "" {
|
|
// // Si se usa archivo con lumberjack
|
|
// logWriter := &lumberjack.Logger{
|
|
// Filename: cfg.App.LogFilePath,
|
|
// MaxSize: cfg.App.LogMaxSize,
|
|
// MaxBackups: cfg.App.LogMaxBackups,
|
|
// MaxAge: cfg.App.LogMaxAge,
|
|
// Compress: cfg.App.LogCompress,
|
|
// }
|
|
//
|
|
// core = zapcore.NewCore(
|
|
// customEncoder,
|
|
// zapcore.AddSync(logWriter),
|
|
// level,
|
|
// )
|
|
// } else {
|
|
// // Solo usar stdout
|
|
// core = zapcore.NewCore(
|
|
// customEncoder,
|
|
// zapcore.AddSync(os.Stdout),
|
|
// level,
|
|
// )
|
|
// }
|
|
//
|
|
// // Habilitar el caller para mostrar información del archivo y línea
|
|
// zapLog := zap.New(core, zap.AddCaller())
|
|
//
|
|
// // Ya no agregamos el nombre del servicio como campo, ya que lo incluimos en el formato
|
|
// // zapLog = zapLog.With(zap.String("service", cfg.App.Name))
|
|
//
|
|
// return &zapLogger{logger: zapLog}
|
|
//}
|
|
//
|
|
//// NewField crea un campo para agregar a los logs
|
|
//func NewField(key string, value interface{}) Field {
|
|
// return Field{Key: key, Value: value}
|
|
//}
|
|
//
|
|
//// convertFields convierte nuestros campos a campos de zap
|
|
//func (l *zapLogger) convertFields(fields []Field) []zap.Field {
|
|
// zapFields := make([]zap.Field, len(fields))
|
|
// for i, field := range fields {
|
|
// zapFields[i] = zap.Any(field.Key, field.Value)
|
|
// }
|
|
// return zapFields
|
|
//}
|
|
//
|
|
//// Debug registra un mensaje con nivel Debug
|
|
//func (l *zapLogger) Debug(msg string, fields ...Field) {
|
|
// l.logger.Debug(msg, l.convertFields(fields)...)
|
|
//}
|
|
//
|
|
//// Info registra un mensaje con nivel Info
|
|
//func (l *zapLogger) Info(msg string, fields ...Field) {
|
|
// l.logger.Info(msg, l.convertFields(fields)...)
|
|
//}
|
|
//
|
|
//// Warn registra un mensaje con nivel Warn
|
|
//func (l *zapLogger) Warn(msg string, fields ...Field) {
|
|
// l.logger.Warn(msg, l.convertFields(fields)...)
|
|
//}
|
|
//
|
|
//// Error registra un mensaje con nivel Error
|
|
//func (l *zapLogger) Error(msg string, fields ...Field) {
|
|
// l.logger.Error(msg, l.convertFields(fields)...)
|
|
//}
|
|
//
|
|
//// Fatal registra un mensaje con nivel Fatal
|
|
//func (l *zapLogger) Fatal(msg string, fields ...Field) {
|
|
// l.logger.Fatal(msg, l.convertFields(fields)...)
|
|
//}
|
|
//
|
|
//// With retorna un nuevo logger con campos adicionales
|
|
////
|
|
//// func (l *zapLogger) With(fields ...Field) Logger {
|
|
//// return &zapLogger{
|
|
//// logger: l.logger.With(l.convertFields(fields)...),
|
|
//// }
|
|
//// }
|
|
//func (l *zapLogger) With(fields ...Field) Logger {
|
|
// return &zapLogger{
|
|
// logger: l.logger.With(l.convertFields(fields)...),
|
|
// }
|
|
//}
|
|
//
|
|
////package logger
|
|
////
|
|
////import (
|
|
//// "api-soap-facturacion/internal/config"
|
|
//// "go.uber.org/zap"
|
|
//// "go.uber.org/zap/zapcore"
|
|
////)
|
|
////
|
|
////// Logger es una interfaz que define los métodos necesarios para el logging
|
|
////type Logger interface {
|
|
//// Debug(msg string, fields ...Field)
|
|
//// Info(msg string, fields ...Field)
|
|
//// Warn(msg string, fields ...Field)
|
|
//// Error(msg string, fields ...Field)
|
|
//// Fatal(msg string, fields ...Field)
|
|
//// With(fields ...Field) Logger
|
|
////}
|
|
////
|
|
////// Field es un campo para agregar contexto a los logs
|
|
////type Field struct {
|
|
//// Key string
|
|
//// Value interface{}
|
|
////}
|
|
////
|
|
////// zapLogger implementa la interfaz Logger usando zap
|
|
////type zapLogger struct {
|
|
//// logger *zap.Logger
|
|
////}
|
|
////
|
|
////// NewLogger crea una nueva instancia de Logger
|
|
////func NewLogger(cfg *config.Config) Logger {
|
|
//// // Configurar nivel de log
|
|
//// var level zapcore.Level
|
|
//// switch cfg.App.LogLevel {
|
|
//// case "debug":
|
|
//// level = zapcore.DebugLevel
|
|
//// case "info":
|
|
//// level = zapcore.InfoLevel
|
|
//// case "warn":
|
|
//// level = zapcore.WarnLevel
|
|
//// case "error":
|
|
//// level = zapcore.ErrorLevel
|
|
//// default:
|
|
//// level = zapcore.InfoLevel
|
|
//// }
|
|
////
|
|
//// // Configuración de zap
|
|
//// zapConfig := zap.Config{
|
|
//// Level: zap.NewAtomicLevelAt(level),
|
|
//// Development: cfg.App.Environment == "development",
|
|
//// Encoding: "json",
|
|
//// OutputPaths: []string{"stdout"},
|
|
//// ErrorOutputPaths: []string{"stderr"},
|
|
//// EncoderConfig: zapcore.EncoderConfig{
|
|
//// TimeKey: "time",
|
|
//// LevelKey: "level",
|
|
//// NameKey: "logger",
|
|
//// CallerKey: "caller",
|
|
//// MessageKey: "msg",
|
|
//// StacktraceKey: "stacktrace",
|
|
//// LineEnding: zapcore.DefaultLineEnding,
|
|
//// EncodeLevel: zapcore.LowercaseLevelEncoder,
|
|
//// EncodeTime: zapcore.ISO8601TimeEncoder,
|
|
//// EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
//// EncodeCaller: zapcore.ShortCallerEncoder,
|
|
//// },
|
|
//// }
|
|
////
|
|
//// // Agregar service name a todos los logs
|
|
//// logger, _ := zapConfig.Build()
|
|
//// logger = logger.With(zap.String("service", cfg.App.Name))
|
|
////
|
|
//// return &zapLogger{logger: logger}
|
|
////}
|
|
////
|
|
////// NewField crea un campo para agregar a los logs
|
|
////func NewField(key string, value interface{}) Field {
|
|
//// return Field{Key: key, Value: value}
|
|
////}
|
|
////
|
|
////// convertFields convierte nuestros campos a campos de zap
|
|
////func (l *zapLogger) convertFields(fields []Field) []zap.Field {
|
|
//// zapFields := make([]zap.Field, len(fields))
|
|
//// for i, field := range fields {
|
|
//// zapFields[i] = zap.Any(field.Key, field.Value)
|
|
//// }
|
|
//// return zapFields
|
|
////}
|
|
////
|
|
////// Debug registra un mensaje con nivel Debug
|
|
////func (l *zapLogger) Debug(msg string, fields ...Field) {
|
|
//// l.logger.Debug(msg, l.convertFields(fields)...)
|
|
////}
|
|
////
|
|
////// Info registra un mensaje con nivel Info
|
|
////func (l *zapLogger) Info(msg string, fields ...Field) {
|
|
//// l.logger.Info(msg, l.convertFields(fields)...)
|
|
////}
|
|
////
|
|
////// Warn registra un mensaje con nivel Warn
|
|
////func (l *zapLogger) Warn(msg string, fields ...Field) {
|
|
//// l.logger.Warn(msg, l.convertFields(fields)...)
|
|
////}
|
|
////
|
|
////// Error registra un mensaje con nivel Error
|
|
////func (l *zapLogger) Error(msg string, fields ...Field) {
|
|
//// l.logger.Error(msg, l.convertFields(fields)...)
|
|
////}
|
|
////
|
|
////// Fatal registra un mensaje con nivel Fatal
|
|
////func (l *zapLogger) Fatal(msg string, fields ...Field) {
|
|
//// l.logger.Fatal(msg, l.convertFields(fields)...)
|
|
////}
|
|
////
|
|
////// With retorna un nuevo logger con campos adicionales
|
|
////func (l *zapLogger) With(fields ...Field) Logger {
|
|
//// return &zapLogger{
|
|
//// logger: l.logger.With(l.convertFields(fields)...),
|
|
//// }
|
|
////}
|