|
@@ -1,8 +1,33 @@
|
|
import logging
|
|
import logging
|
|
import os
|
|
import os
|
|
|
|
+import sys
|
|
|
|
|
|
loglevel = os.getenv("LOGLEVEL", "INFO")
|
|
loglevel = os.getenv("LOGLEVEL", "INFO")
|
|
|
|
|
|
|
|
+_env_colors = os.getenv("HIVEMIND_COLORS")
|
|
|
|
+if _env_colors is not None:
|
|
|
|
+ use_colors = _env_colors.lower() == "true"
|
|
|
|
+else:
|
|
|
|
+ use_colors = sys.stderr.isatty()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class TextStyle:
|
|
|
|
+ """
|
|
|
|
+ ANSI escape codes. Details: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
|
|
|
+ """
|
|
|
|
+
|
|
|
|
+ RESET = "\033[0m"
|
|
|
|
+ BOLD = "\033[1m"
|
|
|
|
+ RED = "\033[31m"
|
|
|
|
+ BLUE = "\033[34m"
|
|
|
|
+ PURPLE = "\033[35m"
|
|
|
|
+ ORANGE = "\033[38;5;208m" # From 8-bit palette
|
|
|
|
+
|
|
|
|
+ if not use_colors:
|
|
|
|
+ # Set the constants above to empty strings
|
|
|
|
+ _codes = locals()
|
|
|
|
+ _codes.update({_name: "" for _name in list(_codes) if _name.isupper()})
|
|
|
|
+
|
|
|
|
|
|
class CustomFormatter(logging.Formatter):
|
|
class CustomFormatter(logging.Formatter):
|
|
"""
|
|
"""
|
|
@@ -10,6 +35,15 @@ class CustomFormatter(logging.Formatter):
|
|
``logger.log(level, message, extra={"origin_created": ..., "caller": ...})``.
|
|
``logger.log(level, message, extra={"origin_created": ..., "caller": ...})``.
|
|
"""
|
|
"""
|
|
|
|
|
|
|
|
+ # Details: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
|
|
|
+ _LEVEL_TO_COLOR = {
|
|
|
|
+ logging.DEBUG: TextStyle.PURPLE,
|
|
|
|
+ logging.INFO: TextStyle.BLUE,
|
|
|
|
+ logging.WARNING: TextStyle.ORANGE,
|
|
|
|
+ logging.ERROR: TextStyle.RED,
|
|
|
|
+ logging.CRITICAL: TextStyle.RED,
|
|
|
|
+ }
|
|
|
|
+
|
|
def format(self, record: logging.LogRecord) -> str:
|
|
def format(self, record: logging.LogRecord) -> str:
|
|
if hasattr(record, "origin_created"):
|
|
if hasattr(record, "origin_created"):
|
|
record.created = record.origin_created
|
|
record.created = record.origin_created
|
|
@@ -18,6 +52,11 @@ class CustomFormatter(logging.Formatter):
|
|
if not hasattr(record, "caller"):
|
|
if not hasattr(record, "caller"):
|
|
record.caller = f"{record.name}.{record.funcName}:{record.lineno}"
|
|
record.caller = f"{record.name}.{record.funcName}:{record.lineno}"
|
|
|
|
|
|
|
|
+ # Aliases for the format argument
|
|
|
|
+ record.levelcolor = self._LEVEL_TO_COLOR[record.levelno]
|
|
|
|
+ record.bold = TextStyle.BOLD
|
|
|
|
+ record.reset = TextStyle.RESET
|
|
|
|
+
|
|
return super().format(record)
|
|
return super().format(record)
|
|
|
|
|
|
|
|
|
|
@@ -27,9 +66,9 @@ def get_logger(module_name: str) -> logging.Logger:
|
|
|
|
|
|
logging.addLevelName(logging.WARNING, "WARN")
|
|
logging.addLevelName(logging.WARNING, "WARN")
|
|
formatter = CustomFormatter(
|
|
formatter = CustomFormatter(
|
|
- fmt="[{asctime}.{msecs:03.0f}][{levelname}][{caller}] {message}",
|
|
|
|
|
|
+ fmt="{asctime}.{msecs:03.0f} [{bold}{levelcolor}{levelname}{reset}] [{bold}{caller}{reset}] {message}",
|
|
style="{",
|
|
style="{",
|
|
- datefmt="%Y/%m/%d %H:%M:%S",
|
|
|
|
|
|
+ datefmt="%b %d %H:%M:%S",
|
|
)
|
|
)
|
|
handler = logging.StreamHandler()
|
|
handler = logging.StreamHandler()
|
|
handler.setFormatter(formatter)
|
|
handler.setFormatter(formatter)
|