def METHOD_NAME(events, log, analyzer, read_header=True):
    """Invoke an analyzer on each event in a log."""
    if isinstance(events, str):
        events = read_events(open(events, 'r'))
    if isinstance(log, str):
        log = open(log, 'rb')
    if read_header:
        read_trace_header(log)
    dropped_event = Event.build("Dropped_Event(uint64_t num_events_dropped)")
    edict = {"dropped": dropped_event}
    for event in events:
        edict[event.name] = event
    def build_fn(analyzer, event):
        if isinstance(event, str):
            return analyzer.catchall
        fn = getattr(analyzer, event.name, None)
        if fn is None:
            return analyzer.catchall
        event_argcount = len(event.args)
        fn_argcount = len(inspect.getargspec(fn)[0]) - 1
        if fn_argcount == event_argcount + 1:
            # Include timestamp as first argument
            return lambda _, rec: fn(*((rec[1:2],) + rec[3:3 + event_argcount]))
        elif fn_argcount == event_argcount + 2:
            # Include timestamp and pid
            return lambda _, rec: fn(*rec[1:3 + event_argcount])
        else:
            # Just arguments, no timestamp or pid
            return lambda _, rec: fn(*rec[3:3 + event_argcount])
    analyzer.begin()
    fn_cache = {}
    for rec in read_trace_records(edict, log):
        event_num = rec[0]
        event = edict[event_num]
        if event_num not in fn_cache:
            fn_cache[event_num] = build_fn(analyzer, event)
        fn_cache[event_num](event, rec)
    analyzer.end()