MCPcopy
hub / github.com/gliderlabs/logspout

github.com/gliderlabs/logspout @v3.2.14 sqlite

repository ↗ · DeepWiki ↗ · release v3.2.14 ↗
234 symbols 603 edges 24 files 75 documented · 32%
README

logspout

CircleCI Docker pulls IRC Channel

Docker Hub automated builds for gliderlabs/logspout:latest and progrium/logspout:latest are now pointing to the release branch. For master, use gliderlabs/logspout:master. Individual versions are also available as saved images in releases.

Logspout is a log router for Docker containers that runs inside Docker. It attaches to all containers on a host, then routes their logs wherever you want. It also has an extensible module system.

It's a mostly stateless log appliance. It's not meant for managing log files or looking at history. It is just a means to get your logs out to live somewhere else, where they belong.

For now it only captures stdout and stderr, but a module to collect container syslog is planned.

Getting logspout

Logspout is a very small Docker container (15.2MB virtual, based on Alpine). Pull the latest release from the index:

$ docker pull gliderlabs/logspout:latest

You can also download and load a specific version:

$ curl -s dl.gliderlabs.com/logspout/v2.tgz | docker load

Using logspout

Route all container output to remote syslog

The simplest way to use logspout is to just take all logs and ship to a remote syslog. Just pass a syslog URI (or several comma separated URIs) as the command. Here we show use of the tls encrypted transport option in the URI. Also, we always mount the Docker Unix socket with -v to /var/run/docker.sock:

$ docker run --name="logspout" \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    gliderlabs/logspout \
    syslog+tls://logs.papertrailapp.com:55555

logspout will gather logs from other containers that are started without the -t option and are configured with a logging driver that works with docker logs (journald and json-file).

To see what data is used for syslog messages, see the syslog adapter docs.

The container must be able to access the Docker Unix socket to mount it. This is typically a problem when namespace remapping is enabled. To disable remapping for the logspout container, pass the --userns=host flag to docker run, .. create, etc.

Ignoring specific containers

You can tell logspout to ignore specific containers by setting an environment variable when starting your container, like so:-

$ docker run -d -e 'LOGSPOUT=ignore' image

Or, by adding a label which you define by setting an environment variable when running logspout:

$ docker run --name="logspout" \
    -e EXCLUDE_LABEL=logspout.exclude \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    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:

$ docker run \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    gliderlabs/logspout \
    raw://192.168.10.10:5000?filter.name=*_db

$ docker run \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    gliderlabs/logspout \
    raw://192.168.10.10:5000?filter.id=3b6ba57db54a

$ docker run \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    gliderlabs/logspout \
    raw://192.168.10.10:5000?filter.sources=stdout%2Cstderr

# Forward logs from containers with both label 'a' starting with 'x', and label 'b' ending in 'y'.
$ docker run \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    gliderlabs/logspout \
    raw://192.168.10.10:5000?filter.labels=a:x*%2Cb:*y

Note that you must URL-encode parameter values such as the comma in filter.sources and filter.labels.

Multiple logging destinations

You can route to multiple destinations by comma-separating the URIs:

$ docker run \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    gliderlabs/logspout \
    raw://192.168.10.10:5000?filter.name=*_db,syslog+tls://logs.papertrailapp.com:55555?filter.name=*_app

Suppressing backlog tail

You can tell logspout to only display log entries since container "start" or "restart" event by setting a BACKLOG=false environment variable (equivalent to docker logs --since=0s):

$ docker run -d --name="logspout" \
    -e 'BACKLOG=false' \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    gliderlabs/logspout

The default behaviour is to output all logs since creation of the container (equivalent to docker logs --tail=all or simply docker logs).

NOTE: Use of this option may cause the first few lines of log output to be missed following a container being started, if the container starts outputting logs before logspout has a chance to see them. If consistent capture of every line of logs is critical to your application, you might want to test thoroughly and/or avoid this option (at the expense of getting the entire backlog for every restarting container). This does not affect containers that are removed and recreated.

Environment variable, TAIL

Whilst BACKLOG=false restricts the tail by setting the Docker Logs.Options.Since to time.Now(), another mechanism to restrict the tail is to set TAIL=n. Use of this mechanism avoids parsing the earlier content of the logfile which may have a speed advantage if the tail content is of no interest or has become corrupted.

Inspect log streams using curl

Using the httpstream module, you can connect with curl to see your local aggregated logs in realtime. You can do this without setting up a route URI.

