Comments (3)
My assumption is that you
- add the log handler to the
autogluon
logger to ensure that users receive output even IF they have not configured logging - set
propagate = False
to avoid duplicate logs IF they have configured logging.
To gracefully handle both cases, I would suggest to add a handler to the autogluon
logger which will produce output only if the root logger is not associated with any handlers, i.e. to use a handler like this one I've added to sensAI:
class FallbackHandler(logging.Handler):
"""
A log handler which applies the given handler only if the root logger has no defined handlers
(or has no handlers other than this fallback handler itself)
"""
def __init__(self, handler: logging.Handler, level=logging.NOTSET):
"""
:param handler: the handler to which messages shall be passed on
:param level: the minimum level to output; if NOTSET, pass on everything
"""
super().__init__(level=level)
self._handler = handler
def emit(self, record):
root_handlers = logging.getLogger().handlers
if len(root_handlers) == 0 or (len(root_handlers) == 1 and root_handlers[0] == self):
self._handler.emit(record)
With this type of handler, you can do this:
ag_logger = logging.getLogger("autogluon")
ag_logger.setLevel(logging.INFO)
ag_logger.addHandler(FallbackHandler(logging.StreamHandler(sys.stderr)))
ag_logger.info("Foo")
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
logging.getLogger("foo").info("I am some other logger")
ag_logger.info("Bar")
and you will get
i.e. as long as no root log handler is configured, the autogluon
logger will print to stderr
(as indicated by the red output colour), and after logging has been configured by the user, the logs will end up wherever it was configured instead (stdout
with a different format in this case).
I don't really think a test is needed, as once this is handled properly, it's unlikely to break, but a simple test you could add is this:
def test_root_logger_receives_autogluon_logs():
import autogluon
root_logger = logging.getLogger()
stream = io.StringIO()
stream_handler = logging.StreamHandler(stream=stream)
root_logger.addHandler(stream_handler)
try:
ag_logger = logging.getLogger("autogluon")
ag_logger.setLevel(logging.INFO)
ag_logger.info("Foobar")
assert "Foobar" in stream.getvalue()
finally:
root_logger.removeHandler(stream_handler)
It will currently fail, but it will pass if you apply the function _fix_autogluon_logging
I had pasted above.
I can issue a PR if you like, but I really don't know what you were trying to achieve wrt the kaggle case.
from autogluon.
Thanks for this issue @opcode81!
Indeed logging is a bit odd in AutoGluon (and previously it was even odder). I remember that we chose the current method because of the ways in which other packages sometimes altered logging functionality, which would then also alter AutoGluon's logging in unexpected ways and thus we got GitHub issues from users that were the inverse of yours. Therefore, we isolated the logging logic to be harder to accidentally override in other packages as they are imported. (One of the big ones is Kaggle, which previously hid all AutoGluon logs due to how it altered the logger).
This definitely has side effects, such as what you encountered, and we are interested in making things work with less friction.
I'd be interested in a small code snippet that includes your user-defined logging configuration followed by an import of AutoGluon and calling logger
or fitting TabularPredictor so we can use that for testing.
from autogluon.
Awesome write-up, this is very helpful @opcode81! We will look into addressing this for the next minor release (v1.2).
from autogluon.
Related Issues (20)
- [cloud] Improve clarity on local_to_cloud support
- [BUG] [timeseries] Some forecasting models fail during fit if an S3 path is used HOT 2
- [timeseries] Parallel Training of Time series Predictor HOT 1
- [tabular] Improve GPU Support
- [tabular] Parallel Model Training HOT 1
- [tabular] Add log-scaling to regression for appropriate metrics
- [TimeSeries][TFT] Add parameter to limit number of CPUs (or GPUs)
- Instance Segmentation
- How does TabularPredictor handle new categorical values in test data? HOT 1
- hyperparameters sum len() Error
- Document How To Load a Specific Model in the Tabular FAQ
- [multimodal] Better support for multimodal multi-label regression
- Error occur while using kaggle notebook HOT 2
- [BUG] ValueError: Not enough time left to train models for the full fit in TabularPredictor.fit HOT 1
- [timeseries] Does DirectTabular predict recursively? HOT 1
- Document Layout Understanding
- Not able to import Image classification packages
- Autogluon 0.7.0 vs Autogluon 1.1.0 performance degradation on simple regression task HOT 1
- [BUG] TimeSeriesDataFrame.train_test_split produces incorrect split when unsorted in time HOT 2
- Feature pruning ending very early
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from autogluon.