u
This commit is contained in:
1 parent
d04d22723b
commit
4ce951dd56
30 files changed
+982
-74
No files matched your search
@@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
@@ -12,11 +14,62 @@ var (
|
||||
conf *Config
|
||||
)
|
||||
|
||||
func InitConf() {
|
||||
func InitConfig() error {
|
||||
// 加载配置
|
||||
err := readConfigFile()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("read config file failed: %w", err)
|
||||
}
|
||||
|
||||
initLogger()
|
||||
initUniqueId()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultConfig() *Config {
|
||||
return &Config{
|
||||
Server: ServerConfig{
|
||||
Port: "8080",
|
||||
BaseUrl: "/",
|
||||
WsUrl: "/ws",
|
||||
},
|
||||
JWT: JwtConfig{
|
||||
Secret: "qwemwddlalmskadklsdklamlkdsakld",
|
||||
AccessExpiry: 24 * time.Hour,
|
||||
},
|
||||
UniqueID: UniqueIDConfig{
|
||||
DataCenterID: 1,
|
||||
WorkerID: 1,
|
||||
},
|
||||
Postgres: PostgresConfig{
|
||||
Port: 5432,
|
||||
SslMode: false,
|
||||
TimeZone: "Asia/Shanghai",
|
||||
MaxOpenConns: 20,
|
||||
MaxIdleConns: 10,
|
||||
ConnMaxLifetime: 30 * time.Minute,
|
||||
},
|
||||
Log: LogConfig{
|
||||
Level: "info",
|
||||
Dir: "logs",
|
||||
MaxSize: 100,
|
||||
MaxBackups: 10,
|
||||
MaxAge: 30,
|
||||
Compress: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func readConfigFile() error {
|
||||
// 配置文件的目录
|
||||
prefix := "resources"
|
||||
env := GetEnv() // 获取当前环境
|
||||
|
||||
// 设置默认值
|
||||
conf = defaultConfig() // 先给默认结构体
|
||||
|
||||
// 默认配置文件
|
||||
confFileRelPath := filepath.Join(prefix, "application.yaml")
|
||||
|
||||
@@ -42,18 +95,18 @@ func InitConf() {
|
||||
|
||||
// 如果需要,合并环境特定的配置文件
|
||||
if err := v.MergeInConfig(); err != nil {
|
||||
panic(err)
|
||||
return fmt.Errorf("merge env config failed: %w", err)
|
||||
}
|
||||
|
||||
// 将配置文件反序列化到 Config 结构体
|
||||
conf = new(Config)
|
||||
if err := v.Unmarshal(conf); err != nil {
|
||||
panic(err)
|
||||
return fmt.Errorf("unmarshal config failed: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("✅️ 加载配置成功")
|
||||
// 设置环境变量
|
||||
conf.Env = env
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetEnv 获取 GO_ENV 环境变量,默认返回 "dev"
|
||||
@@ -66,6 +119,16 @@ func GetEnv() string {
|
||||
return e
|
||||
}
|
||||
|
||||
// GetConf 获取配置信息
|
||||
func GetConf() *Config {
|
||||
return conf
|
||||
}
|
||||
|
||||
// GetServerPort 项目启动端口
|
||||
func GetServerPort() string {
|
||||
port := conf.Server.Port
|
||||
if strings.HasPrefix(port, ":") {
|
||||
return port
|
||||
}
|
||||
return ":" + port
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package config
|
||||
@@ -1 +1,153 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
fiberZap "github.com/gofiber/contrib/v3/zap"
|
||||
"github.com/gofiber/fiber/v3/log"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
currentDay = make(map[string]string)
|
||||
currentSync = make(map[string]zapcore.WriteSyncer)
|
||||
)
|
||||
|
||||
func initLogger() {
|
||||
dynamicLevel := zap.NewAtomicLevel()
|
||||
dynamicLevel.SetLevel(LogLevel())
|
||||
|
||||
logger := fiberZap.NewLogger(fiberZap.LoggerConfig{
|
||||
ExtraKeys: []string{"request_id"},
|
||||
ZapOptions: []zap.Option{
|
||||
zap.AddCaller(), // 打开 caller
|
||||
zap.AddCallerSkip(2), // 跳过一层 Fiber 调用
|
||||
},
|
||||
CoreConfigs: []fiberZap.CoreConfig{
|
||||
{
|
||||
Encoder: zapcore.NewConsoleEncoder(consoleEncoderConfig()),
|
||||
WriteSyncer: zapcore.AddSync(os.Stdout),
|
||||
LevelEncoder: dynamicLevel,
|
||||
},
|
||||
{
|
||||
Encoder: zapcore.NewJSONEncoder(humanEncoderConfig()),
|
||||
WriteSyncer: getWriteSyncer(fmt.Sprintf("%s/debug", conf.Log.Dir)),
|
||||
LevelEncoder: zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
|
||||
return lev == zap.DebugLevel
|
||||
}),
|
||||
},
|
||||
{
|
||||
Encoder: zapcore.NewJSONEncoder(humanEncoderConfig()),
|
||||
WriteSyncer: getWriteSyncer(fmt.Sprintf("%s/info", conf.Log.Dir)),
|
||||
LevelEncoder: zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
|
||||
return lev == zap.InfoLevel
|
||||
}),
|
||||
},
|
||||
{
|
||||
Encoder: zapcore.NewJSONEncoder(humanEncoderConfig()),
|
||||
WriteSyncer: getWriteSyncer(fmt.Sprintf("%s/warn", conf.Log.Dir)),
|
||||
LevelEncoder: zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
|
||||
return lev == zap.WarnLevel
|
||||
}),
|
||||
},
|
||||
{
|
||||
Encoder: zapcore.NewJSONEncoder(humanEncoderConfig()),
|
||||
WriteSyncer: getWriteSyncer(fmt.Sprintf("%s/error", conf.Log.Dir)),
|
||||
LevelEncoder: zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
|
||||
return lev >= zap.ErrorLevel
|
||||
}),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
log.SetLogger(logger)
|
||||
|
||||
// 退出时同步日志
|
||||
defer func() {
|
||||
_ = logger.Sync()
|
||||
}()
|
||||
}
|
||||
|
||||
func getWriteSyncer(basePath string) zapcore.WriteSyncer {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
today := time.Now().Format("2006-01-02")
|
||||
if day, ok := currentDay[basePath]; !ok || day != today {
|
||||
currentDay[basePath] = today
|
||||
file := fmt.Sprintf("%s/%s.log", basePath, today)
|
||||
|
||||
currentSync[basePath] = zapcore.AddSync(&lumberjack.Logger{
|
||||
Filename: file,
|
||||
MaxSize: conf.Log.MaxSize,
|
||||
MaxBackups: conf.Log.MaxBackups,
|
||||
MaxAge: conf.Log.MaxAge,
|
||||
Compress: conf.Log.Compress,
|
||||
LocalTime: true,
|
||||
})
|
||||
}
|
||||
return currentSync[basePath]
|
||||
}
|
||||
|
||||
func LogLevel() zapcore.Level {
|
||||
level := conf.Log.Level
|
||||
|
||||
switch level {
|
||||
case "trace":
|
||||
return zapcore.DebugLevel
|
||||
case "debug":
|
||||
return zapcore.DebugLevel
|
||||
case "info":
|
||||
return zapcore.InfoLevel
|
||||
case "warn":
|
||||
return zapcore.WarnLevel
|
||||
case "error":
|
||||
return zapcore.ErrorLevel
|
||||
case "dpanic":
|
||||
return zapcore.DPanicLevel
|
||||
case "panic":
|
||||
return zapcore.PanicLevel
|
||||
case "fatal":
|
||||
return zapcore.FatalLevel
|
||||
default:
|
||||
return zapcore.InfoLevel
|
||||
}
|
||||
}
|
||||
|
||||
func consoleEncoderConfig() zapcore.EncoderConfig {
|
||||
return zapcore.EncoderConfig{
|
||||
MessageKey: "msg",
|
||||
LevelKey: "level",
|
||||
TimeKey: "ts",
|
||||
EncodeTime: customTimeEncoder,
|
||||
EncodeLevel: zapcore.CapitalColorLevelEncoder,
|
||||
EncodeCaller: zapcore.ShortCallerEncoder,
|
||||
}
|
||||
}
|
||||
|
||||
func humanEncoderConfig() zapcore.EncoderConfig {
|
||||
return zapcore.EncoderConfig{
|
||||
MessageKey: "message",
|
||||
LevelKey: "level",
|
||||
NameKey: "mame",
|
||||
TimeKey: "ts",
|
||||
CallerKey: "caller",
|
||||
FunctionKey: "func",
|
||||
StacktraceKey: "stacktrace",
|
||||
LineEnding: "\n",
|
||||
EncodeTime: customTimeEncoder,
|
||||
EncodeLevel: zapcore.LowercaseLevelEncoder,
|
||||
EncodeDuration: zapcore.SecondsDurationEncoder,
|
||||
EncodeCaller: zapcore.ShortCallerEncoder,
|
||||
}
|
||||
}
|
||||
|
||||
func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||
enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package config
|
||||
@@ -5,53 +5,53 @@ import "time"
|
||||
type Config struct {
|
||||
Env string
|
||||
|
||||
Server ServerConfig `yaml:"server"`
|
||||
JWT JwtConfig `yaml:"jwt"`
|
||||
SnowID SnowIDConfig `yaml:"snow_id"`
|
||||
Postgres PostgresConfig `yaml:"postgres"`
|
||||
Log LogConfig `yaml:"log"`
|
||||
Wechat WechatConfig `yaml:"wechat"`
|
||||
Server ServerConfig `mapstructure:"server"`
|
||||
JWT JwtConfig `mapstructure:"jwt"`
|
||||
UniqueID UniqueIDConfig `mapstructure:"unique_id"`
|
||||
Postgres PostgresConfig `mapstructure:"postgres"`
|
||||
Log LogConfig `mapstructure:"log"`
|
||||
Wechat WechatConfig `mapstructure:"wechat"`
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
Port string `yaml:"port" mapstructure:"port"`
|
||||
BaseUrl string `mapstructure:"base_url"` // 添加mapstructure标签
|
||||
WsUrl string `yaml:"ws_url" mapstructure:"ws_url"`
|
||||
Port string `mapstructure:"port"`
|
||||
BaseUrl string `mapstructure:"base_url"`
|
||||
WsUrl string `mapstructure:"ws_url"`
|
||||
}
|
||||
|
||||
type JwtConfig struct {
|
||||
Secret string `yaml:"secret"`
|
||||
AccessExpiry time.Duration `yaml:"access_expiry"`
|
||||
Secret string `mapstructure:"secret"`
|
||||
AccessExpiry time.Duration `mapstructure:"access_expiry"`
|
||||
}
|
||||
|
||||
type SnowIDConfig struct {
|
||||
DataCenterID uint16 `yaml:"datacenter_id"`
|
||||
WorkerID uint16 `yaml:"worker_id"`
|
||||
type UniqueIDConfig struct {
|
||||
DataCenterID uint16 `mapstructure:"datacenter_id"`
|
||||
WorkerID uint16 `mapstructure:"worker_id"`
|
||||
}
|
||||
|
||||
type PostgresConfig struct {
|
||||
Host string `yaml:"host"`
|
||||
Port int `yaml:"port"`
|
||||
User string `yaml:"user"`
|
||||
Password string `yaml:"password"`
|
||||
Dbname string `yaml:"dbname"`
|
||||
SllMode bool `yaml:"sll_mode"`
|
||||
TimeZone string `yaml:"timezone"`
|
||||
MaxOpenConns int32 `yaml:"max_open_conns"`
|
||||
MaxIdleConns int32 `yaml:"max_idle_conns"`
|
||||
ConnMaxLifetime time.Duration `yaml:"conn_max_lifetime"`
|
||||
Host string `mapstructure:"host"`
|
||||
Port int `mapstructure:"port"`
|
||||
User string `mapstructure:"user"`
|
||||
Password string `mapstructure:"password"`
|
||||
Dbname string `mapstructure:"dbname"`
|
||||
SslMode bool `mapstructure:"ssl_mode"`
|
||||
TimeZone string `mapstructure:"timezone"`
|
||||
MaxOpenConns int32 `mapstructure:"max_open_conns"`
|
||||
MaxIdleConns int32 `mapstructure:"max_idle_conns"`
|
||||
ConnMaxLifetime time.Duration `mapstructure:"conn_max_lifetime"`
|
||||
}
|
||||
|
||||
type LogConfig struct {
|
||||
Level string `yaml:"level"`
|
||||
Dir string `yaml:"dir"`
|
||||
MaxSize int `yaml:"max_size"`
|
||||
MaxBackups int `yaml:"max_backups"`
|
||||
MaxAge int `yaml:"max_age"`
|
||||
Compress bool `yaml:"compress"`
|
||||
Level string `mapstructure:"level"`
|
||||
Dir string `mapstructure:"dir"`
|
||||
MaxSize int `mapstructure:"max_size"`
|
||||
MaxBackups int `mapstructure:"max_backups"`
|
||||
MaxAge int `mapstructure:"max_age"`
|
||||
Compress bool `mapstructure:"compress"`
|
||||
}
|
||||
|
||||
type WechatConfig struct {
|
||||
AppId string `yaml:"app_id"`
|
||||
AppSecret string `yaml:"app_secret"`
|
||||
AppId string `mapstructure:"app_id"`
|
||||
AppSecret string `mapstructure:"app_secret"`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package config
|
||||
|
||||
import "allapp/utils/uniqueid"
|
||||
|
||||
// 初始化雪花id
|
||||
func initUniqueId() {
|
||||
options := uniqueid.NewIdGeneratorOptions(conf.UniqueID.WorkerID)
|
||||
uniqueid.SetIdGenerator(options)
|
||||
}
|
||||
Reference in new issue
Block a user