$ docker run -d --name="logspout" \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    --publish=127.0.0.1:8000:80 \
    gliderlabs/logspout
$ curl http://127.0.0.1:8000/logs

You should see a nicely colored stream of all your container logs. You can filter by container name and more. You can also get JSON objects, or you can upgrade to WebSocket and get JSON logs in your browser.

See httpstream module for all options.

Create custom routes via HTTP

Using the routesapi module logspout can also expose a /routes resource to create and manage routes.

$ curl $(docker port `docker ps -lq` 8000)/routes \
    -X POST \
    -d '{"source": {"filter": "db", "types": ["stderr"]}, "target": {"type": "syslog", "addr": "logs.papertrailapp.com:55555"}}'

That example creates a new syslog route to Papertrail of only stderr for containers with db in their name.

Routes are stored on disk, so by default routes are ephemeral. You can mount a volume to /mnt/routes to persist them.

See routesapi module for all options.

Detecting timeouts in Docker log streams

Logspout relies on the Docker API to retrieve container logs. A failure in the API may cause a log stream to hang. Logspout can detect and restart inactive Docker log streams. Use the environment variable INACTIVITY_TIMEOUT to enable this feature. E.g.: INACTIVITY_TIMEOUT=1m for a 1-minute threshold.

Multiline logging

In order to enable multiline logging, you must first prefix your adapter with the multiline adapter:

$ docker run \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    gliderlabs/logspout \
    multiline+raw://192.168.10.10:5000?filter.name=*_db

Using the the above prefix enables multiline logging on all containers by default. To enable it only to specific containers set MULTILINE_ENABLE_DEFAULT=false for logspout, and use the LOGSPOUT_MULTILINE environment variable on the monitored container:

$ docker run -d -e 'LOGSPOUT_MULTILINE=true' image
MULTILINE_MATCH

Using the environment variable MULTILINE_MATCH= (default nonfirst) you define, which lines should be matched to the MULTILINE_PATTERN. * first: match first line only and append following messages until you match another line * last: concatenate all messages until the pattern matches the next line * nonlast: match a line, append upcoming matching lines, also append first non-matching line and start * nonfirst: append all matching lines to first line and start over with the next non-matching line

Important!

If you use multiline logging with raw, it's recommended to json encode the Data to avoid line breaks in the output, eg:

"RAW_FORMAT={{ toJSON .Data }}\n"

Environment variables

  • ALLOW_TTY - include logs from containers started with -t or --tty (i.e. Allocate a pseudo-TTY)
  • BACKLOG - suppress container tail backlog
  • TAIL - specify the number of lines in the log tail to capture when logspout starts (default all)
  • DEBUG - emit debug logs
  • EXCLUDE_LABEL - exclude containers with a given label. The label can have a value of true or a custom value matched with : after the label name like label_name:label_value.
  • INACTIVITY_TIMEOUT - detect hang in Docker API (default 0)
  • HTTP_BIND_ADDRESS - configure which interface address to listen on (default 0.0.0.0)
  • PORT or HTTP_PORT - configure which port to listen on (default 80)
  • RAW_FORMAT - log format for the raw adapter (default {{.Data}}\n)
  • RETRY_COUNT - how many times to retry a broken socket (default 10)
  • ROUTESPATH - path to routes (default /mnt/routes)
  • SYSLOG_DATA - datum for data field (default {{.Data}})
  • SYSLOG_FORMAT - syslog format to emit, either rfc3164 or rfc5424 (default rfc5424)
  • SYSLOG_HOSTNAME - datum for hostname field (default {{.Container.Config.Hostname}})
  • SYSLOG_PID - datum for pid field (default {{.Container.State.Pid}})
  • SYSLOG_PRIORITY - datum for priority field (default {{.Priority}})
  • SYSLOG_STRUCTURED_DATA - datum for structured data field
  • SYSLOG_TAG - datum for tag field (default {{.ContainerName}}+route.Options["append_tag"])
  • SYSLOG_TCP_FRAMING - for TCP or TLS transports, whether to use octet-counted framing in emitted messages or traditional LF framing (default traditional)
  • SYSLOG_TIMESTAMP - datum for timestamp field (default {{.Timestamp}})
  • MULTILINE_ENABLE_DEFAULT - enable multiline logging for all containers when using the multiline adapter (default true)
  • MULTILINE_MATCH - determines which lines the pattern should match, one of first|last|nonfirst|nonlast, for details see: MULTILINE_MATCH (default nonfirst)
  • MULTILINE_PATTERN - pattern for multiline logging, see: MULTILINE_MATCH (default: ^\s)
  • MULTILINE_FLUSH_AFTER - maximum time between the first and last lines of a multiline log entry in milliseconds (default: 500)
  • MULTILINE_SEPARATOR - separator between lines for output (default: \n)

