206 lines
5.0 KiB
Go
206 lines
5.0 KiB
Go
// package qfixdpl is a Micro service quantex base project
|
|
package main
|
|
|
|
import (
|
|
"embed"
|
|
"flag"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/mitchellh/panicwrap"
|
|
|
|
"quantex.com/qfixdpl/src/app"
|
|
"quantex.com/qfixdpl/src/app/mode"
|
|
"quantex.com/qfixdpl/src/app/version"
|
|
"quantex.com/qfixdpl/src/client/config"
|
|
googlechat "quantex.com/qfixdpl/src/client/notify/google"
|
|
"quantex.com/qfixdpl/src/client/res"
|
|
"quantex.com/qfixdpl/src/cmd"
|
|
"quantex.com/qfixdpl/src/cmd/example"
|
|
"quantex.com/qfixdpl/src/cmd/service"
|
|
"quantex.com/qfixdpl/src/common/logger"
|
|
"quantex.com/qfixdpl/src/common/logger/tint"
|
|
"quantex.com/qfixdpl/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
|
|
|
|
if runner == "" {
|
|
runner = "service"
|
|
}
|
|
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)
|
|
}
|
|
}
|