def handle_stat(client, container, line): data = json.loads(line.decode('utf-8')) events = riemann.handle_stat(data, container._info) for event in events: client.event(**event) client.flush()
def main(): logs = [] stats = [] for container in docker_containers(): try: info = docker_inspect(container['Id']) except HTTPError as exc: if exc.status != 404: raise continue if info['Config']['Tty']: continue print("%(Id).12s: logs" % info) logs.append({ 'p': docker_logs(container['Id'], since=time.time()), 'info': info, }) print("%(Id).12s: stats" % info) stats.append({ 'p': docker_stats(container['Id']), 'info': info, 'id': container['Id'], }) events = docker_events() write_count = 0 write_start = time.time() log_queue = [] partial = {} while True: logs = list(filter(is_running_or_pending, logs)) stats = list(filter(is_running_or_pending, stats)) rlist = ([events.result()] if events.done() else []) + [x['p'].result() for x in filter(is_running, logs)] + [x['p'].result() for x in filter(is_running, stats)] if not rlist: time.sleep(1) continue try: rs, _, _ = select.select(rlist, [], [], 1) except AttributeError as exc: # AttributeError: 'NoneType' object has no attribute 'fileno' time.sleep(0.05) continue except ValueError as exc: # ValueError: filedescriptor out of range in select() time.sleep(0.05) continue for r in rs: stream = None for part in os.read(r.fileno(), 8192).split(b'\r\n'): part = partial.pop(r, b'') + part if part == b'': continue if part[:7] == b'\x01\x00\x00\x00\x00\x00\x00': stream = 'stdout' if part[:7] == b'\x02\x00\x00\x00\x00\x00\x00': stream = 'stderr' if part.startswith(b'{'): try: json.loads(part.decode('utf-8')) except Exception as exc: partial[r] = part continue elif re.match(rb'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}', part): pass else: continue line = part if events.done() and r is events.result(): data = json.loads(line.decode('utf-8')) try: log_queue += handle_event(data) except Exception as exc: print("Unable to handle event: %r" % data, file=sys.stderr) traceback.print_exc() if data['status'] == 'start': try: info = docker_inspect(data['id']) except HTTPError as exc: if exc.status != 404: raise continue if info['Config']['Tty']: continue print("%(Id).12s: logs" % info) logs.append({ 'p': docker_logs(data['id'], since(info)), 'info': info, }) if not [x for x in stats if x['id'] == info['Id']]: print("%(Id).12s: stats" % info) stats.append({ 'p': docker_stats(data['id']), 'info': info, 'id': info['Id'], }) elif r in [x['p'].result() for x in filter(is_running, logs)]: try: info = [l['info'] for l in filter(is_running, logs) if r == l['p'].result()][0] except IndexError: continue try: log_queue += handle_log(line, info, stream) except Exception as exc: print("Unable to handle log: %r" % line, file=sys.stderr) traceback.print_exc() elif r in [x['p'].result() for x in filter(is_running, stats)]: try: info = [s['info'] for s in filter(is_running, stats) if r == s['p'].result()][0] except IndexError: continue data = json.loads(line.decode('utf-8')) try: log_queue += handle_stat(data, info) except Exception as exc: print("Unable to handle stat: %r" % data, file=sys.stderr) traceback.print_exc() if log_queue: write_count += len(log_queue) try: write_log(log_queue) except Exception as exc: traceback.print_exc() try: while True: log_queue.pop() except IndexError: pass if time.time() - write_start >= 10: print("events:", write_count) write_start = time.time() time.sleep(1)