Skip to content

Commit 67fdc40

Browse files
Merge pull request #470 from gliderlabs/master
release 3.2.9
2 parents 11b8eaa + 4bfb0d6 commit 67fdc40

File tree

6 files changed

+103
-15
lines changed

6 files changed

+103
-15
lines changed

CHANGELOG.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ All notable changes to this project will be documented in this file.
1010

1111
### Changed
1212

13+
## [v3.2.9] - 2020-04-30
14+
### Fixed
15+
- @bbigras add missing syntax highlighting in README.md
16+
17+
### Added
18+
- @edorgeville Adds `db` log driver to `logDriverSupported`
19+
- @renehernandez Add support for multiple exclusion labels
20+
- @renehernandez Add support for EXCLUDE_LABELS envvar with fallback to existing EXCLUDE_LABEL
21+
- @hhromic adapters/syslog: add ContainerNameSplitN utility message function
22+
23+
### Changed
24+
- @hhromic adapters/syslog: enforce RFC size limits in message fields
25+
1326
## [v3.2.8] - 2020-04-03
1427
### Changed
1528
- @michaelshobbs bump alpine to 3.11 and go to 1.13.4-r1
@@ -214,7 +227,8 @@ All notable changes to this project will be documented in this file.
214227
- Base container is now Alpine
215228
- Moved to gliderlabs organization
216229

217-
[unreleased]: https://github.com/gliderlabs/logspout/compare/v3.2.8...HEAD
230+
[unreleased]: https://github.com/gliderlabs/logspout/compare/v3.2.9...HEAD
231+
[v3.2.9]: https://github.com/gliderlabs/logspout/compare/v3.2.8...v3.2.9
218232
[v3.2.8]: https://github.com/gliderlabs/logspout/compare/v3.2.7...v3.2.8
219233
[v3.2.7]: https://github.com/gliderlabs/logspout/compare/v3.2.6...v3.2.7
220234
[v3.2.6]: https://github.com/gliderlabs/logspout/compare/v3.2.5...v3.2.6

README.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ Or, by adding a label which you define by setting an environment variable when r
5353
gliderlabs/logspout
5454
$ docker run -d --label logspout.exclude=true image
5555

56+
Logspout also allows to ignore containers by specifying a list of labels using the environment variables `EXCLUDE_LABELS` or `EXCLUDE_LABEL`, using the `;` as separator:
57+
58+
$ $ docker run --name="logspout" \
59+
-e EXCLUDE_LABELS=k8s:app;backend:rails;io.kubernetes.pod.namespace:default \
60+
--volume=/var/run/docker.sock:/var/run/docker.sock \
61+
gliderlabs/logspout
62+
$ docker run -d --label k8s=app image1
63+
$ docker run -d --label backend=rails image2
64+
65+
**NOTE** Setting `EXCLUDE_LABELS` would take precedence over setting `EXCLUDE_LABEL`
66+
5667
#### Including specific containers
5768

5869
You can tell logspout to only include certain containers by setting filter parameters on the URI:
@@ -243,7 +254,7 @@ Use examples:
243254

244255
In a swarm, logspout is best deployed as a global service. When running logspout with 'docker run', you can change the value of the hostname field using the `SYSLOG_HOSTNAME` environment variable as explained above. However, this does not work in a compose file because the value for `SYSLOG_HOSTNAME` will be the same for all logspout "tasks", regardless of the docker host on which they run. To support this mode of deployment, the syslog adapter will look for the file `/etc/host_hostname` and, if the file exists and it is not empty, will configure the hostname field with the content of this file. You can then use a volume mount to map a file on the docker hosts with the file `/etc/host_hostname` in the container. The sample compose file below illustrates how this can be done
245256

246-
```
257+
```yml
247258
version: "3"
248259
networks:
249260
logging:

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v3.2.8
1+
v3.2.9

