Skip to content

Commit

Permalink
Merge pull request #470 from gliderlabs/master
Browse files Browse the repository at this point in the history
release 3.2.9
  • Loading branch information
michaelshobbs committed May 1, 2020
2 parents 11b8eaa + 4bfb0d6 commit 67fdc40
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 15 deletions.
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ All notable changes to this project will be documented in this file.

### Changed

## [v3.2.9] - 2020-04-30
### Fixed
- @bbigras add missing syntax highlighting in README.md

### Added
- @edorgeville Adds `db` log driver to `logDriverSupported`
- @renehernandez Add support for multiple exclusion labels
- @renehernandez Add support for EXCLUDE_LABELS envvar with fallback to existing EXCLUDE_LABEL
- @hhromic adapters/syslog: add ContainerNameSplitN utility message function

### Changed
- @hhromic adapters/syslog: enforce RFC size limits in message fields

## [v3.2.8] - 2020-04-03
### Changed
- @michaelshobbs bump alpine to 3.11 and go to 1.13.4-r1
Expand Down Expand Up @@ -214,7 +227,8 @@ All notable changes to this project will be documented in this file.
- Base container is now Alpine
- Moved to gliderlabs organization

[unreleased]: https://github.com/gliderlabs/logspout/compare/v3.2.8...HEAD
[unreleased]: https://github.com/gliderlabs/logspout/compare/v3.2.9...HEAD
[v3.2.9]: https://github.com/gliderlabs/logspout/compare/v3.2.8...v3.2.9
[v3.2.8]: https://github.com/gliderlabs/logspout/compare/v3.2.7...v3.2.8
[v3.2.7]: https://github.com/gliderlabs/logspout/compare/v3.2.6...v3.2.7
[v3.2.6]: https://github.com/gliderlabs/logspout/compare/v3.2.5...v3.2.6
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ Or, by adding a label which you define by setting an environment variable when r
gliderlabs/logspout
$ docker run -d --label logspout.exclude=true image

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:

$ $ docker run --name="logspout" \
-e EXCLUDE_LABELS=k8s:app;backend:rails;io.kubernetes.pod.namespace:default \
--volume=/var/run/docker.sock:/var/run/docker.sock \
gliderlabs/logspout
$ docker run -d --label k8s=app image1
$ docker run -d --label backend=rails image2

**NOTE** Setting `EXCLUDE_LABELS` would take precedence over setting `EXCLUDE_LABEL`

#### Including specific containers

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

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

