mirror of
https://github.com/moby/moby.git
synced 2026-08-12 22:16:46 +00:00
This adds support for streaming logs as JSON stream either through an
"Accept" header ("application/jsonl", "application/x-ndjson", or
"application/json-seq"), or through a `format=json` query variable.
By default log messages are included as UTF-8 encoded strings, which should
work for regular logs, but can be lossy.
```bash
docker rm -fv my-container3
docker run \
-qit \
--name my-container3 \
--label=labelA=foo \
--label=labelB=bar \
--log-opt labels=labelA,labelB \
ubuntu bash
```
Inside the container:
```bash
root@b36bfcd439e9:/# echo {1..9} && exit
1 2 3 4 5 6 7 8 9
exit
```
With the message encoded as utf-8;
```bash
curl -s --unix-socket /var/run/docker.sock 'http://localhost/v1.54/containers/my-container3/logs?stdout=1&stderr=1&format=json' | jq .
{
"Line": "\u001b[?2004h\u001b]0;root@1065b85dd167: /\u0007root@1065b85dd167:/# \u001b[7mecho {1..9} && exit\u001b[27m\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\becho {1..9} && exit\r\n",
"Source": "stdout",
"Timestamp": "2026-02-20T15:39:01.083531419Z"
}
{
"Line": "\u001b[?2004l\r1 2 3 4 5 6 7 8 9\r\n",
"Source": "stdout",
"Timestamp": "2026-02-20T15:39:01.088152377Z"
}
{
"Line": "exit\r\n",
"Source": "stdout",
"Timestamp": "2026-02-20T15:39:01.088183336Z"
}
```
With `details` enabled;
```bash
curl -s --unix-socket /var/run/docker.sock 'http://localhost/v1.54/containers/my-container3/logs?stdout=1&stderr=1&format=json&details=1' | jq .
{
"Line": "\u001b[?2004h\u001b]0;root@1065b85dd167: /\u0007root@1065b85dd167:/# \u001b[7mecho {1..9} && exit\u001b[27m\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\becho {1..9} && exit\r\n",
"Source": "stdout",
"Timestamp": "2026-02-20T15:39:01.083531419Z",
"Attrs": [{"Key": "labelA","Value": "foo"},{"Key": "labelB","Value": "bar"}]
}
{
"Line": "\u001b[?2004l\r1 2 3 4 5 6 7 8 9\r\n",
"Source": "stdout",
"Timestamp": "2026-02-20T15:39:01.088152377Z",
"Attrs": [{"Key": "labelA","Value": "foo"},{"Key": "labelB","Value": "bar"}]
}
{
"Line": "exit\r\n",
"Source": "stdout",
"Timestamp": "2026-02-20T15:39:01.088183336Z",
"Attrs": [{"Key": "labelA","Value": "foo"},{"Key": "labelB","Value": "bar"}]
}
```
Using `Accept` header instead of the `format=json` query parameter;
```bash
curl -s -H 'Accept: application/json-seq' --unix-socket /var/run/docker.sock 'http://localhost/v1.54/containers/my-container3/logs?stdout=1&stderr=1' | jq .
{
"Line": "\u001b[?2004h\u001b]0;root@1065b85dd167: /\u0007root@1065b85dd167:/# \u001b[7mecho {1..9} && exit\u001b[27m\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\becho {1..9} && exit\r\n",
"Source": "stdout",
"Timestamp": "2026-02-20T15:39:01.083531419Z"
}
{
"Line": "\u001b[?2004l\r1 2 3 4 5 6 7 8 9\r\n",
"Source": "stdout",
"Timestamp": "2026-02-20T15:39:01.088152377Z"
}
{
"Line": "exit\r\n",
"Source": "stdout",
"Timestamp": "2026-02-20T15:39:01.088183336Z"
}
```
Metadata about partial messages is included (except for the json-file logging
driver, which doesn't use it currently);
The partial messages also don't get a trailing newline, except for the last entry;
```bash
docker run --name bar alpine sh -c 'head -c 20000 /dev/zero | tr "\0" A; echo'
curl -s --unix-socket /var/run/docker.sock 'http://localhost/v1.54/containers/bar/logs?stdout=1&stderr=1&format=json'
{"Line":"AAAAAAAAAA....AAAA","Source":"stdout","Timestamp":"2026-02-21T21:45:47.075093919Z"}
{"Line":"AAAAAAAAAAAAAAAA\n","Source":"stdout","Timestamp":"2026-02-21T21:45:47.075093919Z"}
```
And for logging drivers other than the `json-file`, we have information about
partials in a slightly more structured format:
```bash
docker run --name baz --log-driver=local alpine sh -c 'head -c 20000 /dev/zero | tr "\0" A; echo'
curl -s --unix-socket /var/run/docker.sock 'http://localhost/v1.54/containers/baz/logs?stdout=1&stderr=1&format=json'
{"Line":"AAAAAAAAAA....ASAA","Source":"stdout","Timestamp":"2026-02-21T21:49:42.453363584Z","LogMetaData":{"Last":false,"ID":"46a9188a552a068c1d63a5096b7335788aea7e430817f3d2d83c5fd90c6365ef","Ordinal":1}}
{"Line":"AAAAAAAAAAAAAAAA\n","Source":"stdout","Timestamp":"2026-02-21T21:49:42.453363584Z","LogMetaData":{"Last":true,"ID":"46a9188a552a068c1d63a5096b7335788aea7e430817f3d2d83c5fd90c6365ef","Ordinal":2}}
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>