package mongoLogger import ( "context" "fmt" "time" "maps" "github.com/SamuelTariku/FortuneBet-Backend/internal/config" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.uber.org/zap/zapcore" ) type MongoCore struct { collection *mongo.Collection level zapcore.Level fields []zapcore.Field cfg *config.Config } func NewMongoCore(uri, dbName, collectionName string, level zapcore.Level) (zapcore.Core, error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) if err != nil { return nil, err } if err := client.Ping(ctx, nil); err != nil { return nil, fmt.Errorf("unable to connect to MongoDB: %w", err) } coll := client.Database(dbName).Collection(collectionName) return &MongoCore{ collection: coll, level: level, }, nil } func (mc *MongoCore) Enabled(lvl zapcore.Level) bool { return lvl >= mc.level } func (mc *MongoCore) With(fields []zapcore.Field) zapcore.Core { clone := *mc clone.fields = append(clone.fields, fields...) return &clone } func (mc *MongoCore) Check(entry zapcore.Entry, checkedEntry *zapcore.CheckedEntry) *zapcore.CheckedEntry { if mc.Enabled(entry.Level) { return checkedEntry.AddCore(entry, mc) } return checkedEntry } func (mc *MongoCore) Write(entry zapcore.Entry, fields []zapcore.Field) error { logMap := make(map[string]interface{}) enc := zapcore.NewMapObjectEncoder() for _, f := range append(mc.fields, fields...) { f.AddTo(enc) } maps.Copy(logMap, enc.Fields) doc := bson.M{ "level": entry.Level.String(), "message": entry.Message, "timestamp": entry.Time.UTC().Format(time.RFC3339Nano), "fields": logMap, "caller": entry.Caller.String(), "stacktrace": entry.Stack, "service": mc.cfg.Service, "env": mc.cfg.Env, } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() _, err := mc.collection.InsertOne(ctx, doc) return err } func (mc *MongoCore) Sync() error { return nil }