How to configure logging for an imported module? - python

In my Superset web application, I am interested in setting the level of logging in Flask-OAuthLib to DEBUG. We can see Flask-OAuthLib access its logger here on line 26
from a Superset web application.
Superset is a web application implemented using Flask-AppBuilder. It
allows for OAuth2 authentication via Flask-OAuthLib.
I want to configure Flask-OAuthLib logging from custom_sso_security_manager.py ... a module described in
the Superset docs on custom OAuth configuration.

You can access the logger in exactly the same way. They are added to a global dictionary that items can be get from with getLogger(key). So all you need is put something like this into your file after you imported the oauth lib:
oauth_logger = logging.getLogger('flask_oauthlib')
oauth_logger.setLevel(logging.DEBUG)
# it is custom for libs to have no handler (except the NullHandler)
# so you may want to add one:
oauth_logger.addHandler(logging.StreamHandler()) # just an example

Related

Replace Flask's logger with a custom one imported from another module

In my program I have several custom loggers in a file called loggers.py, this file initializes them with custom settings and saves them as variables using logging.getLogger().
Then in each module of my system I import the corresponding logger as a variable, and use it to log to its respective file.
Now everything works fine this way, but I'm having trouble in my webapi.py script, which uses Flask to create some endpoints to handle some requests. I want Flask to use the logger I imported as a variable, but no matter what I try it still uses the custom one.
I tried to assign my custom logger to app.logger and also removing handlers from flask's logger with app.logger.removeHandler(default_handler), but none of those worked. The only solution I could find was to configure the logger in the same script, but it defeats the purpose of having a single script that contains all loggers and their settings.
Is there really no way to simply override Flask's internal logger with a custom one imported from another module?

Flask application - What is the difference between using logging and flask app.logger for a very basic flask application? [duplicate]

I'm building a website using Flask and I'm now in the process of adding some logging to it for which I found these docs. The basic example is as follows:
if not app.debug:
import logging
from themodule import TheHandlerYouWant
file_handler = TheHandlerYouWant(...)
file_handler.setLevel(logging.WARNING)
app.logger.addHandler(file_handler)
after which you can log using app.logger.error('An error occurred'). This works fine, but apart from the fact that I do not see any advantage over the regular python logging module I also see a major downside: if I want to log outside of a request context (when for example running some code with a cron job) I get errors because I'm using app outside of the request context.
So my main question; why would I use the Flask logger at all? What is the reason that it was ever built?
The Flask logger uses the "generic" Python logging, it's a logging.getLogger(name) like any other.
The logger exists so that Flask app and views can log things that happen during execution. For example, it will log tracebacks on 500 errors during debug mode. The configuration example is there to show how to enable these logs, which are still useful in production, when you are not in debug mode.
Having an internal logger is not unique to Flask, it's the standard way to use logging in Python. Every module defines it's own logger, but the configuration of the logging is only handled by the last link in the chain: your project.
You can also use app.logger for your own messages, although it's not required. You could also create a separate logger for your own messages. In the end, it's all Python logging.

Should library loggers have only null handlers?

I am developing a new library and I am completely new to the concept of logging.
I have added logging using Python's logging module for same. The logging I gave has a specific FileHandler set for debug level and StreamHandler set at Warning level. Python documentation about logging says libraries should have only Null Handlers.
Here is the documentation link https://docs.python.org/3/howto/logging.html#library-config
Will it be a problem if I still have an exclusive file and stream handlers in my library.
I am not able to understand why one should create logs in libraries if they cannot have their own customized handlers.
It would be very helpful if someone could clear my understanding gap about implementing logging in libraries.
A secondary question: How will an application developer who uses my library be able to access/enable the logs that I created in the library if I set Null handler?
to your first question - [from the python docs] -
"The application developer knows their target audience and what
handlers are most appropriate for their application: if you add
handlers ‘under the hood’, you might well interfere with their ability
to carry out unit tests and deliver logs which suit their
requirements." 1
as a user of your library, I may want to show logs from your_pkg.foo.baz,
but not your_pkg.foo module.
adding handlers from within your library may force me to do that (depending on the log level that was set to the loggers and handlers).
to your second question -
adding a Nullhandler allows a user to choose his custom logging needs by configuring new handlers through the logging.get_logger("your_pkg.foo.baz").add_handler(...).
to fully understand the logging mechanism (loggers, handlers, filters, and propagation)-
you could look here -
logging flow

Django settings module...not possible to run the logger?

I use the python logging module in my my_app/views.py file with no problem.
I tried to use it inside the staging_settings.py that I use for my configuration. But the messages never reach the error log, whilst the messages from the views.py work fine.
my staging_settings.py:
LOGGING= { ..redacted for space.. } # the logging config-dict
import logging
logger = logging.getLogger(__name__)
logger.debug(F"this is staging_ setup")
Is it just an impossibility to run a logger inside a setup.py? I guess the server actually isn't running yet, so there is nothing for the logger to send to? I'm running this on pythonanywhere, so I don't really have a console to simply print() to or some other hack alternative.
Logging isn't configured at the time the settings file is imported, so you can't do logging from the module level in it. The sequence is
Django imports the settings from your staging_settings.py
Django fetches the LOGGING dict with the configuration from that imported module
Django configures logging with the configuration
When you log anything after that, logging then starts to output stuff as per your configuration
You can't expect to log and get log output in step 1.
Update: AFAIK there's no Django-version-independent way of determining when logging has been configured. You could define your own filter which sets a flag when instantiated, which would happen during configuration. Anyway, that doesn't help you if you need to log from the settings module in module-level code. However, functions that are defined in the settings module and are called later (after logging configuration has happened) can do logging.

What is the advantage of flask.logger over the more generic python logging module?

I'm building a website using Flask and I'm now in the process of adding some logging to it for which I found these docs. The basic example is as follows:
if not app.debug:
import logging
from themodule import TheHandlerYouWant
file_handler = TheHandlerYouWant(...)
file_handler.setLevel(logging.WARNING)
app.logger.addHandler(file_handler)
after which you can log using app.logger.error('An error occurred'). This works fine, but apart from the fact that I do not see any advantage over the regular python logging module I also see a major downside: if I want to log outside of a request context (when for example running some code with a cron job) I get errors because I'm using app outside of the request context.
So my main question; why would I use the Flask logger at all? What is the reason that it was ever built?
The Flask logger uses the "generic" Python logging, it's a logging.getLogger(name) like any other.
The logger exists so that Flask app and views can log things that happen during execution. For example, it will log tracebacks on 500 errors during debug mode. The configuration example is there to show how to enable these logs, which are still useful in production, when you are not in debug mode.
Having an internal logger is not unique to Flask, it's the standard way to use logging in Python. Every module defines it's own logger, but the configuration of the logging is only handled by the last link in the chain: your project.
You can also use app.logger for your own messages, although it's not required. You could also create a separate logger for your own messages. In the end, it's all Python logging.

Categories