예제 #1
0
파일: events.py 프로젝트: SamRoberts/events
def handle_log(client, container, line):
    if len(line) == 8:
        container.logs_stream = 'stdout' if line[0] == 1 else 'stderr'
        return

    events = riemann.handle_log(line, container._info, container.logs_stream)

    for event in events:
        client.event(**event)
        client.flush()
예제 #2
0
파일: events.py 프로젝트: SamRoberts/events
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)