/
contentserver.go
111 lines (96 loc) · 3.16 KB
/
contentserver.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
105
106
107
108
109
110
111
package main
import (
"flag"
"fmt"
_ "net/http/pprof"
"os"
"runtime/debug"
"time"
. "github.com/foomo/contentserver/logger"
"github.com/foomo/contentserver/metrics"
"github.com/foomo/contentserver/server"
"github.com/foomo/contentserver/status"
"go.uber.org/zap"
)
const (
ServiceName = "Content Server"
DefaultHealthzHandlerAddress = ":8080"
DefaultPrometheusListener = ":9200"
)
var (
flagAddress = flag.String("address", "", "address to bind socket server host:port")
flagWebserverAddress = flag.String("webserver-address", "", "address to bind web server host:port, when empty no webserver will be spawned")
flagWebserverPath = flag.String("webserver-path", "/contentserver", "path to export the webserver on - useful when behind a proxy")
flagVarDir = flag.String("var-dir", "/var/lib/contentserver", "where to put my data")
flagPrometheusListener = flag.String("prometheus-listener", getenv("PROMETHEUS_LISTENER", DefaultPrometheusListener), "address for the prometheus listener")
flagRepositoryTimeoutDuration = flag.Duration("repository-timeout-duration", server.DefaultRepositoryTimeout, "timeout duration for the contentserver")
flagPoll = flag.Bool("poll", false, "if true, the address arg will be used to periodically poll the content url")
// debugging / profiling
flagDebug = flag.Bool("debug", false, "toggle debug mode")
flagFreeOSMem = flag.Int("free-os-mem", 0, "free OS mem every X minutes")
flagHeapDump = flag.Int("heap-dump", 0, "dump heap every X minutes")
)
func getenv(env, fallback string) string {
if value, ok := os.LookupEnv(env); ok {
return value
}
return fallback
}
func exitUsage(code int) {
fmt.Println("Usage:", os.Args[0], "http(s)://your-content-server/path/to/content.json")
flag.PrintDefaults()
os.Exit(code)
}
func main() {
flag.Parse()
SetupLogging(*flagDebug, "contentserver.log")
if *flagFreeOSMem > 0 {
Log.Info("freeing OS memory every $interval minutes", zap.Int("interval", *flagFreeOSMem))
go func() {
for {
time.Sleep(time.Duration(*flagFreeOSMem) * time.Minute)
Log.Info("FreeOSMemory")
debug.FreeOSMemory()
}
}()
}
if *flagHeapDump > 0 {
Log.Info("dumping heap every $interval minutes", zap.Int("interval", *flagHeapDump))
go func() {
for {
time.Sleep(time.Duration(*flagFreeOSMem) * time.Minute)
Log.Info("HeapDump")
f, err := os.Create("heapdump")
if err != nil {
panic("failed to create heap dump file")
}
debug.WriteHeapDump(f.Fd())
err = f.Close()
if err != nil {
panic("failed to create heap dump file")
}
}
}()
}
if len(flag.Args()) == 1 {
fmt.Println(*flagAddress, flag.Arg(0))
// kickoff metric handlers
go metrics.RunPrometheusHandler(*flagPrometheusListener)
go status.RunHealthzHandlerListener(DefaultHealthzHandlerAddress, ServiceName)
err := server.RunServerSocketAndWebServer(
flag.Arg(0),
*flagAddress,
*flagWebserverAddress,
*flagWebserverPath,
*flagVarDir,
*flagRepositoryTimeoutDuration,
*flagPoll,
)
if err != nil {
fmt.Println("exiting with error", err)
os.Exit(1)
}
} else {
exitUsage(1)
}
}