uniugm/admin/lib/node/node_init.go

202 lines
5.3 KiB
Go
Raw Normal View History

2025-04-18 17:17:23 +08:00
/**
* @Author: likun
* @Title: todo
* @Description: todo
* @File: node_init
* @Date: 2024-11-08 14:02:42
*/
package node
import (
"admin/lib/flags"
"admin/lib/prom"
"admin/lib/xlog"
"admin/lib/xlog/handler"
"encoding/json"
"fmt"
"github.com/rs/zerolog"
"gopkg.in/yaml.v3"
"io"
"os"
"time"
)
// initialize 初始化app
func (node *Node) initialize() {
// 初始化节点启动参数,例如 ./app -a a -b b -c 123
must(node.initBootFlags())
// 初始化节点启动配置文件例如config/app.yaml
must(node.initBootConfig())
// 初始化逻辑
for _, j := range node.preInitFuncs {
curErr := j.value.(Task)()
if curErr != nil {
err := fmt.Errorf("node run pre_initialize task(%s) return error:%v", j.key, curErr)
panic(err)
}
}
// 初始化程序日志系统
must(node.initLog())
// 初始化prometheus metrics、go pprof
must(node.initTracer())
// 初始化逻辑
for _, j := range node.initFuncs {
curErr := j.value.(Task)()
if curErr != nil {
err := fmt.Errorf("node run initialize task(%s) return error:%v", j.key, curErr)
panic(err)
}
}
return
}
func (node *Node) initBootFlags() error {
var appBootFlags []interface{}
for _, v := range node.adis {
curApp := newApp(v.name, v.options...)
node.apps = append(node.apps, curApp)
if curApp.bootFlag == nil {
continue
}
appBootFlags = append(appBootFlags, curApp.bootFlag)
}
// 解析启动参数
flags.ParseWithStructPointers(append([]interface{}{node.bootFlags.globalBootFlag, node.bootFlags.exBootFlag}, appBootFlags...)...)
flagBin, _ := json.Marshal(node.bootFlags.globalBootFlag)
xlog.Noticef("os args:%+v, parsed flags:%v", os.Args, string(flagBin))
// check
if node.bootFlags.globalBootFlag.ServiceName == "" {
if len(node.adis) > 1 {
node.bootFlags.globalBootFlag.ServiceName = "all_in_one"
} else {
node.bootFlags.globalBootFlag.ServiceName = node.adis[0].name
}
}
return nil
}
func (node *Node) initBootConfig() error {
// 解析配置文件
if node.bootConfigFile.globalBootConfigFileContent != nil && node.bootFlags.globalBootFlag.BootConfig != "" {
err := node.parseWithConfigFileContent(true)
if err != nil {
newErr := fmt.Errorf("parse With Config File Content is error:%v", err)
return newErr
}
// 定时解析配置文件
ticker := time.NewTicker(time.Second * 3)
go func() {
for range ticker.C {
// 解析配置文件
err = node.parseWithConfigFileContent(false)
if err != nil {
xlog.Errorf("parse With Config File Content is error:%v", err)
continue
}
}
}()
}
return nil
}
func (node *Node) initLog() error {
logConfig := &LogBootConfig{}
if node.bootConfigFile.globalBootConfigFileContent != nil {
logConfig = node.bootConfigFile.globalBootConfigFileContent.GetLogConfig().Check()
}
var (
enableLogFile = logConfig.EnableFile
enableLogStdout = logConfig.EnableStdout
logDir = logConfig.LogDir
logLevel = logConfig.LogLevel
nodeId = node.bootFlags.globalBootFlag.NodeID
serviceName = node.bootFlags.globalBootFlag.ServiceName
maxLogFileBytesSize = logConfig.LogFileSize * 1024 * 1024 * 1024
maxLogRotateBackupCount = logConfig.LogFileRotateCount
)
// 初始化日志系统
var logHandlers []io.Writer
if !enableLogFile {
// 没有指定日志输出目录,默认输出到控制台
logHandlers = append(logHandlers, os.Stdout)
} else {
// 指定日志输出目录
logHandler, err := handler.NewRotatingDayMaxFileHandler(logDir, serviceName, maxLogFileBytesSize, maxLogRotateBackupCount)
if err != nil {
newErr := fmt.Errorf("new xlog file handler with path [%v] name[%v] error:%v", logDir, serviceName, err)
return newErr
}
logHandlers = append(logHandlers, logHandler)
// 也指定输出到控制台
if enableLogStdout {
logHandlers = append(logHandlers, os.Stdout)
}
}
// 创建logger
logLevelEnum := xlog.ParseLogLevelString(logLevel)
xlog.NewGlobalLogger(logHandlers, logLevelEnum, func(l zerolog.Logger) zerolog.Logger {
return l.With().Str("service", serviceName).Str("node_id", nodeId).Logger()
})
return nil
}
func (node *Node) initTracer() error {
node.tracer = prom.NewEngine(true)
return nil
}
// 解析配置文件
func (node *Node) parseWithConfigFileContent(first bool) error {
content, err := os.ReadFile(node.bootFlags.globalBootFlag.BootConfig)
if err != nil {
newErr := fmt.Errorf("load boot config file %v error:%v", node.bootFlags.globalBootFlag.BootConfig, err)
return newErr
}
if node.bootConfigFile.globalBootConfigParser == nil {
node.bootConfigFile.globalBootConfigParser = yaml.Unmarshal
}
oldContent, _ := json.Marshal(node.bootConfigFile.globalBootConfigFileContent)
err = node.bootConfigFile.globalBootConfigParser(content, node.bootConfigFile.globalBootConfigFileContent)
if err != nil {
newErr := fmt.Errorf("load boot config file %v content %v ok, but parse content error:%v",
node.bootFlags.globalBootFlag.BootConfig, string(content), err)
return newErr
}
// 读取配置后设置一次日志等级
if !first {
xlog.SetLogLevel(xlog.ParseLogLevelString(node.bootConfigFile.globalBootConfigFileContent.GetLogConfig().LogLevel))
}
node.bootConfigFile.globalBootConfigFileContent.OnReload(first, string(oldContent))
return nil
}
func must(err error) {
if err != nil {
panic(err)
}
}