All Projects → vfxGer → docker_eventer

vfxGer / docker_eventer

Licence: MIT license
A Docker container to notify about Docker events written in Python

Programming Languages

python
139335 projects - #7 most used programming language
Dockerfile
14818 projects

Projects that are alternatives of or similar to docker eventer

Library
This is a project of a library, driven by real business requirements. We use techniques strongly connected with Domain Driven Design, Behavior-Driven Development, Event Storming, User Story Mapping.
Stars: ✭ 2,685 (+19078.57%)
Mutual labels:  events
React Native Add Calendar Event
Create, view or edit events in react native using the standard iOS / Android dialogs
Stars: ✭ 225 (+1507.14%)
Mutual labels:  events
micro-typed-events
The smallest, most convenient typesafe TS event emitter you'll ever need
Stars: ✭ 39 (+178.57%)
Mutual labels:  events
Pevents
Implementation of Win32 events for *nix platforms, built on top of pthreads.
Stars: ✭ 200 (+1328.57%)
Mutual labels:  events
Php Mysql Replication
Pure PHP Implementation of MySQL replication protocol. This allow you to receive event like insert, update, delete with their data and raw SQL queries.
Stars: ✭ 213 (+1421.43%)
Mutual labels:  events
Cphalcon7
Dao7 - Web framework for PHP7.x,项目接洽 QQ 176013762
Stars: ✭ 237 (+1592.86%)
Mutual labels:  events
Ember Native Dom Helpers
Test helpers for your integration tests that fire native events
Stars: ✭ 187 (+1235.71%)
Mutual labels:  events
di
🐑 A flexible dependency injection container; It is an implementation of PSR-11
Stars: ✭ 20 (+42.86%)
Mutual labels:  container
Mulog
μ/log is a micro-logging library that logs events and data, not words!
Stars: ✭ 222 (+1485.71%)
Mutual labels:  events
Cqrs Clean Eventual Consistency
CQRS, using Clean Architecture, multiple databases and Eventual Consistency
Stars: ✭ 247 (+1664.29%)
Mutual labels:  events
Luv
Cross-platform asynchronous I/O and system calls
Stars: ✭ 203 (+1350%)
Mutual labels:  events
Is Hotkey
Check whether a browser event matches a hotkey.
Stars: ✭ 211 (+1407.14%)
Mutual labels:  events
Php Sse
A simple and efficient library implemented HTML5's server-sent events by PHP, is used to real-time push events from server to client, and easier than Websocket, instead of AJAX request.
Stars: ✭ 237 (+1592.86%)
Mutual labels:  events
Event Driven Spring Boot
Example Application to demo various flavours of handling domain events in Spring Boot
Stars: ✭ 194 (+1285.71%)
Mutual labels:  events
pouchrobot
An AI robot to collaborate in any open source project on GitHub
Stars: ✭ 39 (+178.57%)
Mutual labels:  container
Open Source Meetup Alternatives
Open-Source Alternatives to Meetup
Stars: ✭ 191 (+1264.29%)
Mutual labels:  events
Vue Events
Simple event handling for Vue.js
Stars: ✭ 234 (+1571.43%)
Mutual labels:  events
filegrain
transport-agnostic, fine-grained content-addressable container image layout
Stars: ✭ 23 (+64.29%)
Mutual labels:  container
docker-electrumx
Run an Electrum server with one command
Stars: ✭ 87 (+521.43%)
Mutual labels:  container
Watermill
Building event-driven applications the easy way in Go.
Stars: ✭ 3,504 (+24928.57%)
Mutual labels:  events

Docker Event

The Problem

I had a problem recently. I had a couple Docker containers on one machine for a personal project which was a django web app called  issueinfinity.com. One of the containers, that was doing some image manipulation, kept crashing and I did not know until I logged into the machine and looked at it using docker ps. So I wanted an e-mail notification if any of my containers stopped or if anything happened to them.

The Command

I discovered a command docker events. This is a very handy command to see what has happened to your docker containers.

To see what has happened to your containers in the last hour you can run:

docker events --format {{json .}} --since "1h" --until "0s"

The --since 1h simply means get everything since an hour ago.

The --until 0s means until 0 seconds ago, without the --until the command will just continually stream docker events.

The --format "{{json .}}" argument outputs the events as JSON lines which basically means a JSON document for every event.

As well as the above you can add filters to the events like

docker events --filter 'container=test' --filter 'event=stop'

This will output any stop event on the test container. For more about the filters and more details on the other the arguments see the official docker docs

The Python Script

