How to create a non-root logger in python

handler, logging, python, root

Solution

Replace

logging.basicConfig(filename='child.log')
childLogger = logging.getLogger(__name__)

in your child module with:

childLogger = logging.getLogger(__name__)
childLogger.addHandler(logging.FileHandler('child.log'))

or, alternatively, use dictConfig or fileConfig to configure logging in one place.

What's wrong with basicConfig? From the docs:

This function does nothing if the root logger already has handlers configured for it.

So basically, your call to `basicLogging` in child module has no effect, since the first one (in parent module) has already configured the root logger. And by setting the child logger's `propagate` to `false`, the child's log entries don't get forwarded to the root logger, so you get the `No handlers could be found...` warning.

Edit

Just to elaborate on fileConfig, which allows a lot of flexibility, for your modules you could create a file called `logging.ini`:

[loggers]
keys=root,child

[handlers]
keys=logfile,logfile_child

[formatters]
keys=default

# loggers

[logger_root]
level=INFO
handlers=logfile

[logger_child]
level=INFO
handlers=logfile_child
qualname=child
propagate=0

# handlers

[handler_logfile]
class=FileHandler
formatter=default
args=('parent.log',)

[handler_logfile_child]
class=FileHandler
formatter=default
args=('child.log',)

# formatters

[formatter_default]
format=%(asctime)s [%(module)s:%(lineno)d] %(levelname)s %(message)s
datefmt=

Then, somewhere in your application, you would just need to call `fileConfig`:

import logging.config

logging.config.fileConfig('logging.ini')

This way your logging is configured in one place, which makes is easier to add additional loggers, change log levels, etc.

Problem

I'm trying to create a non-root logger in a child python module using logging.getLogger('child'), but I'm getting an error "No handlers could be found for logger "child" I'm trying to have a parent module log to parent log file. The parent module will create instances of the child module, and I want the child module to write its own child log file, without propagating its messages up to the parent log file. Here's what I have for the parent module (this is executed by the user): ``` #!/usr/bin/env python import logging, child logging.basicConfig( filename='parent.log' ) logging.warning( 'test log from parent' ) c = child.run() ``` And here's the child module: ``` import logging class run: def __init__(self): logging.basicConfig( filename = 'child.log' ) childLogger = logging.getLogger( __name__ ) childLogger.propagate = False childLogger.warning( 'this is a log from the child' ) ``` Expected output is to have 2 files: parent.log (containing the 1 WARNING line from the parent module) and child.log (containing the one WARNING line from the child module). Actual output is: one WARNING line (from the parent) is printed into the parent.log file, and there is no child.log file--the child log message isn't recorded anywhere. Can you please tell me what I'm missing? TIA!

Original source