Skip to content

Commit ea1d0e9

Browse files
committed
Debug only errors
1 parent 35b8efe commit ea1d0e9

File tree

5 files changed

+91
-17
lines changed

5 files changed

+91
-17
lines changed

TODO.md

Lines changed: 0 additions & 2 deletions
This file was deleted.

docs/config.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ The following environment variables can be used to configure the *Docker Flow Pr
1616
|CONNECTION_MODE |HAProxy supports 5 connection modes.<br><br>`http-keep-alive`: all requests and responses are processed.<br>`http-tunnel`: only the first request and response are processed, everything else is forwarded with no analysis.<br>`httpclose`: tunnel with "Connection: close" added in both directions.<br>`http-server-close`: the server-facing connection is closed after the response.<br>`forceclose`: the connection is actively closed after end of response.<br><br>In general, it is preferred to use `http-server-close` with application servers, and some static servers might benefit from `http-keep-alive`.|No|http-server-close|http-keep-alive|
1717
|CONSUL_ADDRESS |The address of a Consul instance used for storing proxy information and discovering running nodes. Multiple addresses can be separated with comma (e.g. 192.168.0.10:8500,192.168.0.11:8500).|Only in the `default` mode| |192.168.0.10:8500|
1818
|DEBUG |Enables logging of each request sent through the proxy. Please consult [Debug Format](#debug-format) for info about the log entries. This feature should be used with caution. Do not use it in production unless necessary.|No|false|true|
19+
|DEBUG |Enables logging of each request sent through the proxy. Please consult [Debug Format](#debug-format) for info about the log entries. This feature should be used with caution. **Do not enable debugging in production unless necessary.**|No|false|true|
20+
|DEBUG_ERRORS_ONLY |If set to `true`, only requests that resulted in an error, timeout, retry, and redispatch will be logged. If a request is HTTP, responses with a status 5xx will be logged too.|No|false|true|
1921
|DEFAULT_PORTS |The default ports used by the proxy. Multiple values can be separated with comma (`,`). If a port should be for SSL connections, append it with `:ssl.|No|80,443:ssl| |
2022
|EXTRA_FRONTEND |Value will be added to the default `frontend` configuration.|No | | |
2123
|EXTRA_GLOBAL |Value will be added to the default `global` configuration.|No | | |
@@ -38,7 +40,7 @@ The following environment variables can be used to configure the *Docker Flow Pr
3840

3941
## Debug Format
4042

41-
If debugging is enabled, *Docker Flow Proxy* will log HTTP and TCP requests.
43+
If debugging is enabled through the environment variable `DEBUG`, *Docker Flow Proxy* will log HTTP and TCP requests in addition to the event requests.
4244

4345
### HTTP Requests Debug Format
4446

docs/debugging.md

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
While the decision to provide minimal logging is a good one when things are working correctly, you might find yourself in a situation when the proxy is not behaving as expected. In such a case, additional logging for a limited time can come in handy.
66

7+
!!! danger
8+
Do not enable debugging in production. It might severally impact *Docker Flow Proxy* performance.
9+
710
The examples that follow will show you how to enable *Docker Flow Proxy* debugging mode.
811

912
## Creating a Swarm Cluster
@@ -79,9 +82,6 @@ We can see log entries from the requests sent by `swarm-listener`, but there is
7982

8083
By default, debugging is disabled for a reason. It slows down the proxy. While that might not be noticeable in this demo, when working with thousands of requests per second, debugging can prove to be a bottleneck.
8184

82-
!!! danger
83-
Do not enable debugging in production.
84-
8585
We'll start by updating the `proxy` service.
8686

8787
```bash
@@ -118,8 +118,8 @@ Please go back to the other terminal and observe the logs.
118118
The relevant part of the output is as follows.
119119

120120
```
121-
HAPRoxy: 10.255.0.3:52639 [10/Mar/2017:13:18:00.780] services go-demo_main-be8080/go-demo_main 0/0/0/1/1 200 150 - - ---- 1/1/0/0/0 0/0 "GET /dem
122-
HAPRoxy: 10.255.0.3:52647 [10/Mar/2017:13:18:00.995] services services/<NOSRV> -1/-1/-1/-1/0 503 1271 - - SC-- 0/0/0/0/0 0/0 "GET /this/endpoint/
121+
HAPRoxy: 10.255.0.3:52639 [10/Mar/2017:13:18:00.780] services go-demo_main-be8080/go-demo_main 0/0/0/1/1 200 150 - - ---- 1/1/0/0/0 0/0 "GET /demo HTTP/1.1"
122+
HAPRoxy: 10.255.0.3:52647 [10/Mar/2017:13:18:00.995] services services/<NOSRV> -1/-1/-1/-1/0 503 1271 - - SC-- 0/0/0/0/0 0/0 "GET /this/endpoint/does/not/exist HTTP/1.1"
123123
```
124124

125125
As you can see, both requests were recorded.
@@ -212,6 +212,36 @@ HAPRoxy: 10.255.0.3:55569 [10/Mar/2017:16:15:40.806] tcpFE_6379 redis_main-be637
212212

213213
As you can see, the TCP request is recorded.
214214

215+
## Debugging Only Errors
216+
217+
Running the proxy in *debug* mode in production might severally impact *Docker Flow Proxy* performance. On the other, not having the relevant information might cause some operational problems. Ideally, you would use a specialized monitoring tool (e.g. Prometheus) that would collect metrics. However, there are cases when you do want to display debugging information directly in the proxy but to have the data limited to errors. Such a choice has much smaller impact on proxy performance then full debugging mode.
218+
219+
Debugging limited to errors can be enabled through the environment variable `DEBUG_ERRORS_ONLY`. Let's try it out.
220+
221+
```bash
222+
docker service update --env-add DEBUG_ERRORS_ONLY=true proxy_proxy
223+
```
224+
225+
We updated the `proxy` service by adding the environment variable `DEBUG_ERROR_ONLY`.
226+
227+
Now we should repeat the two requests we tried before.
228+
229+
```bash
230+
curl -i "http://$(docker-machine ip node-1)/demo/hello"
231+
232+
curl -i "http://$(docker-machine ip node-1)/this/endpoint/does/not/exist"
233+
```
234+
235+
The relevant parts of the `proxy` service log output is as follows.
236+
237+
```
238+
HAPRoxy: 10.255.0.3:59755 [10/Mar/2017:19:11:24.860] services services/<NOSRV> -1/-1/-1/-1/0 503 1271 - - SC-- 0/0/0/0/0 0/0 "GET /this/endpoint/does/not/exist HTTP/1.1"
239+
```
240+
241+
Even though we made two requests, only one was recorded in Docker logs.
242+
243+
With the environment variable `DEBUG_ERRORS_ONLY`, only requests that resulted in an error are output.
244+
215245
## What Now?
216246

217247
We are finished with the short introduction to *Docker Flow Proxy* debugging feature. We should destroy the demo cluster and free our resources for something else.

proxy/ha_proxy.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ func (m HaProxy) getConfigData() ConfigData {
225225
d.ExtraFrontend += `
226226
option httplog
227227
log global`
228+
if strings.EqualFold(GetSecretOrEnvVar("DEBUG_ERRORS_ONLY", ""), "true") {
229+
d.ExtraDefaults += `
230+
option dontlog-normal`
231+
}
228232
} else {
229233
d.ExtraDefaults += `
230234
option dontlognull
@@ -319,7 +323,7 @@ frontend tcpFE_%d
319323
port,
320324
port,
321325
)
322-
if strings.EqualFold(os.Getenv("DEBUG"), "true") {
326+
if strings.EqualFold(GetSecretOrEnvVar("DEBUG", ""), "true") {
323327
tmpl += `
324328
option tcplog
325329
log global`

proxy/ha_proxy_test.go

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,31 @@ func (s HaProxyTestSuite) Test_CreateConfigFromTemplates_AddsLogging_WhenDebug()
309309
s.Equal(expectedData, actualData)
310310
}
311311

312+
func (s HaProxyTestSuite) Test_CreateConfigFromTemplates_AddsDoNotLogNormal_WhenDebugErrorsOnlyIsSet() {
313+
debugOrig := os.Getenv("DEBUG")
314+
debugErrorsOnlyOrig := os.Getenv("DEBUG")
315+
defer func() {
316+
os.Setenv("DEBUG", debugOrig)
317+
os.Setenv("DEBUG_ERRORS_ONLY", debugErrorsOnlyOrig)
318+
}()
319+
os.Setenv("DEBUG", "true")
320+
os.Setenv("DEBUG_ERRORS_ONLY", "true")
321+
var actualData string
322+
expectedData := fmt.Sprintf(
323+
"%s%s",
324+
s.getTemplateWithLogsAndErrorsOnly(),
325+
s.ServicesContent,
326+
)
327+
writeFile = func(filename string, data []byte, perm os.FileMode) error {
328+
actualData = string(data)
329+
return nil
330+
}
331+
332+
NewHaProxy(s.TemplatesPath, s.ConfigsPath).CreateConfigFromTemplates()
333+
334+
s.Equal(expectedData, actualData)
335+
}
336+
312337
func (s HaProxyTestSuite) Test_CreateConfigFromTemplates_AddsExtraGlobal() {
313338
globalOrig := os.Getenv("EXTRA_GLOBAL")
314339
defer func() { os.Setenv("EXTRA_GLOBAL", globalOrig) }()
@@ -584,13 +609,7 @@ frontend tcpFE_1234
584609
acl domain_my-service-1 hdr(host) -i my-domain.com
585610
use_backend my-service-1-be1234 if domain_my-service-1
586611
acl domain_my-service-2 hdr(host) -i my-domain-1.com my-domain-2.com
587-
use_backend my-service-2-be1234 if domain_my-service-2
588-
589-
frontend tcpFE_5678
590-
bind *:5678
591-
mode tcp
592-
acl domain_my-service-2 hdr(host) -i my-domain-1.com my-domain-2.com
593-
use_backend my-service-2-be5678 if domain_my-service-2%s`,
612+
use_backend my-service-2-be1234 if domain_my-service-2%s`,
594613
tmpl,
595614
s.ServicesContent,
596615
)
@@ -612,7 +631,6 @@ frontend tcpFE_5678
612631
ServiceName: "my-service-2",
613632
ServiceDest: []ServiceDest{
614633
{SrcPort: 1234, Port: "4321"},
615-
{SrcPort: 5678, Port: "8765"},
616634
},
617635
ServiceDomain: []string{"my-domain-1.com", "my-domain-2.com"},
618636
}
@@ -1357,6 +1375,28 @@ func (s *HaProxyTestSuite) getTemplateWithLogs() string {
13571375
return tmpl
13581376
}
13591377

1378+
func (s *HaProxyTestSuite) getTemplateWithLogsAndErrorsOnly() string {
1379+
tmpl := strings.Replace(s.TemplateContent, "tune.ssl.default-dh-param 2048", "tune.ssl.default-dh-param 2048\n log 127.0.0.1:1514 local0", -1)
1380+
tmpl = strings.Replace(tmpl, " option dontlognull\n", "", -1)
1381+
tmpl = strings.Replace(
1382+
tmpl,
1383+
`frontend services
1384+
bind *:80
1385+
bind *:443
1386+
mode http
1387+
`,
1388+
`frontend services
1389+
bind *:80
1390+
bind *:443
1391+
mode http
1392+
1393+
option httplog
1394+
log global`,
1395+
-1,
1396+
)
1397+
return tmpl
1398+
}
1399+
13601400
// Mocks
13611401

13621402
type FileInfoMock struct {

0 commit comments

Comments
 (0)