Change logger to slog
This commit is contained in:
107
main.go
107
main.go
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
@@ -29,40 +29,48 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Создаем структурированный логгер
|
||||
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: slog.LevelInfo,
|
||||
}))
|
||||
slog.SetDefault(logger)
|
||||
|
||||
// Загружаем переменные окружения из .env файла
|
||||
if err := godotenv.Load(); err != nil {
|
||||
log.Println("Warning: .env file not found, using system environment variables")
|
||||
logger.Warn("Warning: .env file not found, using system environment variables")
|
||||
}
|
||||
|
||||
// Создаем директории если они не существуют
|
||||
if err := os.MkdirAll("data/files", 0755); err != nil {
|
||||
log.Fatal("Failed to create data/files directory:", err)
|
||||
logger.Error("Failed to create data/files directory", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
db, err := sql.Open("sqlite3", "data/transcriber.db")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open database: %v", err)
|
||||
logger.Error("failed to open database", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
if err := db.Ping(); err != nil {
|
||||
log.Fatalf("failed to ping database: %v", err)
|
||||
logger.Error("failed to ping database", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gq := goqu.New("sqlite3", db)
|
||||
|
||||
// Запускаем миграции
|
||||
if err := RunMigrations(db, "migrations"); err != nil {
|
||||
log.Fatal("Failed to run migrations:", err)
|
||||
if err := RunMigrations(db, "migrations", logger); err != nil {
|
||||
logger.Error("Failed to run migrations", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Создаем репозитории
|
||||
|
||||
fileRepo := sqlite.NewFileRepository(db, gq)
|
||||
jobRepo := sqlite.NewTranscriptJobRepository(db, gq)
|
||||
|
||||
// Создаем адаптеры
|
||||
|
||||
metaviewer := ffmpegmv.NewFfmpegMetaViewer()
|
||||
converter := ffmpegconv.NewFfmpegConverter()
|
||||
|
||||
@@ -76,19 +84,18 @@ func main() {
|
||||
FolderID: os.Getenv("YANDEX_CLOUD_FOLDER_ID"),
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("failed to create audio recognizer: %v", err)
|
||||
logger.Error("failed to create audio recognizer", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer recognizer.Close()
|
||||
|
||||
// Создаем сервисы
|
||||
|
||||
transcribeService := service.NewTranscribeService(jobRepo, fileRepo, metaviewer, converter, recognizer)
|
||||
transcribeService := service.NewTranscribeService(jobRepo, fileRepo, metaviewer, converter, recognizer, logger)
|
||||
|
||||
// Создаем воркеры
|
||||
|
||||
conversionWorker := worker.NewCallbackWorker("conversion_worker", transcribeService.FindAndRunConversionJob)
|
||||
transcribeWorker := worker.NewCallbackWorker("transcribe_worker", transcribeService.FindAndRunTranscribeJob)
|
||||
checkWorker := worker.NewCallbackWorker("check_worker", transcribeService.FindAndRunTranscribeCheckJob)
|
||||
conversionWorker := worker.NewCallbackWorker("conversion_worker", transcribeService.FindAndRunConversionJob, logger)
|
||||
transcribeWorker := worker.NewCallbackWorker("transcribe_worker", transcribeService.FindAndRunTranscribeJob, logger)
|
||||
checkWorker := worker.NewCallbackWorker("check_worker", transcribeService.FindAndRunTranscribeCheckJob, logger)
|
||||
|
||||
workers := []worker.Worker{
|
||||
conversionWorker,
|
||||
@@ -109,13 +116,18 @@ func main() {
|
||||
go func(worker worker.Worker) {
|
||||
defer wg.Done()
|
||||
worker.Start(ctx)
|
||||
log.Printf("%s stopped", worker.Name())
|
||||
logger.Info("Worker stopped", "worker_name", worker.Name())
|
||||
}(w)
|
||||
}
|
||||
|
||||
// Создаем Gin middleware для логирования
|
||||
gin.SetMode(gin.DebugMode)
|
||||
router := gin.New()
|
||||
router.Use(ginSlogMiddleware(logger))
|
||||
router.Use(gin.Recovery())
|
||||
|
||||
// Запускаем HTTP сервер для API (создание задач и проверка статуса)
|
||||
transcribeHandler := httpcontroller.NewTranscribeHandler(jobRepo, transcribeService)
|
||||
router := gin.Default()
|
||||
|
||||
// Настраиваем роуты только для создания задач и проверки статуса
|
||||
api := router.Group("/api")
|
||||
@@ -148,9 +160,9 @@ func main() {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
log.Println("Starting HTTP server on :8080")
|
||||
logger.Info("Starting HTTP server", "port", 8080)
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Printf("HTTP server error: %v", err)
|
||||
logger.Error("HTTP server error", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -158,24 +170,24 @@ func main() {
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
log.Println("Transcriber service started with background workers")
|
||||
log.Println("Workers: ConversionWorker, TranscribeWorker, CheckWorker")
|
||||
log.Println("Press Ctrl+C to stop...")
|
||||
logger.Info("Transcriber service started with background workers")
|
||||
logger.Info("Workers: ConversionWorker, TranscribeWorker, CheckWorker")
|
||||
logger.Info("Press Ctrl+C to stop...")
|
||||
|
||||
// Ждем сигнал завершения
|
||||
<-sigChan
|
||||
log.Println("Received shutdown signal, initiating graceful shutdown...")
|
||||
logger.Info("Received shutdown signal, initiating graceful shutdown...")
|
||||
|
||||
// Создаем контекст с таймаутом для graceful shutdown HTTP сервера
|
||||
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer shutdownCancel()
|
||||
|
||||
// Останавливаем HTTP сервер
|
||||
log.Println("Shutting down HTTP server...")
|
||||
logger.Info("Shutting down HTTP server...")
|
||||
if err := srv.Shutdown(shutdownCtx); err != nil {
|
||||
log.Printf("HTTP server forced to shutdown: %v", err)
|
||||
logger.Error("HTTP server forced to shutdown", "error", err)
|
||||
} else {
|
||||
log.Println("HTTP server stopped gracefully")
|
||||
logger.Info("HTTP server stopped gracefully")
|
||||
}
|
||||
|
||||
// Отменяем контекст для остановки воркеров
|
||||
@@ -191,15 +203,15 @@ func main() {
|
||||
// Ждем завершения всех воркеров или таймаута в 10 секунд
|
||||
select {
|
||||
case <-done:
|
||||
log.Println("All workers stopped gracefully")
|
||||
logger.Info("All workers stopped gracefully")
|
||||
case <-time.After(10 * time.Second):
|
||||
log.Println("Timeout reached, forcing shutdown")
|
||||
logger.Warn("Timeout reached, forcing shutdown")
|
||||
}
|
||||
|
||||
log.Println("Transcriber service stopped")
|
||||
logger.Info("Transcriber service stopped")
|
||||
}
|
||||
|
||||
func RunMigrations(db *sql.DB, migrationsDir string) error {
|
||||
func RunMigrations(db *sql.DB, migrationsDir string, logger *slog.Logger) error {
|
||||
if err := goose.SetDialect("sqlite3"); err != nil {
|
||||
return fmt.Errorf("failed to set goose dialect: %w", err)
|
||||
}
|
||||
@@ -208,6 +220,37 @@ func RunMigrations(db *sql.DB, migrationsDir string) error {
|
||||
return fmt.Errorf("failed to run migrations: %w", err)
|
||||
}
|
||||
|
||||
log.Println("Migrations completed successfully")
|
||||
logger.Info("Migrations completed successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
// ginSlogMiddleware создает middleware для Gin, который использует slog для логирования
|
||||
func ginSlogMiddleware(logger *slog.Logger) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
path := c.Request.URL.Path
|
||||
raw := c.Request.URL.RawQuery
|
||||
|
||||
// Обрабатываем запрос
|
||||
c.Next()
|
||||
|
||||
// Логируем после обработки
|
||||
latency := time.Since(start)
|
||||
clientIP := c.ClientIP()
|
||||
method := c.Request.Method
|
||||
statusCode := c.Writer.Status()
|
||||
|
||||
if raw != "" {
|
||||
path = path + "?" + raw
|
||||
}
|
||||
|
||||
logger.Info("HTTP request",
|
||||
"method", method,
|
||||
"path", path,
|
||||
"status", statusCode,
|
||||
"latency", latency,
|
||||
"client_ip", clientIP,
|
||||
"user_agent", c.Request.UserAgent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user