/
main.go
104 lines (90 loc) · 2.56 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"os"
"os/signal"
"path/filepath"
"runtime"
"runtime/pprof"
"strings"
"syscall"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/domino14/macondo/config"
"github.com/domino14/macondo/shell"
)
const (
GracefulShutdownTimeout = 20 * time.Second
)
func main() {
// Determine the directory of the executable. We will use this
// directory to find the data files if an absolute path is not
// provided for these!
ex, err := os.Executable()
if err != nil {
panic(err)
}
exPath := filepath.Dir(ex)
log.Info().Msgf("executable path: %v", exPath)
cfg := &config.Config{}
args := os.Args[1:]
cfg.Load(args)
log.Info().Msgf("Loaded config: %v", cfg.AllSettings())
cfg.AdjustRelativePaths(exPath)
var logger zerolog.Logger
if cfg.GetBool("debug") {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
logger = zerolog.New(os.Stderr).Level(zerolog.DebugLevel)
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
logger = zerolog.New(os.Stderr).Level(zerolog.InfoLevel)
}
zerolog.DefaultContextLogger = &logger
logger.Debug().Msg("Debug logging is on")
if cfg.GetString("cpu-profile") != "" {
f, err := os.Create(cfg.GetString("cpu-profile"))
if err != nil {
panic("could not create CPU profile: " + err.Error())
}
defer f.Close()
if err := pprof.StartCPUProfile(f); err != nil {
panic("could not start CPU profile: " + err.Error())
}
defer pprof.StopCPUProfile()
}
idleConnsClosed := make(chan struct{})
sig := make(chan os.Signal, 1)
go func() {
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
// We received an interrupt signal, shut down.
log.Info().Msg("got quit signal...")
close(idleConnsClosed)
}()
argsLine := strings.Join(args, " ")
argsLineTrimmed := strings.TrimSpace(argsLine)
sc := shell.NewShellController(cfg, exPath)
if argsLineTrimmed == "" {
go sc.Loop(sig)
} else {
sc.Execute(sig, argsLineTrimmed)
sig <- syscall.SIGINT
}
<-idleConnsClosed
if cfg.GetString("mem-profile") != "" {
f, err := os.Create(cfg.GetString("mem-profile"))
if err != nil {
panic("could not create memory profile: " + err.Error())
}
defer f.Close() // error handling omitted for example
memstats := &runtime.MemStats{}
runtime.ReadMemStats(memstats)
log.Info().Interface("memstats", memstats).Msg("memory-stats")
// runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
panic("could not write memory profile: " + err.Error())
}
log.Info().Msg("wrote memory profile")
}
log.Info().Msg("server gracefully shutting down")
}