Files
open-im-server/pkg/common/cmd/root.go
T

248 lines
6.4 KiB
Go
Raw Normal View History

2023-06-30 09:45:02 +08:00
package cmd
import (
2024-12-25 18:08:08 +08:00
"context"
"encoding/json"
2023-06-30 09:45:02 +08:00
"fmt"
2023-08-04 21:38:30 +08:00
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
2024-12-25 18:08:08 +08:00
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discovery"
disetcd "github.com/openimsdk/open-im-server/v3/pkg/common/discovery/etcd"
"github.com/openimsdk/open-im-server/v3/version"
2024-12-25 18:08:08 +08:00
"github.com/openimsdk/tools/discovery/etcd"
2024-04-19 22:23:08 +08:00
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
2024-03-05 10:51:55 +08:00
"github.com/spf13/cobra"
2024-12-25 18:08:08 +08:00
clientv3 "go.etcd.io/etcd/client/v3"
2023-06-30 09:45:02 +08:00
)
type RootCmd struct {
Command cobra.Command
2024-04-19 22:23:08 +08:00
processName string
2023-06-30 09:45:02 +08:00
port int
prometheusPort int
2024-04-19 22:23:08 +08:00
log config.Log
index int
2024-06-13 12:13:13 +08:00
configPath string
2024-12-25 18:08:08 +08:00
etcdClient *clientv3.Client
2024-06-13 12:13:13 +08:00
}
func (r *RootCmd) ConfigPath() string {
return r.configPath
2024-04-19 22:23:08 +08:00
}
func (r *RootCmd) Index() int {
return r.index
}
2024-04-19 22:23:08 +08:00
func (r *RootCmd) Port() int {
return r.port
2023-06-30 09:45:02 +08:00
}
2023-07-12 15:31:24 +08:00
type CmdOpts struct {
loggerPrefixName string
2024-04-19 22:23:08 +08:00
configMap map[string]any
2023-07-12 15:31:24 +08:00
}
func WithCronTaskLogName() func(*CmdOpts) {
return func(opts *CmdOpts) {
opts.loggerPrefixName = "openim-crontask"
2023-07-12 15:31:24 +08:00
}
}
func WithLogName(logName string) func(*CmdOpts) {
return func(opts *CmdOpts) {
opts.loggerPrefixName = logName
}
}
2024-04-19 22:23:08 +08:00
func WithConfigMap(configMap map[string]any) func(*CmdOpts) {
return func(opts *CmdOpts) {
opts.configMap = configMap
}
}
2023-07-12 15:31:24 +08:00
2024-04-19 22:23:08 +08:00
func NewRootCmd(processName string, opts ...func(*CmdOpts)) *RootCmd {
rootCmd := &RootCmd{processName: processName}
cmd := cobra.Command{
2024-04-19 22:23:08 +08:00
Use: "Start openIM application",
Long: fmt.Sprintf(`Start %s `, processName),
2023-06-30 09:45:02 +08:00
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
2023-10-24 20:28:22 +08:00
return rootCmd.persistentPreRun(cmd, opts...)
2023-06-30 09:45:02 +08:00
},
2024-04-19 22:23:08 +08:00
SilenceUsage: true,
SilenceErrors: false,
2023-06-30 09:45:02 +08:00
}
2024-12-25 18:08:08 +08:00
cmd.Flags().StringP(config.FlagConf, "c", "", "path of config directory")
cmd.Flags().IntP(config.FlagTransferIndex, "i", 0, "process startup sequence number")
2024-04-19 22:23:08 +08:00
rootCmd.Command = cmd
2023-06-30 09:45:02 +08:00
return rootCmd
}
2024-12-25 18:08:08 +08:00
func (r *RootCmd) initEtcd() error {
configDirectory, _, err := r.getFlag(&r.Command)
if err != nil {
return err
}
disConfig := config.Discovery{}
err = config.Load(configDirectory, config.DiscoveryConfigFilename, config.EnvPrefixMap[config.DiscoveryConfigFilename], &disConfig)
2024-12-25 18:08:08 +08:00
if err != nil {
return err
}
if disConfig.Enable == config.ETCD {
discov, _ := kdisc.NewDiscoveryRegister(&disConfig, nil)
2024-12-25 18:08:08 +08:00
r.etcdClient = discov.(*etcd.SvcDiscoveryRegistryImpl).GetClient()
}
return nil
}
2024-04-19 22:23:08 +08:00
func (r *RootCmd) persistentPreRun(cmd *cobra.Command, opts ...func(*CmdOpts)) error {
2024-12-25 18:08:08 +08:00
if err := r.initEtcd(); err != nil {
return err
}
2024-04-19 22:23:08 +08:00
cmdOpts := r.applyOptions(opts...)
if err := r.initializeConfiguration(cmd, cmdOpts); err != nil {
return err
2023-10-24 20:28:22 +08:00
}
2024-12-25 18:08:08 +08:00
if err := r.updateConfigFromEtcd(cmdOpts); err != nil {
return err
}
2024-04-19 22:23:08 +08:00
if err := r.initializeLogger(cmdOpts); err != nil {
return errs.WrapMsg(err, "failed to initialize logger")
2023-10-24 20:28:22 +08:00
}
if err := r.etcdClient.Close(); err != nil {
return errs.WrapMsg(err, "failed to close etcd client")
}
2023-10-24 20:28:22 +08:00
return nil
}
2024-04-19 22:23:08 +08:00
func (r *RootCmd) initializeConfiguration(cmd *cobra.Command, opts *CmdOpts) error {
configDirectory, _, err := r.getFlag(cmd)
if err != nil {
return err
}
2024-04-19 22:23:08 +08:00
// Load common configuration file
//opts.configMap[ShareFileName] = StructEnvPrefix{EnvPrefix: shareEnvPrefix, ConfigStruct: &r.share}
for configFileName, configStruct := range opts.configMap {
err := config.Load(configDirectory, configFileName, config.EnvPrefixMap[configFileName], configStruct)
2024-04-19 22:23:08 +08:00
if err != nil {
return err
}
}
// Load common log configuration file
return config.Load(configDirectory, config.LogConfigFileName, config.EnvPrefixMap[config.LogConfigFileName], &r.log)
2024-12-25 18:08:08 +08:00
}
func (r *RootCmd) updateConfigFromEtcd(opts *CmdOpts) error {
if r.etcdClient == nil {
return nil
}
ctx := context.TODO()
res, err := r.etcdClient.Get(ctx, disetcd.BuildKey(disetcd.EnableConfigCenterKey))
if err != nil {
log.ZWarn(ctx, "root cmd updateConfigFromEtcd, etcd Get EnableConfigCenterKey err: %v", errs.Wrap(err))
return nil
}
if res.Count == 0 {
return nil
} else {
if string(res.Kvs[0].Value) == disetcd.Disable {
return nil
} else if string(res.Kvs[0].Value) != disetcd.Enable {
return errs.New("unknown EnableConfigCenter value").Wrap()
}
}
2024-12-25 18:08:08 +08:00
update := func(configFileName string, configStruct any) error {
key := disetcd.BuildKey(configFileName)
etcdRes, err := r.etcdClient.Get(ctx, key)
if err != nil {
log.ZWarn(ctx, "root cmd updateConfigFromEtcd, etcd Get err: %v", errs.Wrap(err))
return nil
}
if etcdRes.Count == 0 {
data, err := json.Marshal(configStruct)
if err != nil {
return errs.ErrArgs.WithDetail(err.Error()).Wrap()
}
_, err = r.etcdClient.Put(ctx, disetcd.BuildKey(configFileName), string(data))
if err != nil {
log.ZWarn(ctx, "root cmd updateConfigFromEtcd, etcd Put err: %v", errs.Wrap(err))
}
2024-12-25 18:08:08 +08:00
return nil
}
err = json.Unmarshal(etcdRes.Kvs[0].Value, configStruct)
if err != nil {
return errs.WrapMsg(err, "failed to unmarshal config from etcd")
}
return nil
}
for configFileName, configStruct := range opts.configMap {
if err := update(configFileName, configStruct); err != nil {
return err
}
}
if err := update(config.LogConfigFileName, &r.log); err != nil {
return err
}
// Load common log configuration file
return nil
}
2024-04-19 22:23:08 +08:00
func (r *RootCmd) applyOptions(opts ...func(*CmdOpts)) *CmdOpts {
2023-10-24 20:28:22 +08:00
cmdOpts := defaultCmdOpts()
for _, opt := range opts {
opt(cmdOpts)
}
2023-10-24 20:28:22 +08:00
return cmdOpts
}
2024-04-19 22:23:08 +08:00
func (r *RootCmd) initializeLogger(cmdOpts *CmdOpts) error {
err := log.InitLoggerFromConfig(
2023-10-24 20:28:22 +08:00
cmdOpts.loggerPrefixName,
2024-04-19 22:23:08 +08:00
r.processName,
"", "",
2024-04-19 22:23:08 +08:00
r.log.RemainLogLevel,
r.log.IsStdout,
r.log.IsJson,
r.log.StorageLocation,
2024-07-17 10:31:02 +08:00
r.log.RemainRotationCount,
2024-04-19 22:23:08 +08:00
r.log.RotationTime,
version.Version,
2024-07-24 19:27:02 +08:00
r.log.IsSimplify,
2023-10-24 20:28:22 +08:00
)
2024-04-19 22:23:08 +08:00
if err != nil {
return errs.Wrap(err)
}
return errs.Wrap(log.InitConsoleLogger(r.processName, r.log.RemainLogLevel, r.log.IsJson, version.Version))
2024-04-19 22:23:08 +08:00
2023-10-24 20:28:22 +08:00
}
2023-10-23 16:24:55 +08:00
2023-10-24 20:28:22 +08:00
func defaultCmdOpts() *CmdOpts {
return &CmdOpts{
2024-04-19 22:23:08 +08:00
loggerPrefixName: "openim-service-log",
2023-10-24 20:28:22 +08:00
}
}
2024-04-19 22:23:08 +08:00
func (r *RootCmd) getFlag(cmd *cobra.Command) (string, int, error) {
2024-12-25 18:08:08 +08:00
configDirectory, err := cmd.Flags().GetString(config.FlagConf)
2023-10-30 10:16:37 +08:00
if err != nil {
2024-04-19 22:23:08 +08:00
return "", 0, errs.Wrap(err)
2023-10-30 10:16:37 +08:00
}
2024-06-13 12:13:13 +08:00
r.configPath = configDirectory
2024-12-25 18:08:08 +08:00
index, err := cmd.Flags().GetInt(config.FlagTransferIndex)
2024-04-19 22:23:08 +08:00
if err != nil {
return "", 0, errs.Wrap(err)
}
2024-04-19 22:23:08 +08:00
r.index = index
return configDirectory, index, nil
2023-06-30 09:45:02 +08:00
}
func (r *RootCmd) Execute() error {
return r.Command.Execute()
}