# From https://docs.python.org/3.7/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes

import logging
import logging.handlers
import multiprocessing


def listener_configurer(console_level):
    root = logging.getLogger()
    rfh = logging.handlers.RotatingFileHandler("../linkedout.log", "a", 1500000, 10)
    rfh_f = logging.Formatter(
        "%(asctime)s | %(processName)-10s | %(name)s | %(levelname)-8s | %(message)s"
    )
    rfh.setFormatter(rfh_f)
    root.addHandler(rfh)
    sh = logging.StreamHandler()
    sh.setLevel(console_level)
    sh_f = logging.Formatter(
        "%(processName)-10s %(levelname)-8s | %(message)s"
    )
    sh.setFormatter(sh_f)
    root.addHandler(sh)
    root.info("Starting logging")


# This is the listener process top-level loop: wait for logging events
# (LogRecords)on the queue and handle them, quit when you get a None for a
# LogRecord.
def listener_process(queue, configurer, console_level=logging.INFO):
    configurer(console_level)
    while True:
        try:
            record = queue.get()
            if (
                record is None
            ):  # We send this as a sentinel to tell the listener to quit.
                break
            logger = logging.getLogger(record.name)
            logger.handle(record)  # No level or filter logic applied - just do it!
        except Exception:
            import sys, traceback

            print("Whoops! Problem:", file=sys.stderr)
            traceback.print_exc(file=sys.stderr)


LEVELS = [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL]


# The worker configuration is done at the start of the worker process run.
# Note that on Windows you can't rely on fork semantics, so each process
# will run the logging configuration code when it starts.
def worker_configurer(queue, level=logging.DEBUG):
    h = logging.handlers.QueueHandler(queue)  # Just the one handler needed
    root = logging.getLogger()
    root.addHandler(h)
    # send all messages, for demo; no other level or filter logic applied.
    root.setLevel(level)
