29
29
import textwrap
30
30
import traceback
31
31
from difflib import SequenceMatcher
32
- from typing import TYPE_CHECKING , Any , Callable
32
+ from typing import TYPE_CHECKING , Any , Callable , OrderedDict , cast
33
33
34
34
import confuse
35
35
@@ -1637,11 +1637,7 @@ def _configure(options):
1637
1637
overlay_path = None
1638
1638
config .set_args (options )
1639
1639
1640
- # Configure the logger.
1641
- if config ["verbose" ].get (int ):
1642
- log .set_global_level (logging .DEBUG )
1643
- else :
1644
- log .set_global_level (logging .INFO )
1640
+ _configure_logging ()
1645
1641
1646
1642
if overlay_path :
1647
1643
log .debug (
@@ -1661,6 +1657,71 @@ def _configure(options):
1661
1657
return config
1662
1658
1663
1659
1660
+ def _configure_logging ():
1661
+ """Configure logging levels and handlers."""
1662
+ root_logger = logging .getLogger ()
1663
+
1664
+ if config ["verbose" ].get (int ):
1665
+ level = logging .DEBUG
1666
+ else :
1667
+ level = logging .INFO
1668
+
1669
+ log .set_global_level (level )
1670
+ root_logger .setLevel (level )
1671
+
1672
+ log_format = config ["logging" ]["format" ].get (
1673
+ confuse .String (default = "{message}" )
1674
+ )
1675
+ date_format = config ["logging" ]["date_format" ].get (
1676
+ confuse .String (default = "%Y-%m-%d %H:%M:%S" )
1677
+ )
1678
+
1679
+ # Remove the `StreamHandler` we added earlier so we can make a new one with
1680
+ # the user's format.
1681
+ for logger in [log , root_logger ]:
1682
+ stream_handlers = [
1683
+ handler
1684
+ for handler in logger .handlers
1685
+ if isinstance (handler , logging .StreamHandler )
1686
+ ]
1687
+ for handler in stream_handlers :
1688
+ logger .removeHandler (handler )
1689
+
1690
+ handler = logging .StreamHandler ()
1691
+ handler .setFormatter (
1692
+ logging .Formatter (
1693
+ fmt = cast (str , log_format ),
1694
+ datefmt = cast (str , date_format ),
1695
+ style = "{" ,
1696
+ validate = True ,
1697
+ )
1698
+ )
1699
+ logger .addHandler (handler )
1700
+
1701
+ level_names_mapping = logging .getLevelNamesMapping ()
1702
+ log_levels = config ["logging" ]["levels" ].get (
1703
+ confuse .MappingValues (
1704
+ confuse .OneOf (
1705
+ allowed = [
1706
+ confuse .Integer (),
1707
+ confuse .OneOf (allowed = level_names_mapping .keys ()),
1708
+ ]
1709
+ )
1710
+ )
1711
+ )
1712
+
1713
+ if log_levels :
1714
+ for name , level in cast (OrderedDict , log_levels ).items ():
1715
+ name = None if name == "root" else name
1716
+ logger = logging .getLogger (name )
1717
+ if isinstance (level , int ):
1718
+ logger .setLevel (level )
1719
+ else :
1720
+ logger .setLevel (level_names_mapping [level ])
1721
+
1722
+ logging .getLogger ("musicbrainzngs.mbxml" ).setLevel (logging .WARNING )
1723
+
1724
+
1664
1725
def _ensure_db_directory_exists (path ):
1665
1726
if path == b":memory:" : # in memory db
1666
1727
return
0 commit comments