feat: 初始化后端服务骨架,包含配置加载、数据库连接、Redis集成及消息队列任务处理。
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
|
||||||
|
|
||||||
"accounting-app/internal/cache"
|
"accounting-app/internal/cache"
|
||||||
"accounting-app/internal/config"
|
"accounting-app/internal/config"
|
||||||
@@ -125,8 +124,8 @@ func main() {
|
|||||||
ctx,
|
ctx,
|
||||||
redisClient.Client(),
|
redisClient.Client(),
|
||||||
db,
|
db,
|
||||||
5*time.Second, // Poll interval: 检查延迟任务的间隔
|
cfg.MQPollInterval, // Poll interval from config
|
||||||
2, // Worker count: 并发处理任务的数量
|
cfg.MQWorkerCount, // Worker count from config
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Warning: Failed to initialize recurring task system: %v", err)
|
log.Printf("Warning: Failed to initialize recurring task system: %v", err)
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ type Config struct {
|
|||||||
MaxImageSize int64
|
MaxImageSize int64
|
||||||
AllowedImageTypes string
|
AllowedImageTypes string
|
||||||
MaxImagesPerTx int
|
MaxImagesPerTx int
|
||||||
|
|
||||||
|
// Task Queue configuration
|
||||||
|
MQWorkerCount int
|
||||||
|
MQPollInterval time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load loads configuration from environment variables
|
// Load loads configuration from environment variables
|
||||||
@@ -113,6 +117,10 @@ func Load() *Config {
|
|||||||
MaxImageSize: getEnvInt64("MAX_IMAGE_SIZE", 10*1024*1024), // 10MB
|
MaxImageSize: getEnvInt64("MAX_IMAGE_SIZE", 10*1024*1024), // 10MB
|
||||||
AllowedImageTypes: getEnv("ALLOWED_IMAGE_TYPES", "image/jpeg,image/png,image/heic"),
|
AllowedImageTypes: getEnv("ALLOWED_IMAGE_TYPES", "image/jpeg,image/png,image/heic"),
|
||||||
MaxImagesPerTx: getEnvInt("MAX_IMAGES_PER_TX", 9),
|
MaxImagesPerTx: getEnvInt("MAX_IMAGES_PER_TX", 9),
|
||||||
|
|
||||||
|
// Task Queue
|
||||||
|
MQWorkerCount: getEnvInt("MQ_WORKER_COUNT", 2),
|
||||||
|
MQPollInterval: getEnvDuration("MQ_POLL_INTERVAL", 5*time.Second),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure data directory exists
|
// Ensure data directory exists
|
||||||
|
|||||||
67
internal/mq/logger.go
Normal file
67
internal/mq/logger.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package mq
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LogLevel 日志级别
|
||||||
|
type LogLevel string
|
||||||
|
|
||||||
|
const (
|
||||||
|
LevelInfo LogLevel = "INFO"
|
||||||
|
LevelError LogLevel = "ERROR"
|
||||||
|
LevelWarn LogLevel = "WARN"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Logger 简单的结构化日志封装
|
||||||
|
// 格式: [Component] [Level] Message key1=value1 key2=value2
|
||||||
|
type Logger struct {
|
||||||
|
Component string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogger(component string) *Logger {
|
||||||
|
return &Logger{Component: component}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) Info(msg string, keysAndValues ...interface{}) {
|
||||||
|
l.log(LevelInfo, msg, keysAndValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) Warn(msg string, keysAndValues ...interface{}) {
|
||||||
|
l.log(LevelWarn, msg, keysAndValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) Error(msg string, keysAndValues ...interface{}) {
|
||||||
|
l.log(LevelError, msg, keysAndValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) log(level LogLevel, msg string, args ...interface{}) {
|
||||||
|
// 构建 key=value 字符串
|
||||||
|
var kvStr string
|
||||||
|
for i := 0; i < len(args); i += 2 {
|
||||||
|
key := args[i]
|
||||||
|
var val interface{} = ""
|
||||||
|
if i+1 < len(args) {
|
||||||
|
val = args[i+1]
|
||||||
|
}
|
||||||
|
if kvStr != "" {
|
||||||
|
kvStr += " "
|
||||||
|
}
|
||||||
|
kvStr += logFormatKV(key, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
if kvStr != "" {
|
||||||
|
log.Printf("[%s] [%s] %s %s", l.Component, level, msg, kvStr)
|
||||||
|
} else {
|
||||||
|
log.Printf("[%s] [%s] %s", l.Component, level, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func logFormatKV(key, val interface{}) string {
|
||||||
|
return logStr(key) + "=" + logStr(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func logStr(v interface{}) string {
|
||||||
|
return fmt.Sprint(v)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user