Which Docker log drivers can serve logs back to docker logs, and what happens with the others?
answer
- The engine keeps no log store
- Three drivers can replay, the rest cannot
- A cache was added so reads still work
- Its options all begin with the same prefix
- One driver is unreadable by construction
basics
~20 sOnly json-file, local and journald keep messages where the daemon can replay them. Shipping drivers send them away, so since Docker 20.10 the daemon writes a bounded local cache to answer reads; the none driver is never readable.
solid answer
~40 sReading a container's logs is a *driver capability*, not a universal engine feature. **json-file**, **local** and **journald** keep the messages somewhere the daemon can query, so they serve reads natively. The shipping drivers — **fluentd**, **gelf**, **syslog**, **splunk**, **awslogs**, **gcplogs** — hand each message to a remote endpoint and keep nothing, and on older engines that meant an empty read and the error `configured logging driver does not support reading`. Docker **20.10** added *dual logging*: alongside a non-reading driver the daemon also writes a bounded local-driver cache purely to answer reads, tuned with the `cache-disabled`, `cache-max-size`, `cache-max-file` and `cache-compress` log options. So on a modern engine an on-call engineer keeps a short local window even when logs ship to a collector. The `none` driver keeps nothing and is never readable.
go deeper
Know that a container's logs come from whichever driver it was started with, and that shipping drivers send output off the host instead of keeping it. You are not expected to recall the cache options.
Explain which drivers replay natively — json-file, local, journald — and why a shipping driver keeps nothing locally, plus what dual logging adds on a current engine.
Show a diagnostic order for an empty read: the container's real LogConfig, the driver's read capability, whether the cache is disabled, whether the app writes to stdout at all, and whether rotation already discarded the lines.
Decide deliberately how much on-host readable history the fleet keeps versus what lives in the log backend, and make sure that decision is not accidentally made by someone disabling the cache to reclaim disk.
## Reading back is a property of the driver The engine has no log store of its own. When you ask for a container's logs, `dockerd` asks that container's **logging driver** to replay them, and only some drivers can. That is the whole shape of the question, and it explains the war story it is usually asked as: somebody switched the fleet to a shipping driver, and the next incident began with a completely empty read against a container that was obviously producing output. **Drivers that can replay natively:** - **json-file** — reads its own `-json.log` files, including the rotated (and, if `compress` is on, gzipped) ones. - **local** — reads its own compact files, likewise across rotations. - **journald** — queries the systemd journal, which is a real store with its own index; entries are also reachable directly with `journalctl` filtered by container name or id. **Drivers that cannot:** `syslog`, `gelf`, `fluentd`, `splunk`, `awslogs`, `gcplogs` — each is a one-way pipe to something outside the engine. The engine will not go and query that backend on your behalf; retrieval there is the backend's own query language and tooling. And **`none`** discards everything, so nothing is readable by construction. ## Dual logging: why a modern engine still answers Docker Engine **20.10** introduced *dual logging* to remove exactly this cliff. When a container uses a driver that cannot serve reads, the daemon additionally writes the same messages to a bounded ring of **local**-driver files, used for nothing except answering read requests. The effect is that `docker logs` works on virtually every driver on a current engine, showing a recent window even though the authoritative copy is in a collector somewhere. It is tuned with log options that mirror the local driver's own: - `cache-disabled` — turn the cache off entirely (then reads fail as they did before 20.10) - `cache-max-size`, `cache-max-file` — bound the cache, the same size × count arithmetic as normal rotation - `cache-compress` — compress the rotated cache files Two consequences follow. First, on a host using a shipping driver you are still spending disk on logs, and that budget must be accounted for. Second, if someone has set `cache-disabled=true` to reclaim that disk, the empty-read failure mode is back — and it will be discovered during an incident, not before one. ## Diagnosing an empty read When a container's logs come back empty, work down the ownership chain rather than guessing: 1. **Which driver is this container actually using?** Not what `daemon.json` says today — log configuration is frozen at container creation, so a container started last month may be on a different driver than the current default. `docker inspect` shows the container's real `LogConfig`. 2. **Can that driver read?** If it is `none`, stop: there is nothing anywhere. If it is a shipping driver, check the engine version and whether `cache-disabled` is set. 3. **Did the driver ever get anything?** Only `stdout` and `stderr` are captured. An application logging to a file inside the container produces an empty read on *every* driver, and no driver change will fix it. 4. **Has rotation already discarded it?** With a tight `max-size × max-file` bound, a burst of output can push the interesting lines out within minutes. An empty-looking window is sometimes a rotation problem wearing a driver problem's clothes. ## Design implications The practical rule is that **the driver decides who can investigate and with what tool**. Choosing journald hands retrieval to the host's journal and everything that already reads it. Choosing a shipping driver hands the authoritative copy to a log backend and leaves you a short cached window locally. Choosing json-file or local keeps everything on the host, which is excellent for one machine and useless the moment the host is gone. Most fleets end up wanting both properties: an on-host copy short enough to be cheap and long enough for an on-call engineer to read directly, plus a durable copy elsewhere. Dual logging gives the first almost for free; deciding what the second is, and who owns it, belongs to the logging architecture rather than to the engine. One last nuance about the file-based drivers: replaying is not free. Both json-file and local read across rotated generations, and when `compress` is on the rotated files must be decompressed to be read, which costs CPU and temporary space at exactly the moment somebody is trying to work quickly. It is a small effect at 10 MB files and a noticeable one when a team has set a very large bound to keep more history locally. If reads have to be fast and wide, that is a signal the history belongs in a log backend built for querying rather than in bigger files on the host — the engine's replay is a convenience for one container, not a search tool.
- A container on a modern engine uses the fluentd driver and reading its logs still returns nothing. What do you check?First whether `cache-disabled=true` is set on that container, which switches off the local read cache dual logging relies on. Then whether the container is really on fluentd at all — log configuration is frozen at creation, so `docker inspect` is authoritative, not `daemon.json`. Then whether the application writes to stdout and stderr at all, since a file-logging app reads empty on every driver. Finally, whether the cache bound is so small that a burst already rotated the interesting lines away.
- How does journald change who can read a container's logs, compared with json-file?journald puts the messages into the host's systemd journal, so anyone with journal access can query them with the journal's own tooling and filters, alongside every other service on the machine, and retention is governed by the journal's configuration rather than by `max-size` and `max-file`. json-file keeps a private file per container that in practice only the daemon and root read. The engine can replay from either.
- Does the local read cache mean logs are safe if the collector is down?Only for a short window, and only for reading — it is a bounded ring of files sized by `cache-max-size` and `cache-max-file`, not a store-and-forward queue. Messages that could not be delivered are not replayed to the backend when it recovers. Treat it as a convenience for on-call reads, and put real delivery durability in the collector tier.
saying these in an interview costs you the question
- Assumes docker logs works identically on every driver
- Thinks the daemon queries the remote log backend for you
- Believes the local read cache buffers for later delivery
- Trusts daemon.json over the container's own LogConfig
- Cannot name a driver that serves reads natively
- Expects logs from a container that never writes to stdout