So now we have enough to create a Python script:

import sys
import subprocess
import time
import json
from collections import Counter
from pprint import pprint, pformat

from notifier import notify


def run():
    proc = subprocess.Popen('docker events --format "{{json .}}" --since "1h" --until "0s"',
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT, shell=True)

    retcode = proc.poll()
    wait_time = 0.1
    while retcode is None:
        time.sleep(wait_time)
        retcode = proc.poll()
    res = proc.stdout.read()
    res = res.decode("utf-8")
    event_data = []
    for line in res.split("\n"):
        line = line.strip()
        if line:
            event_data.append(json.loads(line))
            pprint(event_data[-1])
            print("-"*5)
    if event_data:
        message = ""
        message += "\n%d events\n" % len(event_data)
        message += pformat(Counter(row['Action'] for row in event_data))
        message += "\n"
        message += pformat(event_data)
        subject = "[DOCKER_EVENTS] %d docker events\n" % len(event_data)
        notify(message, subject)
        print("e-mail sent")


def main(_):
    while True:
        run()
        print("Now sleeping for an hour")
        time.sleep(60*60)



if __name__=="__main__":
    main(sys.argv[1:])

Here I am simply running the docker event in a subprocess. I am the putting the stderr of the process into stdout and putting stdout into a temporary file. The temporary file avoids issues with buffer overflows. Then the script sends an e-mail(not shown) if there is any events and parses the json to create a summary of the work.

Although this works the subprocess adds overhead so to simplify the solution we can just use the docker python api.

Using the Docker Python API

Simply run pip install docker to install the python docker api.

Now the script becomes simpler:

import sys
import time
from collections import Counter
from pprint import pprint, pformat
import datetime

from notifier import notify
import docker


def run():
    client = docker.from_env()
    until = datetime.datetime.utcnow()
    since = until - datetime.timedelta(hours=1)
    event_data = []
    for event in client.events(since=since, until=until, decode=True):
        event_data.append(event)
        pprint(event_data[-1])
        print("-" * 5)
    if event_data:
        message = ""
        message += "\n%d events\n" % len(event_data)
        message += pformat(Counter(row['Action'] for row in event_data))
        message += "\n"
        message += pformat(event_data)
        subject = "%d docker events\n" % len(event_data)
        notify(message, subject)
        print("e-mail sent")


def main(_):
    while True:
        run()
        print("Now sleeping for an hour")
        time.sleep(60*60)


if __name__=="__main__":
    main(sys.argv[1:])

The docker client is created from the environment with docker.from_env, which means it works like the command line would. The client.events function works very similar to the command line version. The decode=True means the output are python dictionaries.

I Put Docker in your Docker

Now I could put this python script into supervisord and run on the docker machine but if we are using docker why not use docker. To get this working in a docker container we need to install the docker client inside the container. The simplest way to do this is to run
apt-get install docker.io in the Dockerfile.

Then to make it work we need to mount the docker socket into the container with /var/run/docker.sock:/var/run/docker.sock.

You can see this in the docker-compose.yml file.

And voila a docker event notifier.

Update, now streaming

A comment on reddit said:

Though preferably it would be rather when an event happens than just polling for it.

And I agree but I still did not want to be bombarded with e-mails so here's what I came up with

#!/usr/bin/env python3
import time
from collections import Counter
from pprint import pformat
import datetime

import docker

import notifier

MAX_NOTIFY_TIME = 60


def notify(events):
    message = ""
    message += "\n%d events\n" % len(events)
    message += pformat(Counter(row['Action'] for row in events))
    message += "\n"
    message += pformat(events)
    subject = "[DOCKER_EVNETS] %d docker events\n" % len(events)
    print("Sending e-mail %s", subject)
    notifier.notify(message, subject)


def run():
    client = docker.from_env()
    while True:
        for event in client.events(decode=True):
            notify([event])
            break
        since = datetime.datetime.now()
        # Do not want to bombard the e-mailer with messages so sleeping
        print("Sleeping for %d seconds" % MAX_NOTIFY_TIME)
        time.sleep(MAX_NOTIFY_TIME)
        print("Woke")
        until = datetime.datetime.now()
        notify([event for event in client.events(since=since, until=until, decode=True)])


def main():
    run()


if __name__=="__main__":
    main()

It is a simple solution, it gets the first event, e-mails about it and then sleeps. After the program stops sleeping it gets all the events that happened while it was sleeping and sends them and repeats.

Still to do:

  • make it more configurable
  • make it send notification on the first event and not just once an hour
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].