mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-16 03:49:52 +00:00
Move plugin volume-count updates out of main thread for perf.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from collections import namedtuple
|
||||
from docker import Client
|
||||
import BaseHTTPServer
|
||||
import SocketServer
|
||||
import datetime
|
||||
@@ -8,23 +10,51 @@ import json
|
||||
import os
|
||||
import signal
|
||||
import socket
|
||||
import threading
|
||||
import time
|
||||
import urllib2
|
||||
from collections import namedtuple
|
||||
from subprocess import check_output
|
||||
|
||||
PLUGIN_ID="volume-count"
|
||||
PLUGIN_UNIX_SOCK="/var/run/scope/plugins/" + PLUGIN_ID + ".sock"
|
||||
DOCKER_SOCK="unix://var/run/docker.sock"
|
||||
|
||||
def run(cmd):
|
||||
return check_output(cmd).strip()
|
||||
nodes = {}
|
||||
|
||||
def update_loop():
|
||||
global nodes
|
||||
next_call = time.time()
|
||||
while True:
|
||||
# Get current timestamp in RFC3339
|
||||
timestamp = datetime.datetime.utcnow()
|
||||
timestamp = timestamp.isoformat('T') + 'Z'
|
||||
|
||||
# Fetch and convert data to scope data model
|
||||
new = {}
|
||||
for container_id, volume_count in container_volume_counts().iteritems():
|
||||
new["%s;<container>" % (container_id)] = {
|
||||
'latest': {
|
||||
'volume_count': {
|
||||
'timestamp': timestamp,
|
||||
'value': str(volume_count),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodes = new
|
||||
next_call += 5
|
||||
time.sleep(next_call - time.time())
|
||||
|
||||
def start_update_loop():
|
||||
updateThread = threading.Thread(target=update_loop)
|
||||
updateThread.daemon = True
|
||||
updateThread.start()
|
||||
|
||||
# List all containers, with the count of their volumes
|
||||
def container_volume_counts():
|
||||
# Find all containers which *should* be running "latest" of their image,
|
||||
# but there is a newer image version available
|
||||
containers = {}
|
||||
for short_id in run(["docker", "ps", "--format", "{{.ID}}"]).splitlines():
|
||||
long_id, volume_count = run(["docker", "inspect", "-f", "{{.ID}} {{.Config.Volumes | len}}", short_id]).split()
|
||||
containers[long_id.strip()] = volume_count.strip()
|
||||
cli = Client(base_url=DOCKER_SOCK, version='auto')
|
||||
for c in cli.containers(all=True):
|
||||
containers[c['Id']] = len(c['Mounts'])
|
||||
return containers
|
||||
|
||||
|
||||
@@ -34,22 +64,6 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
# one, so we fake it.
|
||||
self.client_address = "-"
|
||||
|
||||
# Get current timestamp in RFC3339
|
||||
timestamp = datetime.datetime.utcnow()
|
||||
timestamp = timestamp.isoformat('T') + 'Z'
|
||||
|
||||
# Fetch and convert data to scope data model
|
||||
nodes = {}
|
||||
for container_id, volume_count in container_volume_counts().iteritems():
|
||||
nodes["%s;<container>" % (container_id)] = {
|
||||
'latest': {
|
||||
'volume_count': {
|
||||
'timestamp': timestamp,
|
||||
'value': volume_count,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Generate our json body
|
||||
body = json.dumps({
|
||||
'Plugins': [
|
||||
@@ -81,8 +95,8 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
|
||||
# Send the headers
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.send_header('Content-length', len(body))
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Content-Length', len(body))
|
||||
self.end_headers()
|
||||
|
||||
# Send the body
|
||||
@@ -109,6 +123,8 @@ def main():
|
||||
signal.signal(signal.SIGTERM, sig_handler)
|
||||
signal.signal(signal.SIGINT, sig_handler)
|
||||
|
||||
start_update_loop()
|
||||
|
||||
mkdir_p(os.path.dirname(PLUGIN_UNIX_SOCK))
|
||||
delete_socket_file()
|
||||
server = SocketServer.UnixStreamServer(PLUGIN_UNIX_SOCK, Handler)
|
||||
|
||||
Reference in New Issue
Block a user