Skip to content

Commit ff4ca9b

Browse files
author
Greg Dubicki
committed
Make logging requests configurable
not requiring the app logging level to be set to TRACE and with configurable log address (stdout/stderr/syslog etc.)
1 parent 2e1ec40 commit ff4ca9b

File tree

14 files changed

+76
-49
lines changed

14 files changed

+76
-49
lines changed

README.md

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,9 @@ To handle intentions, HAProxy Connect, sets up a SPOE filter on the application
2222

2323
## How to use
2424

25+
Please see this for the current app parameters:
2526
```
2627
./haproxy-consul-connect --help
27-
Usage of ./haproxy-consul-connect:
28-
-dataplane string
29-
Dataplane binary path (default "dataplane-api")
30-
-enable-intentions
31-
Enable Connect intentions
32-
-haproxy string
33-
Haproxy binary path (default "haproxy")
34-
-haproxy-cfg-base-path string
35-
Haproxy binary path (default "/tmp")
36-
-http-addr string
37-
Consul agent address (default "127.0.0.1:8500")
38-
-log-level string
39-
Log level (default "INFO")
40-
-sidecar-for string
41-
The consul service id to proxy
42-
-sidecar-for-tag string
43-
The consul service id to proxy
44-
-stats-addr string
45-
Listen addr for stats server
46-
-stats-service-register
47-
Register a consul service for connect stats
48-
-token string
49-
Consul ACL token./haproxy-consul-connect --help
5028
```
5129

5230
## Minimal working example

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/haproxytech/haproxy-consul-connect
33
go 1.13
44

