185 lines
4.5 KiB
Go
185 lines
4.5 KiB
Go
// File: /home/meninjar/goprint/service/internal/infrastructure/monitoring/repository_wrapper.go
|
|
package monitoring
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"service/pkg/logger"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// GormDBWrapper wraps GORM DB with metrics collection
|
|
type GormDBWrapper struct {
|
|
*gorm.DB
|
|
metrics *Metrics
|
|
database string
|
|
logger logger.Logger
|
|
}
|
|
|
|
// NewGormDBWrapper creates a new GORM wrapper with metrics
|
|
func NewGormDBWrapper(db *gorm.DB, metrics *Metrics, database string) *GormDBWrapper {
|
|
log := logger.Default().WithFields(
|
|
logger.String("component", "gorm_wrapper"),
|
|
logger.String("database", database),
|
|
)
|
|
|
|
return &GormDBWrapper{
|
|
DB: db,
|
|
metrics: metrics,
|
|
database: database,
|
|
logger: log,
|
|
}
|
|
}
|
|
|
|
// Create overrides GORM Create with metrics
|
|
func (w *GormDBWrapper) Create(value interface{}) *gorm.DB {
|
|
start := time.Now()
|
|
result := w.DB.Create(value)
|
|
duration := time.Since(start)
|
|
|
|
table := w.DB.Statement.Table
|
|
status := "success"
|
|
if result.Error != nil {
|
|
status = "error"
|
|
}
|
|
|
|
w.metrics.RecordDBQuery("create", table, w.database, duration, result.Error)
|
|
|
|
w.logger.Debug("Database create operation",
|
|
logger.String("table", table),
|
|
logger.String("status", status),
|
|
logger.Float64("duration_seconds", duration.Seconds()),
|
|
logger.ErrorField(result.Error),
|
|
)
|
|
|
|
return result
|
|
}
|
|
|
|
// Find overrides GORM Find with metrics
|
|
func (w *GormDBWrapper) Find(dest interface{}, conds ...interface{}) *gorm.DB {
|
|
start := time.Now()
|
|
result := w.DB.Find(dest, conds...)
|
|
duration := time.Since(start)
|
|
|
|
table := w.DB.Statement.Table
|
|
status := "success"
|
|
if result.Error != nil {
|
|
status = "error"
|
|
}
|
|
|
|
w.metrics.RecordDBQuery("find", table, w.database, duration, result.Error)
|
|
|
|
w.logger.Debug("Database find operation",
|
|
logger.String("table", table),
|
|
logger.String("status", status),
|
|
logger.Float64("duration_seconds", duration.Seconds()),
|
|
logger.ErrorField(result.Error),
|
|
)
|
|
|
|
return result
|
|
}
|
|
|
|
// First overrides GORM First with metrics
|
|
func (w *GormDBWrapper) First(dest interface{}, conds ...interface{}) *gorm.DB {
|
|
start := time.Now()
|
|
result := w.DB.First(dest, conds...)
|
|
duration := time.Since(start)
|
|
|
|
table := w.DB.Statement.Table
|
|
status := "success"
|
|
if result.Error != nil {
|
|
status = "error"
|
|
}
|
|
|
|
w.metrics.RecordDBQuery("first", table, w.database, duration, result.Error)
|
|
|
|
w.logger.Debug("Database first operation",
|
|
logger.String("table", table),
|
|
logger.String("status", status),
|
|
logger.Float64("duration_seconds", duration.Seconds()),
|
|
logger.ErrorField(result.Error),
|
|
)
|
|
|
|
return result
|
|
}
|
|
|
|
// Update overrides GORM Update with metrics
|
|
func (w *GormDBWrapper) Update(column string, value interface{}) *gorm.DB {
|
|
start := time.Now()
|
|
result := w.DB.Update(column, value)
|
|
duration := time.Since(start)
|
|
|
|
table := w.DB.Statement.Table
|
|
status := "success"
|
|
if result.Error != nil {
|
|
status = "error"
|
|
}
|
|
|
|
w.metrics.RecordDBQuery("update", table, w.database, duration, result.Error)
|
|
|
|
w.logger.Debug("Database update operation",
|
|
logger.String("table", table),
|
|
logger.String("status", status),
|
|
logger.Float64("duration_seconds", duration.Seconds()),
|
|
logger.ErrorField(result.Error),
|
|
)
|
|
|
|
return result
|
|
}
|
|
|
|
// Delete overrides GORM Delete with metrics
|
|
func (w *GormDBWrapper) Delete(value interface{}, conds ...interface{}) *gorm.DB {
|
|
start := time.Now()
|
|
result := w.DB.Delete(value, conds...)
|
|
duration := time.Since(start)
|
|
|
|
table := w.DB.Statement.Table
|
|
status := "success"
|
|
if result.Error != nil {
|
|
status = "error"
|
|
}
|
|
|
|
w.metrics.RecordDBQuery("delete", table, w.database, duration, result.Error)
|
|
|
|
w.logger.Debug("Database delete operation",
|
|
logger.String("table", table),
|
|
logger.String("status", status),
|
|
logger.Float64("duration_seconds", duration.Seconds()),
|
|
logger.ErrorField(result.Error),
|
|
)
|
|
|
|
return result
|
|
}
|
|
|
|
// WithContext overrides GORM WithContext to maintain wrapper
|
|
func (w *GormDBWrapper) WithContext(ctx context.Context) *GormDBWrapper {
|
|
return &GormDBWrapper{
|
|
DB: w.DB.WithContext(ctx),
|
|
metrics: w.metrics,
|
|
database: w.database,
|
|
logger: w.logger,
|
|
}
|
|
}
|
|
|
|
// Model overrides GORM Model to maintain wrapper
|
|
func (w *GormDBWrapper) Model(value interface{}) *GormDBWrapper {
|
|
return &GormDBWrapper{
|
|
DB: w.DB.Model(value),
|
|
metrics: w.metrics,
|
|
database: w.database,
|
|
logger: w.logger,
|
|
}
|
|
}
|
|
|
|
// Table overrides GORM Table to maintain wrapper
|
|
func (w *GormDBWrapper) Table(name string, args ...interface{}) *GormDBWrapper {
|
|
return &GormDBWrapper{
|
|
DB: w.DB.Table(name, args...),
|
|
metrics: w.metrics,
|
|
database: w.database,
|
|
logger: w.logger,
|
|
}
|
|
}
|