drivendataorg / nbautoexport

Automatically export Jupyter notebooks to various file formats (.py, .html, and more) on save.
https://nbautoexport.drivendata.org/
MIT License
72 stars 9 forks source link

Improve logging #80

Closed jayqi closed 3 years ago

jayqi commented 3 years ago

Improves logging for nbautoexport to make things easier to troubleshoot.

There are three scenarios of use, each of which will have logging that works differently, in order of likely relevance to users:

  1. Running with Jupyter app. The logger is set to the Jupyter server logger, which we grab via a traitlets convenience method. This will log things with consistent formatting as the rest of Jupyter's logs with pretty colors.
  2. Using nbautoexport CLI. The logger named "nbautoexport" is used, and configured with a stream handler that will print to console. The --verbose/-v flag is now a counter instead of a boolean flag.
    • Default will print typer.echo statements and sets log level to WARNING.
    • -v is INFO log level.
    • -vv is DEBUG log level.
  3. Importing as library. (This isn't something users will likely do, but it is possible so this is implemented for completeness.) The logger named "nbautoexport" is used, and set with a null handler. This is best practice so that the nbautoexport logger will inherit the users' desired configuration from the root logger.

One change looking for feedback:


Examples of logs from Jupyter Lab

Successful startup

Jupyter Lab

startup_success

Jupyter Notebook

notebook_startup_success

Failed startup

startup_error

Successful export

Jupyter Lab

export_success

Jupyter Notebook

notebook_export_success

.nbautoexport validation error

export_error

Export with debug mode

export_debug

Example of CLI verbosity levels

cli_verbosity

Example of importing as library

demo_logging.py

import logging
from pathlib import Path

from nbautoexport.export import export_notebook
from nbautoexport.sentinel import NbAutoexportConfig

print("---DEFAULT---")

logger = logging.getLogger()
logging.basicConfig()
export_notebook(Path("notebooks/Untitled.ipynb"), NbAutoexportConfig())

print("---INFO---")

logger.setLevel(logging.INFO)
export_notebook(Path("notebooks/Untitled.ipynb"), NbAutoexportConfig())

print("---DEBUG---")

logger.setLevel(logging.DEBUG)
export_notebook(Path("notebooks/Untitled.ipynb"), NbAutoexportConfig())

Output:

---DEFAULT---
---INFO---
INFO:nbautoexport:nbautoexport | Exporting notebooks/Untitled.ipynb ...
---DEBUG---
INFO:nbautoexport:nbautoexport | Exporting notebooks/Untitled.ipynb ...
DEBUG:nbautoexport:nbautoexport | Using export configuration:
{
  "export_formats": [
    "script"
  ],
  "organize_by": "extension",
  "clean": {
    "exclude": []
  }
}
DEBUG:traitlets:Loading script exporter: python
DEBUG:traitlets:Applying preprocessor: TagRemovePreprocessor
DEBUG:traitlets:Applying preprocessor: RegexRemovePreprocessor
codecov[bot] commented 3 years ago

Codecov Report

Merging #80 (1d9c13b) into master (f539250) will increase coverage by 0.4%. The diff coverage is 98.5%.

@@           Coverage Diff            @@
##           master     #80     +/-   ##
========================================
+ Coverage    98.1%   98.5%   +0.4%     
========================================
  Files           8       8             
  Lines         382     425     +43     
========================================
+ Hits          375     419     +44     
+ Misses          7       6      -1     
Impacted Files Coverage Δ
nbautoexport/jupyter_config.py 97.1% <95.4%> (+0.6%) :arrow_up:
nbautoexport/__init__.py 100.0% <100.0%> (ø)
nbautoexport/export.py 95.8% <100.0%> (+0.9%) :arrow_up:
nbautoexport/nbautoexport.py 99.2% <100.0%> (+0.8%) :arrow_up:
nbautoexport/sentinel.py 100.0% <100.0%> (ø)
nbautoexport/utils.py 100.0% <100.0%> (ø)
github-actions[bot] commented 3 years ago

🚀 Deployed on https://deploy-preview-80--zen-roentgen-1e5a72.netlify.app

klwetstone commented 3 years ago

@jayqi Looks very helpful! I installed it from the new branch and had no issues. A couple questions for my own understanding:

jayqi commented 3 years ago

@klwetstone

Is the idea that we will still set up nbautoexport the same, but when there is an error we'll (1) get more information in the logs

Yes.

can manually save out the notebook in debug mode in either python or the nbautoexport cli to get more info (per the exampling of importing as library and CLI verbosity levels sections)

No, this is mainly just for completeness. You could always invoke nbautoexport as a library or (more commonly) with the CLI command. This just makes sure the logs behave in ways that Python devs expect if you were to do those things.

How do we set the notebook to export with debug mode when running with the jupyter app

You can run jupyter lab --debug or jupyter notebook --debug to get more logs than you ever wanted.

jayqi commented 3 years ago

Thanks for the review @r-b-g-b, I incorporated your suggestions.