Switch between gen_event notify/sync_notify based on message queue length

In normal operation, there's no need for log messages to be synchronous.
Its slower and introduces a global serialization point in the
application.

However, when in an overload condition, synchronous logging is good
because it limits each process to at most 1 log message in flight.

So, this change allows the gen_event at the core of lager to switch
modes depending on the size of the gen_event's mailbox. It should
provide better performance in the case of normal load, but it will also
prevent unbounded mailbox growth if an overload occurs.

The threshold at which the switch between async and sync is done is
configured via the 'async_threshold' app env var.