Bläddra i källkod

更新配置文件处理逻辑并增加输出功能

将配置文件的解析和输出分离,新增了对JSON格式的支持,并允许配置文件交叉输出。修改了多个相关函数以适应新的结构,移除了不再需要的代码。
SongZihuan 6 dagar sedan
förälder
incheckning
2cf10a39a4

+ 1 - 0
CHANGELOG.md

@@ -9,6 +9,7 @@
 ### 新增
 
 - 在`Windows`平台上可以使用`Windows`时区信息(最终转换为`IANA`时区信息呈现)。
+- 配置文件可以交叉输出了,输入`yaml`配置文件,通过`check`子命令可输出为`json`。
 
 ### 修改
 

+ 102 - 37
src/config/config.go

@@ -6,51 +6,125 @@ package config
 
 import (
 	"github.com/SongZihuan/BackendServerTemplate/src/config/configerror"
+	"github.com/SongZihuan/BackendServerTemplate/src/config/configoutputer"
 	"github.com/SongZihuan/BackendServerTemplate/src/config/configparser"
 	"github.com/SongZihuan/BackendServerTemplate/src/logger"
 	"github.com/SongZihuan/BackendServerTemplate/src/utils/filesystemutils"
+	"os"
+	"path"
 )
 
 type configInfo struct {
 	data *ConfigData
 
-	ready      bool
+	ready     bool
+	hasOutput bool
+
 	inputFile  string
 	outputFile string
-	provider   configparser.ConfigParserProvider
+
+	parserProvider configparser.ConfigParserProvider
+	outputProvider configoutputer.ConfigOutputProvider
+}
+
+type ConfigOption struct {
+	ConfigFilePath string
+	OutputFilePath string
+	ParserProvider configparser.ConfigParserProvider
+	OutputProvider configoutputer.ConfigOutputProvider
+}
+
+func (opt *ConfigOption) setDefault() (err error) {
+	if opt.ConfigFilePath == "" {
+		wd, err := os.Getwd()
+		if err != nil {
+			logger.Errorf("can not get work directory: %s", err.Error())
+			return err
+		}
+
+		opt.ConfigFilePath = path.Join(wd, "config.yaml")
+	}
+
+	if opt.ParserProvider == nil {
+		opt.ParserProvider, err = configparser.NewConfigParserProvider(opt.ConfigFilePath, nil)
+		if err != nil {
+			return err
+		}
+	}
+
+	if opt.OutputFilePath != "" && opt.OutputProvider == nil {
+		opt.OutputProvider, err = configoutputer.NewConfigOutputProvider(opt.OutputFilePath, nil)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
 }
 
-func newConfig(inputFilePath string, outputFilePath string, provider configparser.ConfigParserProvider) (*configInfo, configerror.Error) {
-	if inputFilePath == "" {
+func newConfig(opt *ConfigOption) (*configInfo, configerror.Error) {
+	if opt == nil {
+		opt = new(ConfigOption)
+	}
+
+	err := opt.setDefault()
+	if err != nil {
+		return nil, configerror.NewErrorf("new config system error: %s", err)
+	}
+
+	configFilePath := opt.ConfigFilePath
+	parserProvider := opt.ParserProvider
+	outputFilePath := opt.OutputFilePath
+	outputProvider := opt.OutputProvider
+
+	data := new(ConfigData)
+	dataInitErr := data.init(configFilePath, parserProvider)
+	if dataInitErr != nil && dataInitErr.IsError() {
+		return nil, dataInitErr
+	}
+
+	if configFilePath == "" {
 		logger.Panic("config path is empty")
 	}
 
-	configFilePath, err := filesystemutils.CleanFilePathAbs(inputFilePath)
+	configFilePath, err = filesystemutils.CleanFilePathAbs(configFilePath)
 	if err != nil {
 		return nil, configerror.NewErrorf("change config file path (%s) to abs error: %s", configFilePath, err.Error())
 	}
 
-	if provider == nil {
-		provider = configparser.NewYamlProvider(nil)
+	if parserProvider == nil {
+		parserProvider = configparser.NewYamlProvider(nil)
 	}
 
-	if !provider.CanUTF8() {
+	if !parserProvider.CanUTF8() {
 		return nil, configerror.NewErrorf("config file parser provider new support UTF-8")
 	}
 
-	data := new(ConfigData)
-	dataInitErr := data.init(configFilePath, provider)
-	if dataInitErr != nil && dataInitErr.IsError() {
-		return nil, dataInitErr
+	if outputFilePath != "" {
+		outputFilePath, err = filesystemutils.CleanFilePathAbs(outputFilePath)
+		if err != nil {
+			return nil, configerror.NewErrorf("change config file path (%s) to abs error: %s", configFilePath, err.Error())
+		}
+
+		if outputProvider == nil {
+			outputProvider = configoutputer.NewYamlProvider(nil)
+		}
+
+		if !outputProvider.CanUTF8() {
+			return nil, configerror.NewErrorf("config file output provider new support UTF-8")
+		}
 	}
 
 	return &configInfo{
 		data: data,
 
-		ready:      false,
+		ready:     false,
+		hasOutput: false,
+
 		inputFile:  configFilePath,
 		outputFile: outputFilePath,
-		provider:   provider,
+
+		parserProvider: parserProvider,
+		outputProvider: outputProvider,
 	}, nil
 }
 
@@ -59,12 +133,16 @@ func (c *configInfo) init() (err configerror.Error) {
 		return configerror.NewErrorf("config is ready")
 	}
 
-	err = c.provider.ReadFile(c.inputFile)
+	if c.parserProvider == nil {
+		return configerror.NewErrorf("config parser provider not set")
+	}
+
+	err = c.parserProvider.ReadFile(c.inputFile)
 	if err != nil && err.IsError() {
 		return err
 	}
 
-	err = c.provider.ParserFile(c.data) // c.Data本身就是指针
+	err = c.parserProvider.ParserFile(c.data) // c.Data本身就是指针
 	if err != nil && err.IsError() {
 		return err
 	}
@@ -74,11 +152,12 @@ func (c *configInfo) init() (err configerror.Error) {
 		return err
 	}
 
-	if c.outputFile != "" {
-		err = c.provider.WriteFile(c.outputFile, c.data)
+	if c.outputFile != "" && c.outputProvider != nil {
+		err = c.outputProvider.WriteFile(c.outputFile, c.data)
 		if err != nil && err.IsError() {
 			return err
 		}
+		c.hasOutput = true
 	}
 
 	err = c.data.check(c)
@@ -95,23 +174,6 @@ func (c *configInfo) init() (err configerror.Error) {
 	return nil
 }
 
-func (c *configInfo) output(filePath string) configerror.Error {
-	if !c.ready {
-		return configerror.NewErrorf("config is not ready")
-	}
-
-	if filePath == "" {
-		return configerror.NewErrorf("config output file path is empty")
-	}
-
-	err := c.provider.WriteFile(filePath, c.data)
-	if err != nil && err.IsError() {
-		return err
-	}
-
-	return nil
-}
-
 func (c *configInfo) GetData() (*ConfigData, configerror.Error) {
 	if !c.ready {
 		return nil, configerror.NewErrorf("config is not ready")
@@ -128,6 +190,9 @@ func (c *configInfo) Data() *ConfigData {
 	return c.data
 }
 
-func (c *configInfo) Output(filePath string) configerror.Error {
-	return c.output(filePath)
+func (c *configInfo) OutputPath() string {
+	if c.hasOutput && c.outputProvider != nil && c.outputFile != "" {
+		return c.outputFile
+	}
+	return ""
 }

+ 59 - 0
src/config/configoutputer/json.go

@@ -0,0 +1,59 @@
+// Copyright 2025 BackendServerTemplate Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package configoutputer
+
+import (
+	"encoding/json"
+	"github.com/SongZihuan/BackendServerTemplate/src/config/configerror"
+	"os"
+	"reflect"
+	"strings"
+)
+
+type JsonProvider struct {
+	Ident string
+}
+
+func NewJsonProvider(opt *NewConfigOutputProviderOption) *JsonProvider {
+	if opt == nil {
+		opt = new(NewConfigOutputProviderOption)
+	}
+
+	if opt.Ident <= 0 {
+		opt.Ident = 4
+	}
+
+	return &JsonProvider{
+		Ident: strings.Repeat(" ", opt.Ident),
+	}
+}
+
+func (j *JsonProvider) CanUTF8() bool {
+	return true
+}
+
+func (j *JsonProvider) WriteFile(filepath string, src any) configerror.Error {
+	if reflect.TypeOf(src).Kind() != reflect.Pointer {
+		return configerror.NewErrorf("target must be a pointer")
+	}
+
+	target, err := json.MarshalIndent(src, "", j.Ident)
+	if err != nil {
+		return configerror.NewErrorf("json marshal error: %s", err.Error())
+	}
+
+	err = os.WriteFile(filepath, target, 0644)
+	if err != nil {
+		return configerror.NewErrorf("write file error: %s", err.Error())
+	}
+
+	return nil
+}
+
+func _testJson() {
+	var a ConfigOutputProvider
+	a = &JsonProvider{}
+	_ = a
+}

+ 16 - 0
src/config/configoutputer/output.go

@@ -0,0 +1,16 @@
+// Copyright 2025 BackendServerTemplate Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package configoutputer
+
+import "github.com/SongZihuan/BackendServerTemplate/src/config/configerror"
+
+type ConfigOutputProvider interface {
+	CanUTF8() bool // Must return true
+	WriteFile(filepath string, data any) configerror.Error
+}
+
+type NewConfigOutputProviderOption struct {
+	Ident int
+}

+ 21 - 0
src/config/configoutputer/provider.go

@@ -0,0 +1,21 @@
+// Copyright 2025 BackendServerTemplate Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package configoutputer
+
+import (
+	"fmt"
+	"strings"
+)
+
+func NewConfigOutputProvider(configPath string, opt *NewConfigOutputProviderOption) (ConfigOutputProvider, error) {
+	switch {
+	case strings.HasSuffix(configPath, ".yaml") || strings.HasSuffix(configPath, ".yml"):
+		return NewYamlProvider(opt), nil
+	case strings.HasSuffix(configPath, ".json") || strings.HasSuffix(configPath, ".js"):
+		return NewJsonProvider(opt), nil
+	default:
+		return nil, fmt.Errorf("config file type unknown")
+	}
+}

+ 68 - 0
src/config/configoutputer/yaml.go

@@ -0,0 +1,68 @@
+// Copyright 2025 BackendServerTemplate Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package configoutputer
+
+import (
+	"bytes"
+	"github.com/SongZihuan/BackendServerTemplate/src/config/configerror"
+	"gopkg.in/yaml.v3"
+	"os"
+	"reflect"
+)
+
+type YamlProvider struct {
+	Ident int
+}
+
+func NewYamlProvider(opt *NewConfigOutputProviderOption) *YamlProvider {
+	if opt == nil {
+		opt = new(NewConfigOutputProviderOption)
+	}
+
+	if opt.Ident <= 0 {
+		opt.Ident = 4
+	}
+
+	return &YamlProvider{
+		Ident: opt.Ident,
+	}
+}
+
+func (y *YamlProvider) CanUTF8() bool {
+	return true
+}
+
+func (y *YamlProvider) WriteFile(filepath string, src any) configerror.Error {
+	if reflect.TypeOf(src).Kind() != reflect.Pointer {
+		return configerror.NewErrorf("target must be a pointer")
+	}
+
+	var buf bytes.Buffer
+
+	encoder := yaml.NewEncoder(&buf)
+	defer func() {
+		_ = encoder.Close()
+	}()
+
+	encoder.SetIndent(4) // 设置缩进长度
+
+	err := encoder.Encode(src)
+	if err != nil {
+		return configerror.NewErrorf("yaml marshal error: %s", err.Error())
+	}
+
+	err = os.WriteFile(filepath, buf.Bytes(), 0644)
+	if err != nil {
+		return configerror.NewErrorf("write file error: %s", err.Error())
+	}
+
+	return nil
+}
+
+func _testYaml() {
+	var a ConfigOutputProvider
+	a = &YamlProvider{}
+	_ = a
+}

+ 2 - 26
src/config/configparser/json.go

@@ -5,7 +5,6 @@
 package configparser
 
 import (
-	"encoding/json"
 	"errors"
 	"github.com/SongZihuan/BackendServerTemplate/src/config/configerror"
 	"github.com/SongZihuan/BackendServerTemplate/src/logger"
@@ -14,7 +13,6 @@ import (
 	"github.com/SongZihuan/BackendServerTemplate/src/utils/osutils"
 	"github.com/fsnotify/fsnotify"
 	"github.com/spf13/viper"
-	"os"
 	"reflect"
 	"sync"
 )
@@ -26,9 +24,9 @@ type JsonProvider struct {
 	restart    sync.Once
 }
 
-func NewJsonProvider(opt *NewProviderOption) *JsonProvider {
+func NewJsonProvider(opt *NewConfigParserProviderOption) *JsonProvider {
 	if opt == nil {
-		opt = new(NewProviderOption)
+		opt = new(NewConfigParserProviderOption)
 	}
 
 	if opt.EnvPrefix == "" {
@@ -106,28 +104,6 @@ func (j *JsonProvider) ParserFile(target any) configerror.Error {
 	return nil
 }
 
-func (j *JsonProvider) WriteFile(filepath string, src any) configerror.Error {
-	if !j.hasRead {
-		return configerror.NewErrorf("config file has not been read")
-	}
-
-	if reflect.TypeOf(src).Kind() != reflect.Pointer {
-		return configerror.NewErrorf("target must be a pointer")
-	}
-
-	target, err := json.MarshalIndent(src, "", "  ")
-	if err != nil {
-		return configerror.NewErrorf("json marshal error: %s", err.Error())
-	}
-
-	err = os.WriteFile(filepath, target, 0644)
-	if err != nil {
-		return configerror.NewErrorf("write file error: %s", err.Error())
-	}
-
-	return nil
-}
-
 func _testJson() {
 	var a ConfigParserProvider
 	a = &JsonProvider{}

+ 1 - 2
src/config/configparser/parser.go

@@ -10,10 +10,9 @@ type ConfigParserProvider interface {
 	CanUTF8() bool // Must return true
 	ReadFile(filepath string) configerror.Error
 	ParserFile(target any) configerror.Error
-	WriteFile(filepath string, data any) configerror.Error
 }
 
-type NewProviderOption struct {
+type NewConfigParserProviderOption struct {
 	EnvPrefix  string
 	AutoReload bool
 }

+ 2 - 2
src/config/configparser/provider.go

@@ -9,11 +9,11 @@ import (
 	"strings"
 )
 
-func NewProvider(configPath string, opt *NewProviderOption) (ConfigParserProvider, error) {
+func NewConfigParserProvider(configPath string, opt *NewConfigParserProviderOption) (ConfigParserProvider, error) {
 	switch {
 	case strings.HasSuffix(configPath, ".yaml") || strings.HasSuffix(configPath, ".yml"):
 		return NewYamlProvider(opt), nil
-	case strings.HasSuffix(configPath, ".yml"):
+	case strings.HasSuffix(configPath, ".json") || strings.HasSuffix(configPath, ".js"):
 		return NewJsonProvider(opt), nil
 	default:
 		return nil, fmt.Errorf("config file type unknown")

+ 2 - 26
src/config/configparser/yaml.go

@@ -13,8 +13,6 @@ import (
 	"github.com/SongZihuan/BackendServerTemplate/src/utils/osutils"
 	"github.com/fsnotify/fsnotify"
 	"github.com/spf13/viper"
-	"gopkg.in/yaml.v3"
-	"os"
 	"reflect"
 	"sync"
 )
@@ -26,9 +24,9 @@ type YamlProvider struct {
 	restart    sync.Once
 }
 
-func NewYamlProvider(opt *NewProviderOption) *YamlProvider {
+func NewYamlProvider(opt *NewConfigParserProviderOption) *YamlProvider {
 	if opt == nil {
-		opt = new(NewProviderOption)
+		opt = new(NewConfigParserProviderOption)
 	}
 
 	if opt.EnvPrefix == "" {
@@ -106,28 +104,6 @@ func (y *YamlProvider) ParserFile(target any) configerror.Error {
 	return nil
 }
 
-func (y *YamlProvider) WriteFile(filepath string, src any) configerror.Error {
-	if !y.hasRead {
-		return configerror.NewErrorf("config file has not been read")
-	}
-
-	if reflect.TypeOf(src).Kind() != reflect.Pointer {
-		return configerror.NewErrorf("target must be a pointer")
-	}
-
-	target, err := yaml.Marshal(src)
-	if err != nil {
-		return configerror.NewErrorf("yaml marshal error: %s", err.Error())
-	}
-
-	err = os.WriteFile(filepath, target, 0644)
-	if err != nil {
-		return configerror.NewErrorf("write file error: %s", err.Error())
-	}
-
-	return nil
-}
-
 func _testYaml() {
 	var a ConfigParserProvider
 	a = &YamlProvider{}

+ 3 - 44
src/config/export.go

@@ -7,58 +7,17 @@ package config
 import (
 	"fmt"
 	"github.com/SongZihuan/BackendServerTemplate/src/config/configerror"
-	"github.com/SongZihuan/BackendServerTemplate/src/config/configparser"
 	"github.com/SongZihuan/BackendServerTemplate/src/logger"
-	"os"
-	"path"
 )
 
 var config *configInfo
 
-type ConfigOption struct {
-	ConfigFilePath string
-	OutputFilePath string
-	Provider       configparser.ConfigParserProvider
-}
-
-func (opt *ConfigOption) setDefault() error {
-	if opt.ConfigFilePath == "" {
-		wd, err := os.Getwd()
-		if err != nil {
-			logger.Errorf("can not get work directory: %s", err.Error())
-			return err
-		}
-
-		opt.ConfigFilePath = path.Join(wd, "config.yaml")
-	}
-
-	if opt.Provider == nil {
-		var err error
-
-		opt.Provider, err = configparser.NewProvider(opt.ConfigFilePath, nil)
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
 func InitConfig(opt *ConfigOption) error {
 	if config != nil {
 		return fmt.Errorf("config already init")
 	}
 
-	if opt == nil {
-		opt = new(ConfigOption)
-	}
-
-	err := opt.setDefault()
-	if err != nil {
-		return err
-	}
-
-	_cfg, cfgErr := newConfig(opt.ConfigFilePath, opt.OutputFilePath, opt.Provider)
+	_cfg, cfgErr := newConfig(opt)
 	if cfgErr != nil && cfgErr.IsError() {
 		return cfgErr
 	}
@@ -88,10 +47,10 @@ func Data() *ConfigData {
 	return config.Data()
 }
 
-func Output(filePath string) error {
+func OutputPath() string {
 	if config == nil {
 		logger.Panic("config is not ready")
 	}
 
-	return config.Output(filePath)
+	return config.OutputPath()
 }

+ 4 - 3
src/logger/logger_export.go

@@ -5,6 +5,7 @@
 package logger
 
 import (
+	"fmt"
 	"github.com/SongZihuan/BackendServerTemplate/src/logger/internal"
 )
 
@@ -49,7 +50,7 @@ func Errorf(format string, args ...interface{}) {
 
 func Panicf(format string, args ...interface{}) {
 	if !internal.IsReady() {
-		return
+		panic(fmt.Sprintf(format, args...))
 	}
 	internal.GlobalLogger.Panicf(format, args...)
 }
@@ -91,7 +92,7 @@ func Error(args ...interface{}) {
 
 func Panic(args ...interface{}) {
 	if !internal.IsReady() {
-		return
+		panic(fmt.Sprint(args...))
 	}
 	internal.GlobalLogger.Panic(args...)
 }
@@ -133,7 +134,7 @@ func ErrorWrite(msg string) {
 
 func PanicWrite(msg string) {
 	if !internal.IsReady() {
-		return
+		panic(msg)
 	}
 	internal.GlobalLogger.PanicWrite(msg)
 }

+ 5 - 5
src/mainfunc/cat/v1/main.go

@@ -75,7 +75,7 @@ func MainV1Install(cmd *cobra.Command, args []string) (exitCode error) {
 		return exitutils.InitFailed("Service Install", err.Error())
 	}
 
-	return exitutils.SuccessExitSimple("Service Install Success")
+	return exitutils.SuccessExit("Service Install Success")
 }
 
 func MainV1UnInstall(cmd *cobra.Command, args []string) (exitCode error) {
@@ -107,7 +107,7 @@ func MainV1UnInstall(cmd *cobra.Command, args []string) (exitCode error) {
 		return exitutils.InitFailed("Service Remove", err.Error())
 	}
 
-	return exitutils.SuccessExitSimple("Service Remove Success")
+	return exitutils.SuccessExit("Service Remove Success")
 }
 
 func MainV1Start(cmd *cobra.Command, args []string) (exitCode error) {
@@ -139,7 +139,7 @@ func MainV1Start(cmd *cobra.Command, args []string) (exitCode error) {
 		return exitutils.InitFailed("Service Start", err.Error())
 	}
 
-	return exitutils.SuccessExitSimple("Service Start Success")
+	return exitutils.SuccessExit("Service Start Success")
 }
 
 func MainV1Stop(cmd *cobra.Command, args []string) (exitCode error) {
@@ -171,7 +171,7 @@ func MainV1Stop(cmd *cobra.Command, args []string) (exitCode error) {
 		return exitutils.InitFailed("Service Stop", err.Error())
 	}
 
-	return exitutils.SuccessExitSimple("Service Stop Success")
+	return exitutils.SuccessExit("Service Stop Success")
 }
 
 func MainV1Restart(cmd *cobra.Command, args []string) (exitCode error) {
@@ -203,5 +203,5 @@ func MainV1Restart(cmd *cobra.Command, args []string) (exitCode error) {
 		return exitutils.InitFailed("Service Restart", err.Error())
 	}
 
-	return exitutils.SuccessExitSimple("Service Restart Success")
+	return exitutils.SuccessExit("Service Restart Success")
 }

+ 0 - 9
src/mainfunc/cat/v1/service.go

@@ -7,7 +7,6 @@ package v1
 import (
 	"errors"
 	"github.com/SongZihuan/BackendServerTemplate/src/config"
-	"github.com/SongZihuan/BackendServerTemplate/src/config/configparser"
 	"github.com/SongZihuan/BackendServerTemplate/src/logger"
 	"github.com/SongZihuan/BackendServerTemplate/src/server/example3"
 	"github.com/SongZihuan/BackendServerTemplate/src/server/servercontext"
@@ -53,16 +52,8 @@ func (p *Program) Start(s service.Service) error {
 		panic("The main process should not be called.")
 	}
 
-	configProvider, err := configparser.NewProvider(p.configPath, nil)
-	if err != nil {
-		p.exitCode = exitutils.InitFailed("Get config file provider", err.Error())
-		return err
-	}
-
 	err = config.InitConfig(&config.ConfigOption{
 		ConfigFilePath: p.configPath,
-		OutputFilePath: "",
-		Provider:       configProvider,
 	})
 	if err != nil {
 		p.exitCode = exitutils.InitFailed("Config file read and parser", err.Error())

+ 9 - 11
src/mainfunc/check/v1/main.go

@@ -7,29 +7,27 @@ package v1
 import (
 	"fmt"
 	"github.com/SongZihuan/BackendServerTemplate/src/config"
-	"github.com/SongZihuan/BackendServerTemplate/src/config/configparser"
+	"github.com/SongZihuan/BackendServerTemplate/src/logger"
 	"github.com/SongZihuan/BackendServerTemplate/src/utils/exitutils"
+	"github.com/SongZihuan/BackendServerTemplate/src/utils/filesystemutils"
 	"github.com/spf13/cobra"
 )
 
 func MainV1(cmd *cobra.Command, args []string, inputConfigFilePath string, outputConfigFilePath string) (exitCode error) {
 	var err error
 
-	configProvider, err := configparser.NewProvider(inputConfigFilePath, &configparser.NewProviderOption{
-		AutoReload: false,
-	})
-	if err != nil {
-		return exitutils.SuccessExitSimple(fmt.Sprintf("Error: config file check failed: %s!", err.Error()))
-	}
-
 	err = config.InitConfig(&config.ConfigOption{
 		ConfigFilePath: inputConfigFilePath,
 		OutputFilePath: outputConfigFilePath,
-		Provider:       configProvider,
 	})
 	if err != nil {
-		return exitutils.SuccessExitSimple(fmt.Sprintf("Error: config file check failed: %s!", err.Error()))
+		return exitutils.RunError(fmt.Sprintf("config file check failed: %s!", err.Error()))
+	}
+
+	outputPath := config.OutputPath()
+	if outputPath != "" && filesystemutils.IsFile(outputPath) {
+		logger.Warnf("config output ok: %s", outputPath)
 	}
 
-	return exitutils.SuccessExitSimple("Info: config file check ok!")
+	return exitutils.SuccessExit("config file check ok!")
 }

+ 0 - 9
src/mainfunc/lion/v1/main.go

@@ -8,7 +8,6 @@ import (
 	"errors"
 	"fmt"
 	"github.com/SongZihuan/BackendServerTemplate/src/config"
-	"github.com/SongZihuan/BackendServerTemplate/src/config/configparser"
 	"github.com/SongZihuan/BackendServerTemplate/src/consolewatcher"
 	"github.com/SongZihuan/BackendServerTemplate/src/logger"
 	"github.com/SongZihuan/BackendServerTemplate/src/restart"
@@ -24,16 +23,8 @@ import (
 func MainV1(cmd *cobra.Command, args []string, inputConfigFilePath string, ppid int) (exitCode error) {
 	var err error
 
-	configProvider, err := configparser.NewProvider(inputConfigFilePath, &configparser.NewProviderOption{
-		AutoReload: ppid != 0,
-	})
-	if err != nil {
-		return exitutils.InitFailed("Get config file provider", err.Error())
-	}
-
 	err = config.InitConfig(&config.ConfigOption{
 		ConfigFilePath: inputConfigFilePath,
-		Provider:       configProvider,
 	})
 	if err != nil {
 		return exitutils.InitFailed("Config file read and parser", err.Error())

+ 0 - 9
src/mainfunc/restart/v1/main.go

@@ -6,7 +6,6 @@ package v1
 
 import (
 	"github.com/SongZihuan/BackendServerTemplate/src/config"
-	"github.com/SongZihuan/BackendServerTemplate/src/config/configparser"
 	"github.com/SongZihuan/BackendServerTemplate/src/consolewatcher"
 	"github.com/SongZihuan/BackendServerTemplate/src/logger"
 	"github.com/SongZihuan/BackendServerTemplate/src/restart"
@@ -18,16 +17,8 @@ import (
 func MainV1(cmd *cobra.Command, args []string, inputConfigFilePath string) (exitCode error) {
 	var err error
 
-	configProvider, err := configparser.NewProvider(inputConfigFilePath, &configparser.NewProviderOption{
-		AutoReload: false,
-	})
-	if err != nil {
-		return exitutils.InitFailed("Get config file provider", err.Error())
-	}
-
 	err = config.InitConfig(&config.ConfigOption{
 		ConfigFilePath: inputConfigFilePath,
-		Provider:       configProvider,
 	})
 	if err != nil {
 		return exitutils.InitFailed("Config file read and parser", err.Error())

+ 0 - 9
src/mainfunc/tiger/v1/main.go

@@ -8,7 +8,6 @@ import (
 	"errors"
 	"fmt"
 	"github.com/SongZihuan/BackendServerTemplate/src/config"
-	"github.com/SongZihuan/BackendServerTemplate/src/config/configparser"
 	"github.com/SongZihuan/BackendServerTemplate/src/consolewatcher"
 	"github.com/SongZihuan/BackendServerTemplate/src/logger"
 	"github.com/SongZihuan/BackendServerTemplate/src/restart"
@@ -22,16 +21,8 @@ import (
 func MainV1(cmd *cobra.Command, args []string, inputConfigFilePath string, ppid int) (exitCode error) {
 	var err error
 
-	configProvider, err := configparser.NewProvider(inputConfigFilePath, &configparser.NewProviderOption{
-		AutoReload: ppid != 0,
-	})
-	if err != nil {
-		return exitutils.InitFailed("Get config file provider", err.Error())
-	}
-
 	err = config.InitConfig(&config.ConfigOption{
 		ConfigFilePath: inputConfigFilePath,
-		Provider:       configProvider,
 	})
 	if err != nil {
 		return exitutils.InitFailed("Config file read and parser", err.Error())

+ 43 - 65
src/utils/exitutils/exit.go

@@ -15,11 +15,14 @@ import (
 const (
 	exitCodeMin                 = 0
 	exitCodeMax                 = 255
-	exitCodeDefaultSuccess      = 0
-	exitCodeDefaultError        = 1
-	exitCodeReload              = 252
-	exitCodeWithUnknownError    = 253
-	exitCodeErrorLogMustBeReady = 254
+	exitCodeDefaultSuccess      = 0   // 默认值:正常
+	exitCodeDefaultError        = 1   // 默认值:错误
+	exitCodeInitFailedError     = 2   // 初始化错误
+	exitCodeRunError            = 3   // 运行时错误
+	exitCodeRunErrorQuite       = 4   // 运行时错误(安静关闭)
+	exitCodeReload              = 252 // 重启信号
+	exitCodeWithUnknownError    = 253 // 未知错误
+	exitCodeErrorLogMustBeReady = 254 // 报告该错误需要日志系统加载完成
 )
 
 const ExitCodeReload = exitCodeReload
@@ -48,41 +51,41 @@ func getExitCode(defaultExitCode int, exitCode ...int) (ec ExitCode) {
 	return ec
 }
 
-func InitFailedForWin32ConsoleModule(reason string, exitCode ...int) ExitCode {
-	if reason == "" {
-		reason = "no reason"
+func initModuleFailedLog(module string, reason string) string {
+	if module == "" {
+		panic("module can not be empty")
 	}
 
-	ec := getExitCode(exitCodeDefaultError, exitCode...)
+	if reason != "" {
+		return fmt.Sprintf("Init failed [ %s ]: %s", module, reason)
+	} else {
+		return fmt.Sprintf("Init failed [ %s ]", module)
+	}
+}
 
-	log.Printf("The module `Win32 Console XXX` init failed (reason: `%s`) .", reason)
-	log.Printf("Now we should exit with code %d.", ec)
+func InitFailedForWin32ConsoleModule(reason string, exitCode ...int) ExitCode {
+	ec := getExitCode(exitCodeInitFailedError, exitCode...)
+
+	log.Printf(initModuleFailedLog("Win32 Console API", reason))
+	log.Printf("Init error exit %d: failed", ec)
 
 	return ec
 }
 
 func InitFailedForTimeLocationModule(reason string, exitCode ...int) ExitCode {
-	if reason == "" {
-		reason = "no reason"
-	}
-
-	ec := getExitCode(exitCodeDefaultError, exitCode...)
+	ec := getExitCode(exitCodeInitFailedError, exitCode...)
 
-	log.Printf("The module `Time Location` init failed (reason: `%s`) .", reason)
-	log.Printf("Now we should exit with code %d.", ec)
+	log.Printf(initModuleFailedLog("Time Location", reason))
+	log.Printf("Init error exit %d: failed", ec)
 
 	return ec
 }
 
 func InitFailedForLoggerModule(reason string, exitCode ...int) ExitCode {
-	if reason == "" {
-		reason = "no reason"
-	}
-
-	ec := getExitCode(exitCodeDefaultError, exitCode...)
+	ec := getExitCode(exitCodeInitFailedError, exitCode...)
 
-	log.Printf("The module `Logger` init failed (reason: `%s`) .", reason)
-	log.Printf("Now we should exit with code %d.", ec)
+	log.Printf(initModuleFailedLog("Logger", reason))
+	log.Printf("Init error exit %d: failed", ec)
 
 	return ec
 }
@@ -92,23 +95,16 @@ func InitFailed(module string, reason string, exitCode ...int) ExitCode {
 		return exitCodeErrorLogMustBeReady
 	}
 
-	if reason == "" {
-		reason = "no reason"
-	}
+	ec := getExitCode(exitCodeInitFailedError, exitCode...)
 
-	ec := getExitCode(exitCodeDefaultError, exitCode...)
-
-	logger.Errorf("The module `%s` init failed (reason: `%s`) .", module, reason)
-	logger.Errorf("Now we should exit with code %d.", ec)
+	logger.Error(initModuleFailedLog(module, reason))
+	logger.Errorf("Init error exit %d: failed", ec)
 
 	return ec
 }
 
 func RunErrorQuite(exitCode ...int) ExitCode {
-	if !logger.IsReady() {
-		return exitCodeErrorLogMustBeReady
-	}
-	return getExitCode(exitCodeDefaultError, exitCode...)
+	return getExitCode(exitCodeRunErrorQuite, exitCode...)
 }
 
 func RunError(reason string, exitCode ...int) ExitCode {
@@ -116,14 +112,13 @@ func RunError(reason string, exitCode ...int) ExitCode {
 		return exitCodeErrorLogMustBeReady
 	}
 
-	if reason == "" {
-		reason = "no reason"
-	}
-
-	ec := getExitCode(exitCodeDefaultError, exitCode...)
+	ec := getExitCode(exitCodeRunError, exitCode...)
 
-	logger.Errorf("Run error (reason: `%s`) .", reason)
-	logger.Errorf("Now we should exit with code %d.", ec)
+	if reason != "" {
+		logger.Errorf("Run error exit %d: %s", ec, reason)
+	} else {
+		logger.Errorf("Run error exit %d: failed", ec)
+	}
 
 	return ec
 }
@@ -133,31 +128,14 @@ func SuccessExit(reason string, exitCode ...int) ExitCode {
 		return exitCodeErrorLogMustBeReady
 	}
 
-	if reason == "" {
-		reason = "no reason"
-	}
-
 	ec := getExitCode(exitCodeDefaultSuccess, exitCode...)
 
-	logger.Warnf("Now we should exit with code %d (reason: %s) .", ec, reason)
-
-	return ec
-}
-
-func SuccessExitSimple(reason string, exitCode ...int) ExitCode {
 	if reason != "" {
-		log.Println(reason)
-	}
-	return getExitCode(exitCodeDefaultSuccess, exitCode...)
-}
-
-func SuccessExitQuite(exitCode ...int) ExitCode {
-	if !logger.IsReady() {
-		return exitCodeErrorLogMustBeReady
+		logger.Warnf("Exit %d: %s", ec, reason)
+	} else {
+		logger.Warnf("Exit %d: ok", ec)
 	}
 
-	ec := getExitCode(exitCodeDefaultSuccess, exitCode...)
-
 	return ec
 }
 
@@ -169,9 +147,9 @@ func Exit(err error) {
 		ExitByCode(ec)
 	} else {
 		if logger.IsReady() {
-			logger.Warnf("Now we should exit with code %d (reason: %s) .", exitCodeDefaultError, err.Error())
+			logger.Errorf("Exit %d: %s", ec, err.Error())
 		} else {
-			log.Printf("Now we should exit with code %d (reason: %s) .", exitCodeDefaultError, err.Error())
+			log.Printf("Exit %d: %s\n", ec, err.Error())
 		}
 		os.Exit(exitCodeDefaultError)
 	}