adapters/syslog/syslog.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,18 @@ func NewSyslogAdapter(route *router.Route) (router.LogAdapter, error) {
9292
var tmplStr string
9393
switch format {
9494
case "rfc5424":
95-
tmplStr = fmt.Sprintf("<%s>1 %s %s %s %s - %s %s\n",
95+
// notes from RFC:
96+
// - there is no upper limit for the entire message and depends on the transport in use
97+
// - the HOSTNAME field must not exceed 255 characters
98+
// - the TAG field must not exceed 48 characters
99+
// - the PROCID field must not exceed 128 characters
100+
tmplStr = fmt.Sprintf("<%s>1 %s %.255s %.48s %.128s - %s %s\n",
96101
priority, timestamp, hostname, tag, pid, structuredData, data)
97102
case "rfc3164":
98-
tmplStr = fmt.Sprintf("<%s>%s %s %s[%s]: %s\n",
103+
// notes from RFC:
104+
// - the entire message must be <= 1024 bytes
105+
// - the TAG field must not exceed 32 characters
106+
tmplStr = fmt.Sprintf("<%s>%s %s %.32s[%s]: %s\n",
99107
priority, timestamp, hostname, tag, pid, data)
100108
default:
101109
return nil, errors.New("unsupported syslog format: " + format)
@@ -259,3 +267,8 @@ func (m *Message) Timestamp() string {
259267
func (m *Message) ContainerName() string {
260268
return m.Message.Container.Name[1:]
261269
}
270+
271+
// ContainerNameSplitN returns the message's container name sliced at most "n" times using "sep"
272+
func (m *Message) ContainerNameSplitN(sep string, n int) []string {
273+
return strings.SplitN(m.ContainerName(), sep, n)
274+
}

router/pump.go

+21-10
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func normalID(id string) string {
7474

7575
func logDriverSupported(container *docker.Container) bool {
7676
switch container.HostConfig.LogConfig.Type {
77-
case "json-file", "journald":
77+
case "json-file", "journald", "db":
7878
return true
7979
default:
8080
return false
@@ -89,17 +89,28 @@ func ignoreContainer(container *docker.Container) bool {
8989
}
9090
}
9191

92-
excludeLabel := cfg.GetEnvDefault("EXCLUDE_LABEL", "")
93-
excludeValue := "true"
94-
// support EXCLUDE_LABEL having a custom label value
95-
excludeLabelArr := strings.Split(excludeLabel, ":")
96-
if len(excludeLabelArr) == 2 {
97-
excludeValue = excludeLabelArr[1]
98-
excludeLabel = excludeLabelArr[0]
92+
excludeLabel := cfg.GetEnvDefault("EXCLUDE_LABELS", "")
93+
94+
if excludeLabel == "" {
95+
excludeLabel = cfg.GetEnvDefault("EXCLUDE_LABEL", "")
9996
}
97+
excludeValue := "true"
98+
// support EXCLUDE_LABEL having multiple custom label values
99+
excludeLabelArr := strings.Split(excludeLabel, ";")
100+
101+
for _, label := range excludeLabelArr {
102+
labelParts := strings.Split(label, ":")
100103

101-
if value, ok := container.Config.Labels[excludeLabel]; ok {
102-
return len(excludeLabel) > 0 && strings.EqualFold(value, strings.ToLower(excludeValue))
104+
if len(labelParts) == 2 {
105+
excludeLabel = labelParts[0]
106+
excludeValue = labelParts[1]
107+
}
108+
109+
if value, ok := container.Config.Labels[excludeLabel]; ok {
110+
if len(excludeLabel) > 0 && strings.EqualFold(value, strings.ToLower(excludeValue)) {
111+
return true
112+
}
113+
}
103114
}
104115
return false
105116
}

router/pump_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,45 @@ func TestPumpIgnoreContainerCustomLabels(t *testing.T) {
9292
}
9393
}
9494

95+
func TestPumpIgnoreContainersMatchingAtLeastOneLabel(t *testing.T) {
96+
os.Setenv("EXCLUDE_LABEL", "k8s-app:canal;io.kubernetes.pod.namespace:default")
97+
defer os.Unsetenv("EXCLUDE_LABEL")
98+
containers := []struct {
99+
in *docker.Config
100+
out bool
101+
}{
102+
{&docker.Config{Labels: map[string]string{"k8s-app": "canal"}}, true},
103+
{&docker.Config{Labels: map[string]string{"app": "demo-app"}}, false},
104+
{&docker.Config{Labels: map[string]string{"io.kubernetes.pod.namespace": "kube-system"}}, false},
105+
{&docker.Config{Labels: map[string]string{"io.kubernetes.pod.namespace": "default"}}, true},
106+
}
107+
108+
for _, conf := range containers {
109+
if actual := ignoreContainer(&docker.Container{Config: conf.in}); actual != conf.out {
110+
t.Errorf("expected %v got %v", conf.out, actual)
111+
}
112+
}
113+
}
114+
115+
func TestPumpIgnoreContainerCustomLabelsUsingExcludeLabelsEnvVar(t *testing.T) {
116+
os.Setenv("EXCLUDE_LABELS", "k8s-app:canal;io.kubernetes.pod.namespace:production")
117+
defer os.Unsetenv("EXCLUDE_LABELS")
118+
containers := []struct {
119+
in *docker.Config
120+
out bool
121+
}{
122+
{&docker.Config{Labels: map[string]string{"k8s-app": "canal"}}, true},
123+
{&docker.Config{Labels: map[string]string{"app": "demo-app"}}, false},
124+
{&docker.Config{Labels: map[string]string{"io.kubernetes.pod.namespace": "production"}}, true},
125+
}
126+
127+
for _, conf := range containers {
128+
if actual := ignoreContainer(&docker.Container{Config: conf.in}); actual != conf.out {
129+
t.Errorf("expected %v got %v", conf.out, actual)
130+
}
131+
}
132+
}
133+
95134
func TestPumpIgnoreContainerAllowTTYDefault(t *testing.T) {
96135
containers := []struct {
97136
in *docker.Config

0 commit comments

Comments
 (0)