202 lines
5.3 KiB
Go
202 lines
5.3 KiB
Go
/**
|
||
* @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)
|
||
}
|
||
}
|