def parse_events()

in hgext/serverlog/scripts/parse.py [0:0]


def parse_events(fh, onlydate=None):
    thisyear = datetime.date.today().year

    requests = {}
    sessions = {}

    for line in fh:
        date = None
        host = None
        if " hgweb: " in line:
            # Legacy logs: Apr 14 20:17:43
            # New logs: 2016-04-14T20:17:44.250678+00:00
            if line.startswith("20"):
                assert line[26:32] == "+00:00"
                date = datetime.datetime.strptime(line[0:26], "%Y-%m-%dT%H:%M:%S.%f")
                hostaction, line = line[33:].split(":", 1)
                host, action = hostaction.split()
            else:
                date = line[0:15]
                if date[4] == " ":
                    date = date[0:4] + "0" + date[5:]

                # Year isn't in the logs and Python defaults to 1900.
                # This can cause a problem during leap years because strptime
                # will raise a "ValueError: day is out of range for month" for
                # Feb 29. So we add the year to the string before parsing.
                date = "%d %s" % (thisyear, date)
                date = datetime.datetime.strptime(date, "%Y %b %d %H:%M:%S")

                hostaction, line = line[16:].split(":", 1)
                host, action = hostaction.split()

            line = line.strip()
        parts = line.rstrip().split()

        ids, action = parts[0:2]
        ids = ids.split(":")

        if len(ids) > 1:
            session = ids[0]
            request = ids[1]
        else:
            session = None
            request = ids[0]

        if action == "BEGIN_REQUEST":
            if onlydate and date.date() != onlydate:
                continue
            repo, ip, url = parts[2:]
            requests[request] = Request(date, repo, ip, url)

        elif action == "BEGIN_PROTOCOL":
            command = parts[2]
            r = requests.get(request)
            if r:
                if command != "None":
                    r.command = command

        elif action == "END_REQUEST":
            r = requests.get(request)
            if not r:
                continue

            wr_count, t_wall, t_cpu = parts[2:]
            wr_count = int(wr_count)
            t_wall = float(t_wall)
            t_cpu = float(t_cpu)

            r.write_count = wr_count
            r.wall_time = t_wall
            r.cpu_time = t_cpu
            r.end_date = date
            del requests[request]
            yield r

        elif action == "BEGIN_SSH_SESSION":
            if onlydate and date.date() != onlydate:
                continue

            repo, username = parts[2:]
            assert session
            sessions[session] = SSHSession(session, date, repo, username)

        elif action == "END_SSH_SESSION":
            s = sessions.get(session)
            if not s:
                continue

            t_wall, t_cpu = parts[2:]
            t_wall = float(t_wall)
            t_cpu = float(t_cpu)

            s.end_date = date
            s.wall_time = t_wall
            s.cpu_time = t_cpu

            del sessions[session]
            yield s

        elif action == "BEGIN_SSH_COMMAND":
            command = parts[2]
            s = sessions.get(session)
            if s:
                s.current_command = (request, command, date)

        elif action == "END_SSH_COMMAND":
            s = sessions.get(session)
            if not s:
                continue

            t_wall, t_cpu = parts[2:]
            t_wall = float(t_wall)
            t_cpu = float(t_cpu)

            current = s.current_command
            if current and current[0] == request:
                s.commands.append((current[1], current[2], date, t_wall, t_cpu))

            # The request IDs don't match or there is no beginning event.
            # This is weird. We just don't record the command.

            s.current_command = None

        elif action == "CHANGEGROUPSUBSET_START":
            source, count = parts[2:]
            # count = int(count)

        elif action == "WRITE_PROGRESS":
            count = parts[2]