uniugm/admin/lib/node/node_init.go
2025-04-18 17:17:23 +08:00

202 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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)
}
}