Raw Format

The raw adapter has a function toJSON that can be used to format the message/fields to generate JSON-like output in a simple way, or full JSON output.

The RAW_FORMAT env variable is used as a Go template with a Message struct passed as data. You can access the following fields

  • Source - source stream name ("stdout", "stderr", ...)
  • Data - original log message
  • Time - a Go Time struct
  • Container - a go-dockerclient Container struct (see container.go source file for accessible fields)

Use examples:

Mixed JSON + generic:
{{ .Time.Format "2006-01-02T15:04:05Z07:00" }} { "container" : "{{ .Container.Name }}", "labels": {{ toJSON .Container.Config.Labels }}, "timestamp": "{{ .Time.Format "2006-01-02T15:04:05Z07:00" }}", "source" : "{{ .Source }}", "message": {{ toJSON .Data }} }
2017-10-26T11:59:32Z { "container" : "/catalogo_worker_1", "image": "sha256:e9bce6c17c80c603c4c8dbac2ad2285982d218f6ea0332f8b0fb84572941b773", "labels": {"com.docker.compose.config-hash":"4f9c3d3bfb2f65e29a4bc8a4a1b3f0a1c8a42323106a5e9106fe9279f8031321","com.docker.compose.container-number":"1","com.docker.compose.oneoff":"False","com.docker.compose.project":"catalogo","com.docker.compose.service":"worker","com.docker.compose.version":"1.16.1","logging":"true"}, "timestamp": "2017-10-26T11:59:32Z", "source" : "stdout", "message": "2017-10-26 11:59:32,950 INFO success: command_bus_0 entered RUNNING state, process has stayed up for \u003e than 1 seconds (startsecs)" }
Full JSON like:
{ "container" : "{{ .Container.Name }}", "labels": {{ toJSON .Container.Config.Labels }}, "timestamp": "{{ .Time.Format "2006-01-02T15:04:05Z07:00" }}", "source" : "{{ .Source }}", "message": {{ toJSON .Data }} }

```json { "container": "/a_container", "image": "sh

Extension points exported contracts — how you extend this code

LogAdapter (Interface)
LogAdapter is a streamed log [5 implementers]
router/types.go
Job (Interface)
Job is a thing to be done [3 implementers]
router/types.go
LogRouter (Interface)
LogRouter sends logs to LogAdapters via Routes [2 implementers]
router/types.go
RouteStore (Interface)
RouteStore is a collections of Routes [1 implementers]
router/types.go
HTTPHandler (FuncType)
HTTPHandler is an extension type for adding HTTP endpoints
router/types.go

Core symbols most depended-on inside this repo

GetEnvDefault
called by 22
cfg/cfg.go
Register
called by 17
router/extpoints.go
Add
called by 16
router/types.go
debug
called by 14
router/pump.go
debug
called by 11
adapters/syslog/syslog.go
all
called by 10
router/extpoints.go
Get
called by 9
router/types.go
Close
called by 9
router/types.go

Shape

Method 102
Function 95
Struct 23
TypeAlias 7
Interface 5
FuncType 2

Languages

Go100%

Modules by API surface

router/extpoints.go39 symbols
router/types.go30 symbols
router/pump.go26 symbols
adapters/syslog/syslog.go25 symbols
router/pump_test.go16 symbols
router/routes.go14 symbols
adapters/syslog/syslog_test.go10 symbols
httpstream/httpstream.go9 symbols
transports/tls/tls_test.go8 symbols
router/persist.go8 symbols
adapters/multiline/multiline_test.go7 symbols
adapters/multiline/multiline.go7 symbols

Dependencies from manifests, versioned

github.com/Microsoft/hcsshimv0.8.14 · 1×
github.com/Sirupsen/logrusv0.10.1-0.2016060111 · 1×
github.com/containerd/cgroupsv0.0.0-2021011418195 · 1×
github.com/containerd/continuityv0.0.0-2020120814235 · 1×
github.com/docker/dockerv20.10.3+incompatibl · 1×
github.com/docker/engine-apiv0.3.2-0.20160708123 · 1×
github.com/gorilla/contextv0.0.0-2016052520331 · 1×
github.com/hashicorp/go-cleanhttpv0.0.0-2016040717412 · 1×

For agents

$ claude mcp add logspout \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact