first commit
This commit is contained in:
201
main.go
Normal file
201
main.go
Normal file
@ -0,0 +1,201 @@
|
||||
// package qfixpt is a Micro service quantex base project
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/panicwrap"
|
||||
|
||||
"quantex.com/qfixpt/src/app"
|
||||
"quantex.com/qfixpt/src/app/mode"
|
||||
"quantex.com/qfixpt/src/app/version"
|
||||
"quantex.com/qfixpt/src/client/config"
|
||||
googlechat "quantex.com/qfixpt/src/client/notify/google"
|
||||
"quantex.com/qfixpt/src/client/res"
|
||||
"quantex.com/qfixpt/src/cmd"
|
||||
"quantex.com/qfixpt/src/cmd/example"
|
||||
"quantex.com/qfixpt/src/cmd/service"
|
||||
"quantex.com/qfixpt/src/common/logger"
|
||||
"quantex.com/qfixpt/src/common/logger/tint"
|
||||
"quantex.com/qfixpt/src/domain"
|
||||
)
|
||||
|
||||
// Embed the entire directory.
|
||||
|
||||
//go:embed res
|
||||
var resources embed.FS
|
||||
|
||||
type flagsType struct {
|
||||
runner, globalCfg, serviceCfg, logLevel, logFormat string
|
||||
debug, version bool
|
||||
}
|
||||
|
||||
func main() {
|
||||
flags := parseFlags()
|
||||
|
||||
if len(os.Args) == 1 {
|
||||
flag.Usage()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if flags.version {
|
||||
fmt.Printf("%s version %s", version.AppName, version.Info())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
cfg, err := config.Read([]string{flags.globalCfg, flags.serviceCfg})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Something went wrong reading the config. %s", err))
|
||||
}
|
||||
|
||||
notify := googlechat.New(cfg.Notify.Google)
|
||||
|
||||
exitStatus, err := panicwrap.BasicWrap(func(output string) {
|
||||
notify.SendMsg(domain.MessageChannelPanic, output, domain.MessageStatusStopper, nil)
|
||||
os.Exit(1)
|
||||
})
|
||||
if err != nil {
|
||||
// Something went wrong setting up the panic wrapper.
|
||||
panic(fmt.Sprintf("Something went wrong setting up the panic wrapper. %s", err))
|
||||
}
|
||||
// If exitStatus >= 0, then we're the parent process and the panicwrap
|
||||
// re-executed ourselves and completed. Just exit with the proper status.
|
||||
if exitStatus >= 0 {
|
||||
os.Exit(exitStatus)
|
||||
}
|
||||
|
||||
handler, err := newLogHandler(flags)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
hook := logger.NewQuantexHandler(handler, []slog.Level{slog.LevelError, slog.LevelWarn})
|
||||
slog.SetDefault(slog.New(hook))
|
||||
|
||||
slog.Info("New Run ----------------------------------------------------------------------------")
|
||||
|
||||
slog.Debug(fmt.Sprintf("flags: %+v", flags))
|
||||
|
||||
v := version.AppName + " version " + version.Info()
|
||||
fmt.Println(v)
|
||||
slog.Info(v)
|
||||
|
||||
setDebugMode(flags.debug)
|
||||
|
||||
startRunner(flags.runner, flags.globalCfg, flags.serviceCfg)
|
||||
}
|
||||
|
||||
func parseFlags() (f flagsType) {
|
||||
fmt.Println(f.runner)
|
||||
flag.StringVar(&f.runner, "run", "", "run the specified service")
|
||||
|
||||
flag.StringVar(&f.globalCfg, "global-cfg", "../global_conf.toml", "set the config global file name")
|
||||
|
||||
flag.StringVar(&f.serviceCfg, "service-cfg", "conf.toml", "set the config service file name")
|
||||
|
||||
const u0 = "set the logs output format: text, json, tint1 (one line), tint2 (two lines)"
|
||||
flag.StringVar(&f.logFormat, "logs-format", "json", u0)
|
||||
flag.StringVar(&f.logFormat, "f", "json", u0+" (shorthand)")
|
||||
|
||||
const u1 = "set the debug mode"
|
||||
flag.BoolVar(&f.debug, "debug", false, u1)
|
||||
flag.BoolVar(&f.debug, "d", false, u1+" (shorthand)")
|
||||
|
||||
const u2 = "show the program version"
|
||||
flag.BoolVar(&f.version, "version", false, u2)
|
||||
flag.BoolVar(&f.version, "v", false, u2+" (shorthand)")
|
||||
|
||||
const u3 = "set the log level: debug, info, warn, error"
|
||||
flag.StringVar(&f.logLevel, "level", "info", u3)
|
||||
flag.StringVar(&f.logLevel, "l", "info", u3+" (shorthand)")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func newLogHandler(flags flagsType) (slog.Handler, error) {
|
||||
logLevel, err := parseLogLevel(flags.logLevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch flags.logFormat {
|
||||
case "json":
|
||||
return logger.NewJSONHandler(logLevel), nil
|
||||
case "text":
|
||||
return logger.NewTextHandler(logLevel), nil
|
||||
case "tint1":
|
||||
return logger.NewTextHandlerTint(logLevel, tint.OneLine), nil
|
||||
case "tint2":
|
||||
return logger.NewTextHandlerTint(logLevel, tint.TwoLines), nil
|
||||
default:
|
||||
flag.PrintDefaults()
|
||||
|
||||
return nil, fmt.Errorf("invalid log format option: \"%s\"", flags.logFormat)
|
||||
}
|
||||
}
|
||||
|
||||
func setDebugMode(debug bool) {
|
||||
mode.Debug = debug
|
||||
|
||||
var msg string
|
||||
|
||||
if mode.Debug {
|
||||
res.Set(os.DirFS("./"))
|
||||
|
||||
msg = fmt.Sprintf("Running %s in DEBUG mode!", version.AppName)
|
||||
} else {
|
||||
res.Set(resources)
|
||||
|
||||
msg = fmt.Sprintf("Running %s!", version.AppName)
|
||||
}
|
||||
|
||||
slog.Info(msg)
|
||||
}
|
||||
|
||||
func parseLogLevel(level string) (slog.Level, error) {
|
||||
switch level {
|
||||
case "debug":
|
||||
return slog.LevelDebug, nil
|
||||
case "info":
|
||||
return slog.LevelInfo, nil
|
||||
case "warn":
|
||||
return slog.LevelWarn, nil
|
||||
case "error":
|
||||
return slog.LevelError, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid log level: %s", level)
|
||||
}
|
||||
}
|
||||
|
||||
func startRunner(runner, globalCfg, serviceCfg string) {
|
||||
var fn func(cfg app.Config) error
|
||||
switch runner {
|
||||
case "service":
|
||||
fn = service.Runner
|
||||
case "async":
|
||||
fn = example.AsyncRunner
|
||||
case "external":
|
||||
fn = example.ExternalRunner
|
||||
case "tracerr":
|
||||
fn = example.TracerrRunner
|
||||
case "logger":
|
||||
fn = example.LogsRunner
|
||||
default:
|
||||
panic("Invalid runner option: \"" + runner + "\"")
|
||||
}
|
||||
|
||||
if err := cmd.NewRunner(fn)(globalCfg, serviceCfg); err != nil {
|
||||
slog.Error(err.Error())
|
||||
// Time guard to allow to notify to send the message
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user