1
0
Fork 0
changer/main.go

144 lines
3.5 KiB
Go

package main
import (
"os"
"os/signal"
"runtime"
"syscall"
"time"
"amuz.es/gogs/infra/changer/http"
"amuz.es/gogs/infra/changer/util"
"gopkg.in/alecthomas/kingpin.v2"
)
var (
app = kingpin.New(util.Config.Name(), "Inhouse internal user mgnt server").Author("Sangbum Kim<sangbumkim@amuz.es>")
verbose = app.Flag("verbose", "Enable verbose mode.").Short('v').Bool()
profile = app.Flag("profile", "Enable pprof mode.").Short('p').Bool()
logDir = app.Flag("log-dir", "logstore directory.").Short('L').String()
configFile = app.Flag("config-file", "config file path").Default("settings.yml").HintOptions("FILENAME").Short('C').String()
logger = util.NewLogger("main")
)
func systemStart(closeSignal chan struct{}, errorSignal chan error) {
defer func() {
if err := recover(); err != nil {
errorSignal <- err.(error)
}
}()
start := time.Now()
app.Version(util.Config.Version())
if _, err := app.Parse(os.Args[1:]); err != nil {
panic(err)
}
setMaxProcs()
if err := util.LoadConfig(*configFile); err != nil {
panic(err)
}
util.InitLogger(*verbose, *logDir, &util.Config.Logging.Application)
showBanner(util.Config.Phase, util.Config.Version(), util.Config.BuildDate())
// init subsystem
http.InitHttp(
util.Config.Bind,
util.Config.Prefix,
&util.Config.Logging.Access,
&util.Config.Ldap,
&util.Config.Session,
*profile, errorSignal, closeSignal)
logger.Info("bootstrapped application ", time.Since(start))
util.NotifyDaemon(util.DaemonStarted)
}
func systemReload() {
util.RotateLogger()
}
func systemTeardown(exitCode int) {
logger.Info("closing application")
util.NotifyDaemon(util.DaemonStopping)
http.CloseHttp()
logger.Info("bye")
os.Exit(exitCode)
}
func main() {
var (
exitCode = 0
exitSignal = make(chan os.Signal, 1)
closeSignal = make(chan struct{}, 1)
errorSignal = make(chan error, 10)
)
systemStart(closeSignal, errorSignal)
defer systemTeardown(exitCode)
signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
for {
select {
case <-closeSignal:
logger.Info("Service request to close this application")
return
case sysSignal := <-exitSignal:
switch sysSignal {
case syscall.SIGHUP:
systemReload()
default:
logger.Info("SYSCALL! ", sysSignal.String())
return
}
case err := <-errorSignal:
logger.Error("exception raised! ", err)
exitCode = -1
return
}
}
}
func setMaxProcs() {
// TODO(vmarmol): Consider limiting if we have a CPU mask in effect.
// Allow as many threads as we have cores unless the user specified a value.
var numProcs int
// if *maxProcs < 1 {
numProcs = runtime.NumCPU()
// } else {
// numProcs = *maxProcs
// }
runtime.GOMAXPROCS(numProcs)
// Check if the setting was successful.
actualNumProcs := runtime.GOMAXPROCS(0)
if actualNumProcs != numProcs {
logger.Warn("Specified max procs of %v but using %v", numProcs, actualNumProcs)
}
}
func showBanner(phase string, version string, buildDate string) {
if util.LoggerIsStd() {
logger.Info(`
{
{ }
}_{ __{
.-{ } }-. ` + util.Config.Name() + `
( } { ) version: ` + version + `
` + "|`-.._____..-'| buildDate: " + buildDate + `
| ;--. phase: ` + phase + `
| (__ \
| | ) )
| |/ /
| / /
| ( /
\ y'
` + "`-.._____..-'")
} else {
logger.
WithField("version", version).
WithField("buildDate", buildDate).
WithField("phase", phase).
Info("##", util.Config.Name())
}
}