Loguru: how to pickle logger

Created on 2 May 2019  路  11Comments  路  Source: Delgan/loguru

from sklearn.base import BaseEstimator, TransformerMixin

class LoggerMixin():
    @property
    def logger(self):
        return logging.getLogger()

class TestClass(BaseEstimator,TransformerMixin,LoggerMixin):
    def __init__(self, datatype_dict):
        self.datatype_dict = datatype_dict

    def fit(self, X, y=None):
        return self

    def transform(self, X, y=None):
        print(self.datatype_dict)
        self.logger.info("transforming datatypes....")
        return X.astype(self.datatype_dict)

How do i start with this functionality in loguru?
Im sorry if this is an easy quiestion, but im trying to learn logging in python. Thanks

question

Most helpful comment

Maybe can you use logger.remove()?

for fruit in ["apple", "orange", "banana"]:
    handler_id = logger.add("%s.log" % fruit)
    peel_the_fruit(fruit)
    logger.remove(handler_id)

That way, logs emitted by peel_the_fruit() will only appear on the corresponding log file.

All 11 comments

Hi @arnav31.

Could you please give me a little bit more information about what you are trying to achieve?

If you want to dynamically populate module and name value for each class using your mixin, I think you can do something like this:

import sys
from loguru import logger

class LoggerMixin():
    @property
    def logger(self):
        return logger.bind(module=type(self).__module__, name=type(self).__name__)

class Foo(LoggerMixin):

    def bar(self):
        self.logger.info("Baz")

if __name__ == "__main__":
    sink = sys.stderr
    fmt = "[{extra[module]}][{extra[name]}] {message}"
    logger.configure(handlers=[{"sink": sink, "format": fmt}])
    foo = Foo()
    foo.bar()

Hi. Sorry for the confusion (new here), what i was trying was to initialize a logger from a different class (Like we can use .getLogger in python logging.). Please correct me if im wrong, but can we initialize loguru logger anywhere right?

Btw loving loguru. Thanks for this

Hi. Sorry for the confusion (new here), what i was trying was to initialize a logger from a different class (Like we can use .getLogger in python logging.). Please correct me if im wrong, but can we initialize loguru logger anywhere right?

Actually, you can't "initialize" a Loguru logger because there is only one such logger object (the one you get when you do from loguru import logger). The same instance is shared across your modules, but the name value is independently populated based on the current file emitting the log message.

If you wish to set additional information to your logs, like for example if you want the class name to appear in the message, you can make use of the bind() method. This method return a new logger object which will add the bound values to the extra dict of each log record.

class Foo:
    def __init__(self):
        self.logger = logger.bind(classname=type(self).__name__)

class Bar:
    def __init__(self):
        self.logger = logger.bind(classname=type(self).__name__)

logger.add(sys.stderr, format="{extra[classname]} {message}")
foo = Foo()
bar = Bar()

foo.logger.info("A")
# => 'Foo A'
bar.logger.info("B")
# => 'Bar B'

Please, don't hesitate to ask for further clarifications! :slightly_smiling_face:

Btw loving loguru. Thanks for this

Thanks for the kind words, much appreciated!

@arnav31 Do you have any other question, or can I close this issue?

I do have another question. Thanks for being patient.
How can i stop loguru, something like logger.exit(). I want this as I'm iterating though a datatype and creating one log file for each element in that data structure.
Eg:
list = ['apple','orange','banana'].
Here i will have 3 separate log files for apple, orange and banana. But since I'm not explicitly stopping my python file and it iterates through logger.add(parameters) thrice, I'm getting logs for apple, orange and banana in apples log, orange and banana in log file generated only for orange and banana log has log only for banana.

What I'm trying to say is after i run my code for apple i want the logging to stop so when then code goes through logger,add(parameters) it logs only in this logger and not in the apple log too.
I'm sorry if i was not able to make the question clear.

Maybe can you use logger.remove()?

for fruit in ["apple", "orange", "banana"]:
    handler_id = logger.add("%s.log" % fruit)
    peel_the_fruit(fruit)
    logger.remove(handler_id)

That way, logs emitted by peel_the_fruit() will only appear on the corresponding log file.

@arnav31 Anything else? :smile:

I don't mean to be pushing, don't worry, I'm just cleaning up a bit the issue tracker.

No, thanks a lot. It is extremely useful and simplt to use. If you want you can close the issue.

Great, anyway if you have others questions in the future you can ask me. ;)

Hey, Delgan!
Could you please elaborate on how to use enqueue for multiprocessing and keeping the flow of the log consistent or any other way around it?

Hey!

What do you mean by "keeping the flow of the log consistent"?

Adding enqueue=True will prevent your logs to be corrupted when using the logger from multiple processes. Otherwise, logging "ABC" and "DEF" at the same time could result in "ABDEFC" in your log file for example.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AllanLRH picture AllanLRH  路  6Comments

shmilylty picture shmilylty  路  5Comments

yoonghm picture yoonghm  路  3Comments

talz picture talz  路  6Comments

sergree picture sergree  路  3Comments