55
require (
6-
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
6+
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
77
github.com/criteo/haproxy-spoe-go v0.0.0-20190925130734-97891c13d324
88
github.com/d4l3k/messagediff v1.2.1 // indirect
99
github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9

haproxy/config.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ global
2828
tune.ssl.default-dh-param 1024
2929
nbproc 1
3030
nbthread {{.NbThread}}
31+
log-tag haproxy_sidecar
3132
3233
userlist controller
3334
user {{.DataplaneUser}} insecure-password {{.DataplanePass}}
@@ -57,7 +58,6 @@ type baseParams struct {
5758
SocketPath string
5859
DataplaneUser string
5960
DataplanePass string
60-
LogsPath string
6161
}
6262

6363
type haConfig struct {
@@ -113,7 +113,6 @@ func newHaConfig(baseDir string, sd *lib.Shutdown) (*haConfig, error) {
113113
err = tmpl.Execute(cfgFile, baseParams{
114114
NbThread: runtime.GOMAXPROCS(0),
115115
SocketPath: cfg.StatsSock,
116-
LogsPath: cfg.LogsSock,
117116
DataplaneUser: dataplaneUser,
118117
DataplanePass: dataplanePass,
119118
})

haproxy/haproxy.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,13 @@ func (h *HAProxy) start(sd *lib.Shutdown) error {
6060
}
6161
h.haConfig = hc
6262

63-
if h.opts.LogRequests {
63+
if h.opts.HAProxyLogAddress == "" {
6464
err := h.startLogger()
6565
if err != nil {
6666
return err
6767
}
68+
} else {
69+
log.Infof("not starting built-in syslog - using %s as syslog address", h.opts.HAProxyLogAddress)
6870
}
6971

7072
if h.opts.EnableIntentions {
@@ -77,6 +79,7 @@ func (h *HAProxy) start(sd *lib.Shutdown) error {
7779
dpc, err := haproxy_cmd.Start(sd, haproxy_cmd.Config{
7880
HAProxyPath: h.opts.HAProxyBin,
7981
HAProxyConfigPath: hc.HAProxy,
82+
HAProxyLogWithThisApp: h.opts.HAProxyLogAddress == "",
8083
DataplanePath: h.opts.DataplaneBin,
8184
DataplaneTransactionDir: hc.DataplaneTransactionDir,
8285
DataplaneSock: hc.DataplaneSock,
@@ -112,6 +115,8 @@ func (h *HAProxy) startLogger() error {
112115
}
113116
}(channel)
114117

118+
log.Infof("starting built-in syslog server at %s", h.haConfig.LogsSock)
119+
115120
return nil
116121
}
117122

haproxy/haproxy_cmd/cmd.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ import (
1313
log "github.com/sirupsen/logrus"
1414
)
1515

16-
func runCommand(sd *lib.Shutdown, cmdPath string, args ...string) (*exec.Cmd, error) {
16+
func runCommand(sd *lib.Shutdown, cmdPath string, logPrefix string, logWithThisApp bool, args ...string) (*exec.Cmd, error) {
1717
_, file := path.Split(cmdPath)
1818
cmd := exec.Command(cmdPath, args...)
19-
halog.Cmd("haproxy", cmd)
19+
if logWithThisApp {
20+
halog.Cmd(logPrefix, cmd)
21+
}
2022

2123
sd.Add(1)
2224
err := cmd.Start()

haproxy/haproxy_cmd/cmd_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import (
1010
func Test_runCommand_ok(t *testing.T) {
1111
t.Parallel()
1212
sd := lib.NewShutdown()
13-
cmd, err := runCommand(sd, "ls", ".")
13+
cmd, err := runCommand(sd, "ls", "foobar", true, ".")
1414
require.NoError(t, err)
1515
cmd.Wait()
1616
}
1717

1818
func Test_runCommand_nok_wrong_path(t *testing.T) {
1919
t.Parallel()
2020
sd := lib.NewShutdown()
21-
cmd, err := runCommand(sd, "/path/to/nowhere/that/can/be/found/myExec", "--help")
21+
cmd, err := runCommand(sd, "/path/to/nowhere/that/can/be/found/myExec", "foobar", true, "--help")
2222
require.NotNil(t, err)
2323
require.Contains(t, err.Error(), "no such file or directory")
2424
require.Nil(t, cmd)

haproxy/haproxy_cmd/run.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const (
2525
type Config struct {
2626
HAProxyPath string
2727
HAProxyConfigPath string
28+
HAProxyLogWithThisApp bool
2829
DataplanePath string
2930
DataplaneTransactionDir string
3031
DataplaneSock string
@@ -35,6 +36,8 @@ type Config struct {
3536
func Start(sd *lib.Shutdown, cfg Config) (*dataplane.Dataplane, error) {
3637
haCmd, err := runCommand(sd,
3738
cfg.HAProxyPath,
39+
"haproxy",
40+
cfg.HAProxyLogWithThisApp,
3841
"-f",
3942
cfg.HAProxyConfigPath,
4043
)
@@ -47,6 +50,8 @@ func Start(sd *lib.Shutdown, cfg Config) (*dataplane.Dataplane, error) {
4750

4851
cmd, err := runCommand(sd,
4952
cfg.DataplanePath,
53+
"dataplaneapi",
54+
true,
5055
"--scheme", "unix",
5156
"--socket-path", cfg.DataplaneSock,
5257
"--haproxy-bin", cfg.HAProxyPath,

haproxy/options.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ type Options struct {
88
EnableIntentions bool
99
StatsListenAddr string
1010
StatsRegisterService bool
11-
LogRequests bool
11+
HAProxyLogRequests bool
12+
HAProxyLogAddress string
1213
}

haproxy/state.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,15 @@ func (h *HAProxy) watch(sd *lib.Shutdown) error {
9595

9696
newConsulCfg := nextState.Load().(consul.Config)
9797

98+
logAddress := h.haConfig.LogsSock
99+
if h.opts.HAProxyLogAddress != "" {
100+
logAddress = h.opts.HAProxyLogAddress
101+
}
102+
98103
newState, err := state.Generate(state.Options{
99104
EnableIntentions: h.opts.EnableIntentions,
100-
LogRequests: h.opts.LogRequests,
101-
LogSocket: h.haConfig.LogsSock,
105+
LogRequests: h.opts.HAProxyLogRequests,
106+
LogAddress: logAddress,
102107
SPOEConfigPath: h.haConfig.SPOE,
103108
SPOESocket: h.haConfig.SPOESock,
104109
}, h.haConfig, currentState, newConsulCfg)

haproxy/state/downstream.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ func generateDownstream(opts Options, certStore CertificateStore, cfg consul.Dow
4444
}
4545

4646
// Logging
47-
if opts.LogRequests && opts.LogSocket != "" {
47+
if opts.LogRequests {
4848
fe.LogTarget = &models.LogTarget{
4949
ID: int64p(0),
50-
Address: opts.LogSocket,
50+
Address: opts.LogAddress,
5151
Facility: models.LogTargetFacilityLocal0,
5252
Format: models.LogTargetFormatRfc5424,
5353
}
@@ -100,10 +100,10 @@ func generateDownstream(opts Options, certStore CertificateStore, cfg consul.Dow
100100
}
101101

102102
// Logging
103-
if opts.LogRequests && opts.LogSocket != "" {
103+
if opts.LogRequests {
104104
be.LogTarget = &models.LogTarget{
105105
ID: int64p(0),
106-
Address: opts.LogSocket,
106+
Address: opts.LogAddress,
107107
Facility: models.LogTargetFacilityLocal0,
108108
Format: models.LogTargetFormatRfc5424,
109109
}

haproxy/state/snapshot_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ func GetTestHAConfig(baseCfg string) State {
217217
var TestOpts = Options{
218218
EnableIntentions: true,
219219
LogRequests: true,
220-
LogSocket: "//logs.sock",
220+
LogAddress: "//logs.sock",
221221
SPOEConfigPath: "//spoe",
222222
}
223223

haproxy/state/states.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
type Options struct {
1313
EnableIntentions bool
1414
LogRequests bool
15-
LogSocket string
15+
LogAddress string
1616
SPOEConfigPath string
1717
SPOESocket string
1818
}

haproxy/state/upstream.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ func generateUpstream(opts Options, certStore CertificateStore, cfg consul.Upstr
3434
Port: &fePort64,
3535
},
3636
}
37-
if opts.LogRequests && opts.LogSocket != "" {
37+
if opts.LogRequests && opts.LogAddress != "" {
3838
fe.LogTarget = &models.LogTarget{
3939
ID: int64p(0),
40-
Address: opts.LogSocket,
40+
Address: opts.LogAddress,
4141
Facility: models.LogTargetFacilityLocal0,
4242
Format: models.LogTargetFormatRfc5424,
4343
}
@@ -56,10 +56,10 @@ func generateUpstream(opts Options, certStore CertificateStore, cfg consul.Upstr
5656
Mode: beMode,
5757
},
5858
}
59-
if opts.LogRequests && opts.LogSocket != "" {
59+
if opts.LogRequests && opts.LogAddress != "" {
6060
be.LogTarget = &models.LogTarget{
6161
ID: int64p(0),
62-
Address: opts.LogSocket,
62+
Address: opts.LogAddress,
6363
Facility: models.LogTargetFacilityLocal0,
6464
Format: models.LogTargetFormatRfc5424,
6565
}

main.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package main
22

33
import (
4+
"errors"
45
"flag"
56
"fmt"
67
"os"
8+
"regexp"
79
"strings"
810

11+
"github.com/asaskevich/govalidator"
912
log "github.com/sirupsen/logrus"
1013

11-
haproxy "github.com/haproxytech/haproxy-consul-connect/haproxy"
14+
"github.com/haproxytech/haproxy-consul-connect/haproxy"
1215
"github.com/haproxytech/haproxy-consul-connect/haproxy/haproxy_cmd"
1316
"github.com/haproxytech/haproxy-consul-connect/lib"
1417

@@ -40,7 +43,7 @@ func (consulLogger) Infof(format string, args ...interface{}) {
4043

4144
// Warnf Display warning message
4245
func (consulLogger) Warnf(format string, args ...interface{}) {
43-
log.Infof(format, args...)
46+
log.Warnf(format, args...)
4447
}
4548

4649
// Errorf Display error message
@@ -59,15 +62,37 @@ func validateRequirements(dataplaneBin, haproxyBin string) error {
5962
return nil
6063
}
6164

65+
// HAproxy doesn't exit immediately when you pass incorrect log address, so we try to do it on our own to fail fast
66+
func validateHaproxyLogAddress(logAddress string) error {
67+
// allowed values taken from https://cbonte.github.io/haproxy-dconv/2.0/configuration.html#4.2-log
68+
fi, err := os.Stat(logAddress)
69+
if err != nil {
70+
match, err := regexp.Match(`(fd@<[0-9]+>|stdout|stderr)`, []byte(logAddress))
71+
if err != nil && match {
72+
return nil
73+
}
74+
if !govalidator.IsHost(logAddress) && !govalidator.IsDialString(logAddress) {
75+
return errors.New(fmt.Sprintf("%s should be either syslog host[:port] or a socket", logAddress))
76+
}
77+
} else {
78+
if fi.Mode()&os.ModeSocket == 0 {
79+
return errors.New(fmt.Sprintf("%s is a file but not a socket", logAddress))
80+
}
81+
}
82+
return nil
83+
}
84+
6285
func main() {
6386
versionFlag := flag.Bool("version", false, "Show version and exit")
64-
logLevel := flag.String("log-level", "INFO", "Log level")
6587
consulAddr := flag.String("http-addr", "127.0.0.1:8500", "Consul agent address")
6688
service := flag.String("sidecar-for", "", "The consul service id to proxy")
6789
serviceTag := flag.String("sidecar-for-tag", "", "The consul service id to proxy")
6890
haproxyBin := flag.String("haproxy", haproxy_cmd.DefaultHAProxyBin, "Haproxy binary path")
6991
dataplaneBin := flag.String("dataplane", haproxy_cmd.DefaultDataplaneBin, "Dataplane binary path")
70-
haproxyCfgBasePath := flag.String("haproxy-cfg-base-path", "/tmp", "Haproxy binary path")
92+
haproxyCfgBasePath := flag.String("haproxy-cfg-base-path", "/tmp", "Generated Haproxy configs path")
93+
haproxyLogRequests := flag.Bool("haproxy-log-requests", false, "Enable logging requests by Haproxy")
94+
haproxyLogAddress := flag.String("haproxy-log-address", "", "Address for Haproxy logs (default stderr with this app logs)")
95+
logLevel := flag.String("log-level", "INFO", "This app log level")
7196
statsListenAddr := flag.String("stats-addr", "", "Listen addr for stats server")
7297
statsServiceRegister := flag.Bool("stats-service-register", false, "Register a consul service for connect stats")
7398
enableIntentions := flag.Bool("enable-intentions", false, "Enable Connect intentions")
@@ -89,6 +114,12 @@ func main() {
89114
}
90115
log.SetLevel(ll)
91116

117+
if *haproxyLogAddress != "" {
118+
if err := validateHaproxyLogAddress(*haproxyLogAddress); err != nil {
119+
log.Fatal(err)
120+
}
121+
}
122+
92123
sd := lib.NewShutdown()
93124

94125
consulConfig := &api.Config{
@@ -144,7 +175,8 @@ func main() {
144175
EnableIntentions: *enableIntentions,
145176
StatsListenAddr: *statsListenAddr,
146177
StatsRegisterService: *statsServiceRegister,
147-
LogRequests: ll == log.TraceLevel,
178+
HAProxyLogRequests: *haproxyLogRequests,
179+
HAProxyLogAddress: *haproxyLogAddress,
148180
})
149181
sd.Add(1)
150182
go func() {

0 commit comments

Comments
 (0)