Pipe Docker log output to STDOUT
Learn how to route application log files to standard output for centralized container logging.
Lesson Content
Anything written to append-only files within containers should be piped to standard output (STDOUT). This makes application logs easy to diagnose and prevents append-only files from consuming disk space.
Some widely used Docker images, such as Nginx, already pipe their logs to STDOUT. You may still have an application-specific log file that you want to apply the same approach to. For example, this Node application overrides console.log() and writes every call to a file named debug.log:
var fs = require('fs');
var util = require('util');
var logFile = fs.createWriteStream(__dirname + '/debug.log', {flags : 'w'});
console.log = (d) => {
logFile.write(util.format(d) + '\n');
};
var i = 0;
var log = () => {
console.log(`foo bar ${i}`);
i++;
};
setInterval(log, 2000);Node’s original console.log() already writes to STDOUT, so this is a deliberately nonsensical example, but it shows how to redirect writes from a log file to STDOUT.
Run the script for a few moments:
node index.jsThen check the contents of debug.log:
cat debug.logThe output shows that the script is running and correctly writing to debug.log.
The Dockerfile starts with a Node base image, copies the application into the image, and runs it with the node command:
FROM mhart/alpine-node
COPY index.js .
CMD node index.jsTo redirect those writes to STDOUT, add a RUN instruction before the CMD instruction. Use ln -sf to create a symbolic link from /debug.log to /dev/stdout:
FROM mhart/alpine-node
COPY index.js .
RUN ln -sf /dev/stdout /debug.log
CMD node index.jsWhatever would normally be written to debug.log is now piped straight to the container’s standard output.
Build the image and run a container in daemon mode:
docker build -t foo .
docker run -d --name=foo fooUse docker logs with -f to follow the container output:
docker logs -f fooThe messages that would normally be written to debug.log now appear in the container logs:
foo bar 0
foo bar 1
foo bar 2
foo bar 3
foo bar 4You can also confirm that nothing is written to debug.log inside the container:
docker exec -it foo cat /debug.logThe application keeps its existing file path while sending its output to STDOUT, where Docker can collect and display it without the container accumulating disk space over time.
Join the discussion!
Comments
Want to comment on this lesson?
Log in to leave comments.