How to view Docker installation event history

0
46


Docker Engine logs an event each time the daemon performs significant actions. You can access the event log to identify when an action occurred and track changes to objects over time.

In this article, we’ll explain what is captured as events and when you might want to see them. We will then show how to monitor events in real time using the Docker CLI and REST API.

Docker events describe the activities performed by your Docker daemon. Most interactions with objects like containers, images, volumes, and networks log an event, creating a log that you can use to inspect past changes.

There are many different types of events that identify specific changes in your environment:

  • Creation and deletion of containers.
  • Container Health Check States
  • Commands executed inside containers with docker exec
  • Pulling and pushing images
  • Volume creation, destruction, mounting, and unmounting
  • Enabling and disabling Docker daemon plugins

You can see the full list in the Docker documentation.

Each logged event includes a timestamp and the ID of the affected object. You can use this information to piece together a history of changes to your environment, whether or not you observed your original triggers.

Stored events can also help diagnose problems like unexpected container failures. Viewing the log allows you to identify the precise time a container stopped, providing a data point that you can correlate with your other logs. Events can establish when a container’s health checks started to fail, reducing the period of interest when you need to inspect external services to determine the root cause of a problem.

Docker Event Streaming with the Docker CLI

the docker events The CLI command streams events from your Docker daemon to your terminal window. The events will appear in real time until the process is finished by pressing the keyboard combination Ctrl + C.

For starters, running the command with no arguments won’t return any results. Only new activity is displayed, so the output remains empty until an event occurs. You can cause one by starting a new container in a different shell:

$ docker run --rm hello-world

Several events should now appear in the terminal window that is executing the docker events domain:

2022-05-31T15:20:00.267970018+01:00 image pull hello-world:latest (name=hello-world)
2022-05-31T15:20:00.347054862+01:00 container create 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (image=hello-world, name=nifty_morse)
2022-05-31T15:20:00.347805277+01:00 container attach 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (image=hello-world, name=nifty_morse)
2022-05-31T15:20:00.621070053+01:00 container start 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (image=hello-world, name=nifty_morse)
...

Each event is displayed on its own line. The timestamp of the event is displayed first, followed by the type of object affected (such as image either container) and then the action that was taken (such as create, attachY start). The rest of the message contains useful metadata about the object. The example above reveals that the hello-world:latest The image was extracted and a container was created from it.

Output format

The raw event list is often unwieldy. You can reformat the output using the --format flag that accepts a Go template string:

$ docker events --format '{{ .Time }} {{ .Action }} {{ .Type}} {{ .ID }}'

Running this example will produce output similar to this:

1654006800 pull image hello-world:latest
1654006800 create container 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378
1654006800 attach container 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378
1654006800 start container 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378

You can get events represented as JSON objects using {{ json . }} as your template string:

$ docker events --format '{{ json . }}' | jq
{
  "status": "create",
  "id": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378",
  "from": "hello-world",
  "Type": "container",
  "Action": "create",
  "Actor": {
    "ID": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378",
    "Attributes": {
      "image": "hello-world",
      "name": "nifty_morse"
    }
  },
  "scope": "local",
  "time": 1654006800,
  "timeNano": 1654006800347054800
}

The raw JSON is passed here jq so it’s pretty much printed on your terminal. This makes the information easier to scan.

When you create custom format strings, you can use the properties in the JSON output as a reference for the supported placeholders. In most cases, you will need to capitalize the first letter of each property, such as time a {{ .Time }}.

event filtering

The event log of a busy Docker daemon can quickly get noisy. You can restrict events to a specific action, object, or object type with the --filter flag:

  • docker events --filter type=container – Get all the events related to the containers.
  • docker events --filter event=create – Get container creation events.
  • docker events --filter container=demo-container – Get all events saved for the named container demo-container (can refer to container ID or name).

Also containeryou can filter by all supported object type names, like image, networkY volume.

Multiple filters are supported when you repeat the --filter flag. Distinct filters are interpreted as logical Y conditions; multiple uses of the same filter become EITHER clauses. Here is an example that emerges from the create event for both app-container Y api-container containers:

$ docker events 
    --filter container=app-container
    --filter container=api-container
    --filter event=create

Access to historical events

docker events by default it only shows the events stored since the command was executed. You can include historical events by adding the --since flag. This accepts either a human-readable time expression or an absolute timestamp:

$ docker events --since 1h
$ docker events --since '2021-05-01T16:00:00'

Events logged after the given time will be displayed immediately on your terminal. New events will continue to appear in real time as they are recorded.

You can exclude events after a certain time with the --until flag. It works similar to --since. Wearing --until will disable the real-time transmission of new events because they would be outside the requested time period.

Docker Event Streaming from the Daemon REST API

Another way to access stored events is through the Docker daemon’s REST API. you can use the /events endpoint to stream events in real time after you enable the API on your Docker host. Events will be returned in JSON format:

$ curl http://127.0.0.1:2375/v1.41/events
{
  "Type": "container",
  "Action": "create",
  "Actor": {
    "ID": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378",
    "Attributes": {
      "image": "hello-world",
      "name": "nifty_morse"
    }
  },
  "scope": "local",
  "time": 1654006800,
  "timeNano": 1654006800347054800
}

The API endpoint supports filter, sinceY until parameters that have the same behavior as their CLI counterparts. Here’s how to retrieve all container creation events logged in the last hour:

$ curl http://127.0.0.1:2375/v1.41/events?since=1h&filters={'type':'container','action':'create'}

Sending events to an external service

Docker lacks a built-in way to send events to an external service. This could be useful if you want all your container builds to be logged to an existing monitoring or auditing platform.

You can configure your own solution by creating a system service that runs continuously docker events. It should send each new line of output to your external system.

First write a Bash script that implements the functionality you need:

#!/bin/bash
docker events --format '{{ .Time }} {{ .Action }} {{ .Type }} {{ .ID }}' | while read event
do
    curl 
        -X POST 
        -H "Content-Type: application/json" 
        -d '{"event": "$event"}' 
        https://example.com/events
done

Now create a new systemd service unit in /etc/systemd/system/docker-events.service:

[Unit]
Description=Custom Docker Event Monitoring Service

[Service]
Type=forking
ExecStart=/usr/local/bin/docker-events.sh

[Install]
WantedBy=multi-user.target

finally recharge systemd to load your service, then start and enable unity:

$ sudo systemctl daemon-reload
$ sudo systemctl start docker-events
$ sudo systemctl enable docker-events

Your service will now stream every new event to your monitoring platform. Enabling the service configures it to start automatically every time the host is rebooted.

Summary

Docker events are created each time the daemon modifies objects in its environment. Streaming the event log allows you to monitor daemon activity in real time. This can help you debug issues, audit changes, and ensure compliance.

Since the events are retrieved directly from the Docker server, they should not be relied upon if you need to retrieve information in the future. Only 1000 entries are kept continuously and you cannot access the events through your Docker host’s file system. The mechanism is best suited for quick ad hoc tasks where you are looking for specific information related to recent activity. For long-term retention, you should use your own system service to push events to an external repository.