Consider a multi threaded python application using python logger module. I want to do per thread logging, so I have appended the a unique-ID (not thread id) at the bottom of logger name in the main module (which creates threads).
mylogger = logging.getLogger(str(someInt) + __name__)
Now this module uses multiple modules which also support logging but have logger initialized as
mylogger = logging.getLogger(__name__)
Since the callee class doesn't see the logger of caller, the logs of caller are thread specific but that of callee go in one global file, according to its path.
What can we do to avoid changing passing str(someInt)
each of the other modules and use them unchanged but still log to thread specific files.
Please correct me if I am wrong anywhere.
I wouldn't recommend a solution which has separate files for separate threads: you can always separate out the information from a common log file if you add
thread
/threadName
to the format string. You can do what you're asking for, using aFilter
subclass, as described in this post for a similar (but not identical) use case.Although, I am not really experienced in what I am suggesting, I would try to use Thread-local storage.
Thread-local storage
You can then save and access the variables in the following way:
I suggest to save the thread-specific logger to the thread-local variable when you create it and then access the logger again when necessary through the thread-local storage.
Have a look, it helped me to understand thread-local:
As far as I can tell, this is actually an intractable problem in python's logging system. You can kind of hack a solution if you have access to every place a new thread is created and can fiddle with logging controls via logging handlers and filters. But as soon as your code calls some lib/code somewhere that wants to do threading itself, this solution fails, at least in terms of where that lib's threads will log messages to.
I asked a related question with more detail at
How do I log to different files from different threads in python?
and I also posted a comment exposing this issue to the blog by @Vinay Sajip mentioned above. I.e., as far as I can tell (and I could be wrong (!)), his solution does not solve the underlying issue here. Nothing really does unless some high level wizardry involving call stack tracing or somesuch is done to hack away at this basic shortcoming in threads + logging. The multiprocessing package does not solve this issue, either. Each of the Processes is still bound to the same root logger (which in my naivete, seems a bit odd/worrisome, btw.)
There would be a real fix if a thread could be queried for its parent thread, but it cannot.
A potential solution would be to replace
getLogger
:You'll need to make sure
someInt
has the correct value though, which may be hard, depending on the structure of your code. @Marek 's suggestion of using thread local storage may be useful for that.It can be implemented by
logging.Filter
, here's an example:Console output:
Check log files: