Docker – How to write docker output to stdout/stderr as daemon

docker

So we can run a docker container as a daemon:

docker run -d --name foo foo

and then read the logs:

docker logs -f foo

but I am wondering how to only write to stdout/stderr, so that I can send the logs to splunk or cloudwatch etc. Something like:

(
  docker run --name foo foo &|  capture_logs
) & disown

what is the official way to do this?

Best Answer

You can use logging options as @Michael pointed out and as described in the following docs

Generally speaking there are at least two ways to do it which will be discussed briefly below.

  1. Using splunk driver as shown in here.

Start by creating an event collector token as described in the docs. The token will be used within splunk driver configuration.

docker cli example

docker run -d \
           --log-driver=splunk \
           --log-opt splunk-token=176FCEBF-4CF5-4EDF-91BC-703796522D20 \
           --log-opt splunk-url=https://splunkhost:8088 \
           --log-opt tag=foo-logs \
           --name foo foo

docker-compose example

version: '3.7'
services:
  foo_app:
  ...
  logging:
    driver: splunk
    options:
      tag: foo-logs
      splunk-token: 176FCEBF-4CF5-4EDF-91BC-703796522D20
      splunk-url: https://splunkhost:8088
  ...
  1. Using syslog driver as shown in here.

docker cli example:

docker run \
      -–log-driver syslog –-log-opt tag=foo-logs \
      --name foo foo

docker-compose example:

version: '3.7'
services:
  foo_app:
  ...
  logging:
    driver: syslog
    options:
      tag: foo-logs
  ...

This will send all container logs to local syslog, you can take it from there and forward these to external udp port where splunk is ready to receive your logs.

So lets say that the Splunk server will receive the logs on port 514 then you need to add this to rsyslogd configuration and then restart rsyslogd service

# /etc/rsyslog.d/20-splunk.conf
:syslogtag, contains, "foo-logs" @splunk_url:514;RSYSLOG_SyslogProtocol23Format

Alternatively, if you intend to make it global for all containers then you can configure the logging through the /etc/docker/daemon.json file itself like below (and don't forget to restart the docker service):

In case of syslog

{
  "log-driver": "syslog"
}

In case of splunk

{
  "log-driver": "splunk",
  "log-opts": {
    "splunk-token": "176FCEBF-4CF5-4EDF-91BC-703796522D20",
    "splunk-url": "https://splunkhost:8088",
    ...
  }
}

Checkout the list of supported logging driver