package customlogger import ( "context" "fmt" "log/slog" "os" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) var LogLevels = map[string]slog.Level{ "debug": slog.LevelDebug, "info": slog.LevelInfo, "warn": slog.LevelWarn, "error": slog.LevelError, } var Environment = map[string]string{ "dev": "development", "prod": "production", } func NewLogger(env string, lvl slog.Level) *slog.Logger { var logHandler slog.Handler err := os.MkdirAll("logs", os.ModePerm) if err != nil { panic("Failed to create log directory: " + err.Error()) } file, err := os.OpenFile("logs/app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { panic("Failed to open log file: " + err.Error()) } switch env { case "development": logHandler = slog.NewTextHandler(file, &slog.HandlerOptions{ Level: lvl, }) default: logHandler = slog.NewJSONHandler(file, &slog.HandlerOptions{ Level: lvl, }) } logger := slog.New(logHandler).With(slog.Group( "service_info", slog.String("env", env), ), ) return logger } // MongoLogger wraps a MongoDB connection and logger type MongoLogger struct { client *mongo.Client collection *mongo.Collection } // NewMongoLogger creates a new MongoDB-connected logger func NewMongoLogger(mongoURI, dbName, collectionName string) (*MongoLogger, error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // 1. Connect to MongoDB with retries client, err := mongo.Connect(ctx, options.Client(). ApplyURI(mongoURI). SetServerAPIOptions(options.ServerAPI(options.ServerAPIVersion1)), ) if err != nil { return nil, fmt.Errorf("MongoDB connection failed: %w", err) } // 2. Verify connection err = client.Ping(ctx, nil) if err != nil { return nil, fmt.Errorf("MongoDB ping failed: %w", err) } // 3. Get collection handle coll := client.Database(dbName).Collection(collectionName) return &MongoLogger{ client: client, collection: coll, }, nil } // Log writes a log entry to MongoDB func (ml *MongoLogger) Log(level, message string, attrs map[string]interface{}) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() _, err := ml.collection.InsertOne(ctx, bson.M{ "timestamp": time.Now(), "level": level, "message": message, "attrs": attrs, }) return err } // Close safely disconnects from MongoDB func (ml *MongoLogger) Close() error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() return ml.client.Disconnect(ctx) }