Skip to content

Instantly share code, notes, and snippets.

@hxer
Forked from JesseBuesking/logging.yaml
Last active July 26, 2018 06:09
Show Gist options
  • Select an option

  • Save hxer/fab9b2b6f905b7c2bc71fa0018d327c3 to your computer and use it in GitHub Desktop.

Select an option

Save hxer/fab9b2b6f905b7c2bc71fa0018d327c3 to your computer and use it in GitHub Desktop.

Revisions

  1. hxer revised this gist Jul 26, 2018. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions output-windows.txt
    Original file line number Diff line number Diff line change
    @@ -1,2 +0,0 @@
    subproc INFO [5432] value begin
    subproc INFO [5432] value end
  2. @JesseBuesking JesseBuesking created this gist Apr 14, 2014.
    23 changes: 23 additions & 0 deletions logging.yaml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    ---
    version: 1
    disable_existing_loggers: False
    formatters:
    simple:
    format: "%(name)-20s%(levelname)-8s%(message)s"
    handlers:
    console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
    mplog:
    class: mplog.MultiProcessingLog
    level: DEBUG
    formatter: simple
    name: mplog.log
    mode: a
    maxsize: 1024
    rotate: 0
    root:
    level: DEBUG
    handlers: [console, mplog]
    61 changes: 61 additions & 0 deletions mplog.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,61 @@
    from logging.handlers import RotatingFileHandler
    import multiprocessing, threading, logging, sys, traceback
    import os


    class MultiProcessingLog(logging.Handler):
    def __init__(self, name, mode, maxsize, rotate):
    logging.Handler.__init__(self)

    self._handler = RotatingFileHandler(name, mode, maxsize, rotate)
    self.queue = multiprocessing.Queue(-1)

    t = threading.Thread(target=self.receive)
    t.daemon = True
    t.start()

    def setFormatter(self, fmt):
    logging.Handler.setFormatter(self, fmt)
    self._handler.setFormatter(fmt)

    def receive(self):
    while True:
    try:
    record = self.queue.get()
    self._handler.emit(record)
    print('received on pid {}'.format(os.getpid()))
    except (KeyboardInterrupt, SystemExit):
    raise
    except EOFError:
    break
    except:
    traceback.print_exc(file=sys.stderr)

    def send(self, s):
    self.queue.put_nowait(s)

    def _format_record(self, record):
    # ensure that exc_info and args have been stringified. Removes any
    # chance of unpickleable things inside and possibly reduces message size
    # sent over the pipe
    if record.args:
    record.msg = record.msg % record.args
    record.args = None
    if record.exc_info:
    dummy = self.format(record)
    record.exc_info = None

    return record

    def emit(self, record):
    try:
    s = self._format_record(record)
    self.send(s)
    except (KeyboardInterrupt, SystemExit):
    raise
    except:
    self.handleError(record)

    def close(self):
    self._handler.close()
    logging.Handler.close(self)
    6 changes: 6 additions & 0 deletions output-linux.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    subproc INFO [20728] value begin
    subproc INFO [20731] value 1
    subproc INFO [20732] value 2
    subproc INFO [20733] value 3
    subproc INFO [20734] value 4
    subproc INFO [20728] value end
    2 changes: 2 additions & 0 deletions output-windows.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    subproc INFO [5432] value begin
    subproc INFO [5432] value end
    23 changes: 23 additions & 0 deletions runner.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    import logging
    from multiprocessing import Pool
    import os
    from subproc import test

    logger = logging.getLogger(__name__)

    if __name__ == '__main__':
    import logging.config
    import yaml

    path = 'logging.yaml'
    if os.path.exists(path):
    with open(path, 'rt') as f:
    config = yaml.load(f.read())
    logging.config.dictConfig(config)

    test('begin')

    p = Pool(4)
    p.map(test, [1, 2, 3, 4])

    test('end')
    8 changes: 8 additions & 0 deletions subproc.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,8 @@
    import logging
    import os
    logger = logging.getLogger(__name__)


    def test(value):
    msg = '[{}] value {}'.format(os.getpid(), value)
    logger.info(msg)