Browse Source

Add logging, update haproxy example

master
Chris Smith 5 years ago
parent
commit
f88042436d
6 changed files with 83 additions and 47 deletions
  1. 13
    9
      container_monitor.go
  2. 22
    2
      dotege.go
  3. 7
    3
      go.mod
  4. 18
    14
      go.sum
  5. 12
    9
      template_generator.go
  6. 11
    10
      templates/haproxy.cfg.tpl

+ 13
- 9
container_monitor.go View File

@@ -2,14 +2,15 @@ package main
2 2
 
3 3
 import (
4 4
 	"context"
5
-	"fmt"
6 5
 	"github.com/docker/docker/api/types"
7 6
 	"github.com/docker/docker/api/types/filters"
8 7
 	"github.com/docker/docker/client"
8
+	"go.uber.org/zap"
9 9
 	"time"
10 10
 )
11 11
 
12 12
 type ContainerMonitor struct {
13
+	logger             *zap.SugaredLogger
13 14
 	newContainers      chan<- Container
14 15
 	goneContainerNames chan<- string
15 16
 	client             *client.Client
@@ -19,11 +20,12 @@ type ContainerMonitor struct {
19 20
 	expiryTimer        *time.Timer
20 21
 }
21 22
 
22
-func NewContainerMonitor(client *client.Client, newContainerChannel chan<- Container, goneContainerChannel chan<- string) *ContainerMonitor {
23
+func NewContainerMonitor(logger *zap.SugaredLogger, client *client.Client, newContainerChannel chan<- Container, goneContainerChannel chan<- string) *ContainerMonitor {
23 24
 	timer := time.NewTimer(time.Hour)
24 25
 	timer.Stop()
25 26
 
26 27
 	return &ContainerMonitor{
28
+		logger:             logger,
27 29
 		newContainers:      newContainerChannel,
28 30
 		goneContainerNames: goneContainerChannel,
29 31
 		client:             client,
@@ -56,7 +58,7 @@ func (c *ContainerMonitor) Monitor() {
56 58
 			c.publishExpiredContainers()
57 59
 
58 60
 		case err := <-errChan:
59
-			panic(err)
61
+			c.logger.Fatal("Error received from docker events API", err)
60 62
 		}
61 63
 	}
62 64
 }
@@ -64,10 +66,11 @@ func (c *ContainerMonitor) Monitor() {
64 66
 func (c *ContainerMonitor) publishExistingContainers() {
65 67
 	containers, err := c.client.ContainerList(context.Background(), types.ContainerListOptions{})
66 68
 	if err != nil {
67
-		panic(err)
69
+		c.logger.Fatal("Error received trying to list containers", err)
68 70
 	}
69 71
 
70 72
 	for _, container := range containers {
73
+		c.logger.Infof("Found existing container %s", container.Names[0][1:])
71 74
 		c.newContainers <- Container{
72 75
 			Id:     container.ID,
73 76
 			Name:   container.Names[0][1:],
@@ -79,13 +82,14 @@ func (c *ContainerMonitor) publishExistingContainers() {
79 82
 func (c *ContainerMonitor) publishNewContainer(id string) {
80 83
 	container, err := c.client.ContainerInspect(context.Background(), id)
81 84
 	if err != nil {
82
-		panic(err)
85
+		c.logger.Fatal("Error received trying to inspect container", err)
83 86
 	}
84 87
 	c.newContainers <- Container{
85 88
 		Id:     container.ID,
86 89
 		Name:   container.Name[1:],
87 90
 		Labels: container.Config.Labels,
88 91
 	}
92
+	c.logger.Info("Found new container %s", container.Name[1:])
89 93
 	delete(c.expiryTimes, container.Name[1:])
90 94
 }
91 95
 
@@ -93,9 +97,9 @@ func (c *ContainerMonitor) scheduleExpiry(name string) {
93 97
 	now := time.Now()
94 98
 	expiryTime := now.Add(c.deletionTime)
95 99
 	c.expiryTimes[name] = expiryTime
96
-	fmt.Printf("Scheduling expiry timer for %s\n", name)
100
+	c.logger.Info("Scheduling expiry timer for %s", name)
97 101
 	if c.nextExpiry.Before(now) || c.nextExpiry.After(expiryTime) {
98
-		fmt.Printf("Starting expiry timer with default duration\n")
102
+		c.logger.Debug("Starting expiry timer with default duration")
99 103
 		c.expiryTimer.Reset(c.deletionTime + 1*time.Second)
100 104
 		c.nextExpiry = expiryTime
101 105
 	}
@@ -107,7 +111,7 @@ func (c *ContainerMonitor) publishExpiredContainers() {
107 111
 
108 112
 	for name, expiryTime := range c.expiryTimes {
109 113
 		if expiryTime.Before(now) {
110
-			fmt.Printf("Expiring %s\n", name)
114
+			c.logger.Info("Expiring %s", name)
111 115
 			delete(c.expiryTimes, name)
112 116
 			c.goneContainerNames <- name
113 117
 		} else if next == 0 || expiryTime.Sub(now) < next {
@@ -116,7 +120,7 @@ func (c *ContainerMonitor) publishExpiredContainers() {
116 120
 	}
117 121
 
118 122
 	if next > 0 {
119
-		fmt.Printf("Starting expiry timer with duration %s\n", next)
123
+		c.logger.Debugf("Starting expiry timer with duration %s\n", next)
120 124
 		c.expiryTimer.Reset(next + 1*time.Second)
121 125
 		c.nextExpiry = now.Add(next)
122 126
 	}

+ 22
- 2
dotege.go View File

@@ -3,6 +3,8 @@ package main
3 3
 import (
4 4
 	"fmt"
5 5
 	"github.com/docker/docker/client"
6
+	"go.uber.org/zap"
7
+	"go.uber.org/zap/zapcore"
6 8
 	"os"
7 9
 	"os/signal"
8 10
 	"strings"
@@ -26,6 +28,11 @@ type Hostname struct {
26 28
 	Containers   []Container
27 29
 }
28 30
 
31
+type Config struct {
32
+	Templates []TemplateConfig
33
+	Labels    LabelConfig
34
+}
35
+
29 36
 func monitorSignals() <-chan bool {
30 37
 	signals := make(chan os.Signal, 1)
31 38
 	done := make(chan bool, 1)
@@ -42,6 +49,15 @@ func monitorSignals() <-chan bool {
42 49
 }
43 50
 
44 51
 func main() {
52
+	config := zap.NewDevelopmentConfig()
53
+	config.DisableCaller = true
54
+	config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
55
+	config.OutputPaths = []string{"stdout"}
56
+	config.ErrorOutputPaths = []string{"stdout"}
57
+	logger, _ := config.Build()
58
+	sugar := logger.Sugar()
59
+	sugar.Info("Dotege is starting")
60
+
45 61
 	done := monitorSignals()
46 62
 	containerChan := make(chan Container, 1)
47 63
 	expiryChan := make(chan string, 1)
@@ -54,13 +70,17 @@ func main() {
54 70
 		panic(err)
55 71
 	}
56 72
 
57
-	templateGenerator := NewTemplateGenerator()
73
+	templateGenerator := NewTemplateGenerator(sugar)
58 74
 	templateGenerator.AddTemplate(TemplateConfig{
59 75
 		Source:      "./templates/domains.txt.tpl",
60 76
 		Destination: "domains.txt",
61 77
 	})
78
+	templateGenerator.AddTemplate(TemplateConfig{
79
+		Source:      "./templates/haproxy.cfg.tpl",
80
+		Destination: "haproxy.cfg",
81
+	})
62 82
 
63
-	monitor := NewContainerMonitor(cli, containerChan, expiryChan)
83
+	monitor := NewContainerMonitor(sugar, cli, containerChan, expiryChan)
64 84
 	go monitor.Monitor()
65 85
 
66 86
 	go func() {

+ 7
- 3
go.mod View File

@@ -1,13 +1,17 @@
1 1
 module github.com/csmith/dotege
2 2
 
3 3
 require (
4
+	github.com/Microsoft/go-winio v0.4.11 // indirect
4 5
 	github.com/docker/distribution v2.7.1+incompatible // indirect
5 6
 	github.com/docker/docker v1.13.1
6 7
 	github.com/docker/go-connections v0.4.0 // indirect
7 8
 	github.com/docker/go-units v0.3.3 // indirect
8
-	github.com/gorilla/mux v1.7.0 // indirect
9 9
 	github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
10 10
 	github.com/pkg/errors v0.8.1 // indirect
11
-	github.com/sirupsen/logrus v1.3.0 // indirect
12
-	golang.org/x/net v0.0.0-20190206173232-65e2d4e15006 // indirect
11
+	github.com/stretchr/testify v1.3.0 // indirect
12
+	go.uber.org/atomic v1.3.2 // indirect
13
+	go.uber.org/multierr v1.1.0 // indirect
14
+	go.uber.org/zap v1.9.1
15
+	golang.org/x/net v0.0.0-20190213061140-3a22650c66bd // indirect
16
+	golang.org/x/sys v0.0.0-20190213121743-983097b1a8a3 // indirect
13 17
 )

+ 18
- 14
go.sum View File

@@ -1,4 +1,7 @@
1
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1
+github.com/Microsoft/go-winio v0.4.11 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6nK2Q=
2
+github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
3
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
4
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2 5
 github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
3 6
 github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
4 7
 github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo=
@@ -7,21 +10,22 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh
7 10
 github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
8 11
 github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
9 12
 github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
10
-github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
11
-github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
12
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
13 13
 github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
14 14
 github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
15 15
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
16 16
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
17
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
17 18
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
18
-github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
19
-github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
20
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
21
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
22
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
23
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
24
-golang.org/x/net v0.0.0-20190206173232-65e2d4e15006 h1:bfLnR+k0tq5Lqt6dflRLcZiz6UaXCMt3vhYJ1l4FQ80=
25
-golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
26
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
27
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
19
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
20
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
21
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
22
+go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
23
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
24
+go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
25
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
26
+go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
27
+go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
28
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
29
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
30
+golang.org/x/sys v0.0.0-20190213121743-983097b1a8a3 h1:+KlxhGbYkFs8lMfwKn+2ojry1ID5eBSMXprS2u/wqCE=
31
+golang.org/x/sys v0.0.0-20190213121743-983097b1a8a3/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

+ 12
- 9
template_generator.go View File

@@ -1,7 +1,7 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	"fmt"
4
+	"go.uber.org/zap"
5 5
 	"io/ioutil"
6 6
 	"path"
7 7
 	"sort"
@@ -26,6 +26,7 @@ type Template struct {
26 26
 }
27 27
 
28 28
 type TemplateGenerator struct {
29
+	logger *zap.SugaredLogger
29 30
 	templates []*Template
30 31
 }
31 32
 
@@ -40,14 +41,17 @@ var funcMap = template.FuncMap{
40 41
 	},
41 42
 }
42 43
 
43
-func NewTemplateGenerator() *TemplateGenerator {
44
-	return &TemplateGenerator{}
44
+func NewTemplateGenerator(logger *zap.SugaredLogger) *TemplateGenerator {
45
+	return &TemplateGenerator{
46
+		logger: logger,
47
+	}
45 48
 }
46 49
 
47 50
 func (t *TemplateGenerator) AddTemplate(config TemplateConfig) {
51
+	t.logger.Infof("Adding template from %s, writing to %s", config.Source, config.Destination)
48 52
 	tmpl, err := template.New(path.Base(config.Source)).Funcs(funcMap).ParseFiles(config.Source)
49 53
 	if err != nil {
50
-		panic(err)
54
+		t.logger.Fatal("Unable to parse template", err)
51 55
 	}
52 56
 
53 57
 	buf, _ := ioutil.ReadFile(config.Destination)
@@ -60,20 +64,19 @@ func (t *TemplateGenerator) AddTemplate(config TemplateConfig) {
60 64
 
61 65
 func (t *TemplateGenerator) Generate(context Context) {
62 66
 	for _, tmpl := range t.templates {
63
-		fmt.Printf("Checking %s\n", tmpl.config.Source)
67
+		t.logger.Debugf("Checking for updates to %s", tmpl.config.Source)
64 68
 		builder := &strings.Builder{}
65 69
 		err := tmpl.template.Execute(builder, context)
66 70
 		if err != nil {
67 71
 			panic(err)
68 72
 		}
69 73
 		if tmpl.content != builder.String() {
70
-			fmt.Printf("--- %s updated, writing to %s ---\n", tmpl.config.Source, tmpl.config.Destination)
71
-			fmt.Printf("%s", builder.String())
72
-			fmt.Printf("--- / writing %s ---\n", tmpl.config.Destination)
74
+			t.logger.Debugf("%s has been updated, writing to %s", tmpl.config.Source, tmpl.config.Destination)
75
+			t.logger.Debug(builder.String())
73 76
 			tmpl.content = builder.String()
74 77
 			err = ioutil.WriteFile(tmpl.config.Destination, []byte(builder.String()), 0666)
75 78
 			if err != nil {
76
-				panic(err)
79
+				t.logger.Fatal("Unable to write template", err)
77 80
 			}
78 81
 		}
79 82
 	}

+ 11
- 10
templates/haproxy.cfg.tpl View File

@@ -22,17 +22,18 @@ frontend main
22 22
     bind    :80
23 23
     redirect scheme https code 301 if !{ ssl_fc }
24 24
     http-response set-header Strict-Transport-Security max-age=15768000
25
-{{ range .Containers }}
26
-    {{- if index .Labels "com.chameth.proxy" -}}
27
-        {{- if index .Labels "com.chameth.vhost" }}
28
-    use_backend {{ .Name }} if { hdr(host) -i {{ index .Labels "com.chameth.vhost" | split "," | join " || hdr(host) -i " }} }
29
-        {{- end -}}
30
-    {{- end -}}
31
-{{ end }}
32
-{{ range .Containers }}
33
-    {{- if index .Labels "com.chameth.proxy" }}
34
-backend {{ .Name }}
25
+{{- range .Hostnames }}
26
+    use_backend {{ .Name | replace "." "_" }} if {hdr(host) -i {{ .Name }}
27
+        {{- range $san, $_ := .Alternatives }} || hdr(host) -i {{ $san }} {{- end -}}
28
+    }
29
+{{- end }}
30
+{{- range .Hostnames }}
31
+
32
+backend {{ .Name | replace "." "_" }}
35 33
     mode http
34
+    {{- range .Containers }}
35
+        {{- if index .Labels "com.chameth.proxy" }}
36 36
     server server1 {{ .Name }}:{{ index .Labels "com.chameth.proxy" }} check resolvers docker_resolver
37
+        {{- end -}}
37 38
     {{- end -}}
38 39
 {{ end }}

Loading…
Cancel
Save