```
```yml
version: "3"
networks:
logging:
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v3.2.8
v3.2.9
17 changes: 15 additions & 2 deletions adapters/syslog/syslog.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,18 @@ func NewSyslogAdapter(route *router.Route) (router.LogAdapter, error) {
var tmplStr string
switch format {
case "rfc5424":
tmplStr = fmt.Sprintf("<%s>1 %s %s %s %s - %s %s\n",
// notes from RFC:
// - there is no upper limit for the entire message and depends on the transport in use
// - the HOSTNAME field must not exceed 255 characters
// - the TAG field must not exceed 48 characters
// - the PROCID field must not exceed 128 characters
tmplStr = fmt.Sprintf("<%s>1 %s %.255s %.48s %.128s - %s %s\n",
priority, timestamp, hostname, tag, pid, structuredData, data)
case "rfc3164":
tmplStr = fmt.Sprintf("<%s>%s %s %s[%s]: %s\n",
// notes from RFC:
// - the entire message must be <= 1024 bytes
// - the TAG field must not exceed 32 characters
tmplStr = fmt.Sprintf("<%s>%s %s %.32s[%s]: %s\n",
priority, timestamp, hostname, tag, pid, data)
default:
return nil, errors.New("unsupported syslog format: " + format)
Expand Down Expand Up @@ -259,3 +267,8 @@ func (m *Message) Timestamp() string {
func (m *Message) ContainerName() string {
return m.Message.Container.Name[1:]
}

// ContainerNameSplitN returns the message's container name sliced at most "n" times using "sep"
func (m *Message) ContainerNameSplitN(sep string, n int) []string {
return strings.SplitN(m.ContainerName(), sep, n)
}
31 changes: 21 additions & 10 deletions router/pump.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func normalID(id string) string {

func logDriverSupported(container *docker.Container) bool {
switch container.HostConfig.LogConfig.Type {
case "json-file", "journald":
case "json-file", "journald", "db":
return true
default:
return false
Expand All @@ -89,17 +89,28 @@ func ignoreContainer(container *docker.Container) bool {
}
}

excludeLabel := cfg.GetEnvDefault("EXCLUDE_LABEL", "")
excludeValue := "true"
// support EXCLUDE_LABEL having a custom label value
excludeLabelArr := strings.Split(excludeLabel, ":")
if len(excludeLabelArr) == 2 {
excludeValue = excludeLabelArr[1]
excludeLabel = excludeLabelArr[0]
excludeLabel := cfg.GetEnvDefault("EXCLUDE_LABELS", "")

if excludeLabel == "" {
excludeLabel = cfg.GetEnvDefault("EXCLUDE_LABEL", "")
}
excludeValue := "true"
// support EXCLUDE_LABEL having multiple custom label values
excludeLabelArr := strings.Split(excludeLabel, ";")

for _, label := range excludeLabelArr {
labelParts := strings.Split(label, ":")

if value, ok := container.Config.Labels[excludeLabel]; ok {
return len(excludeLabel) > 0 && strings.EqualFold(value, strings.ToLower(excludeValue))
if len(labelParts) == 2 {
excludeLabel = labelParts[0]
excludeValue = labelParts[1]
}

if value, ok := container.Config.Labels[excludeLabel]; ok {
if len(excludeLabel) > 0 && strings.EqualFold(value, strings.ToLower(excludeValue)) {
return true
}
}
}
return false
}
Expand Down
39 changes: 39 additions & 0 deletions router/pump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,45 @@ func TestPumpIgnoreContainerCustomLabels(t *testing.T) {
}
}

func TestPumpIgnoreContainersMatchingAtLeastOneLabel(t *testing.T) {
os.Setenv("EXCLUDE_LABEL", "k8s-app:canal;io.kubernetes.pod.namespace:default")
defer os.Unsetenv("EXCLUDE_LABEL")
containers := []struct {
in *docker.Config
out bool
}{
{&docker.Config{Labels: map[string]string{"k8s-app": "canal"}}, true},
{&docker.Config{Labels: map[string]string{"app": "demo-app"}}, false},
{&docker.Config{Labels: map[string]string{"io.kubernetes.pod.namespace": "kube-system"}}, false},
{&docker.Config{Labels: map[string]string{"io.kubernetes.pod.namespace": "default"}}, true},
}

for _, conf := range containers {
if actual := ignoreContainer(&docker.Container{Config: conf.in}); actual != conf.out {
t.Errorf("expected %v got %v", conf.out, actual)
}
}
}

func TestPumpIgnoreContainerCustomLabelsUsingExcludeLabelsEnvVar(t *testing.T) {
os.Setenv("EXCLUDE_LABELS", "k8s-app:canal;io.kubernetes.pod.namespace:production")
defer os.Unsetenv("EXCLUDE_LABELS")
containers := []struct {
in *docker.Config
out bool
}{
{&docker.Config{Labels: map[string]string{"k8s-app": "canal"}}, true},
{&docker.Config{Labels: map[string]string{"app": "demo-app"}}, false},
{&docker.Config{Labels: map[string]string{"io.kubernetes.pod.namespace": "production"}}, true},
}

for _, conf := range containers {
if actual := ignoreContainer(&docker.Container{Config: conf.in}); actual != conf.out {
t.Errorf("expected %v got %v", conf.out, actual)
}
}
}

func TestPumpIgnoreContainerAllowTTYDefault(t *testing.T) {
containers := []struct {
in *docker.Config
Expand Down

0 comments on commit 67fdc40

Please sign in to comment.