mrradix commited on
Commit
345eec3
·
verified ·
1 Parent(s): 81ee232

Update utils/logging.py

Browse files
Files changed (1) hide show
  1. utils/logging.py +104 -128
utils/logging.py CHANGED
@@ -1,163 +1,139 @@
1
  """
2
- Logging module for the MONA application.
3
-
4
- This module provides a centralized logging system for the application,
5
- replacing print statements with proper logging for better debugging and monitoring.
6
  """
7
 
8
  import logging
9
- import logging.config
10
- from datetime import datetime
11
-
12
- from utils.config import LOGGING_CONFIG
13
-
14
- # Configure logging based on the configuration in config.py
15
- logging.config.dictConfig(LOGGING_CONFIG)
16
-
17
- # Create a logger for the application
18
- logger = logging.getLogger("mona")
19
 
20
-
21
- def get_logger(name=None):
 
 
 
 
22
  """
23
- Get a logger instance with the specified name.
24
 
25
  Args:
26
- name (str, optional): The name of the logger. If None, returns the root logger.
27
- For module-specific loggers, use __name__ as the name.
 
 
28
 
29
  Returns:
30
- logging.Logger: A logger instance.
31
  """
32
- if name:
33
- return logging.getLogger(f"mona.{name}")
34
- return logger
35
-
36
-
37
- def log_function_call(func):
38
- """
39
- Decorator to log function calls with parameters and return values.
40
 
41
- Args:
42
- func (callable): The function to decorate.
43
 
44
- Returns:
45
- callable: The decorated function.
46
- """
47
- def wrapper(*args, **kwargs):
48
- func_logger = get_logger(func.__module__)
49
- func_name = func.__qualname__
50
-
51
- # Log function call with arguments
52
- args_repr = [repr(a) for a in args]
53
- kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
54
- signature = ", ".join(args_repr + kwargs_repr)
55
- func_logger.debug(f"Calling {func_name}({signature})")
56
-
57
- # Call the function
58
- try:
59
- result = func(*args, **kwargs)
60
- func_logger.debug(f"{func_name} returned {result!r}")
61
- return result
62
- except Exception as e:
63
- func_logger.exception(f"Exception in {func_name}: {str(e)}")
64
- raise
65
 
66
- return wrapper
67
-
68
-
69
- def log_error(error_msg, exc_info=None):
70
- """
71
- Log an error message.
72
 
73
- Args:
74
- error_msg (str): The error message to log.
75
- exc_info (Exception, optional): The exception information to include in the log.
76
- """
77
- if exc_info:
78
- logger.error(error_msg, exc_info=exc_info)
79
- else:
80
- logger.error(error_msg)
81
-
82
-
83
- def log_warning(warning_msg):
84
- """
85
- Log a warning message.
86
 
87
- Args:
88
- warning_msg (str): The warning message to log.
89
- """
90
- logger.warning(warning_msg)
91
-
92
-
93
- def log_info(info_msg):
94
- """
95
- Log an info message.
96
 
97
- Args:
98
- info_msg (str): The info message to log.
99
- """
100
- logger.info(info_msg)
101
-
102
-
103
- def log_debug(debug_msg):
104
- """
105
- Log a debug message.
 
 
 
106
 
107
- Args:
108
- debug_msg (str): The debug message to log.
109
- """
110
- logger.debug(debug_msg)
111
-
112
 
113
- def log_user_activity(user_id, activity_type, details=None):
114
  """
115
- Log user activity for analytics purposes.
116
 
117
  Args:
118
- user_id (str): The user identifier.
119
- activity_type (str): The type of activity (e.g., 'page_view', 'task_create').
120
- details (dict, optional): Additional details about the activity.
 
121
  """
122
- activity_log = {
123
- "timestamp": datetime.now().isoformat(),
124
- "user_id": user_id,
125
- "activity_type": activity_type,
126
- }
127
 
128
- if details:
129
- activity_log["details"] = details
 
130
 
131
- logger.info(f"User activity: {activity_log}")
132
-
133
 
134
- def log_performance(operation, duration_ms):
135
  """
136
- Log performance metrics for monitoring.
137
 
138
  Args:
139
- operation (str): The operation being measured.
140
- duration_ms (float): The duration of the operation in milliseconds.
141
  """
142
- logger.info(f"Performance: {operation} took {duration_ms:.2f}ms")
143
-
 
144
 
145
- def log_ai_model_usage(model_name, operation, tokens_used=None):
146
  """
147
- Log AI model usage for monitoring and quota management.
148
 
149
  Args:
150
- model_name (str): The name of the AI model used.
151
- operation (str): The operation performed with the model.
152
- tokens_used (int, optional): The number of tokens used in the operation.
153
  """
154
- usage_log = {
155
- "timestamp": datetime.now().isoformat(),
156
- "model": model_name,
157
- "operation": operation,
158
- }
159
-
160
- if tokens_used is not None:
161
- usage_log["tokens_used"] = tokens_used
162
-
163
- logger.info(f"AI model usage: {usage_log}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """
2
+ Logging utilities for the application.
 
 
 
3
  """
4
 
5
  import logging
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import Optional
 
 
 
 
 
 
 
9
 
10
+ def setup_logger(
11
+ name: str = "app",
12
+ level: str = "INFO",
13
+ log_file: Optional[str] = None,
14
+ format_string: Optional[str] = None
15
+ ) -> logging.Logger:
16
  """
17
+ Set up and configure a logger with console and optional file output.
18
 
19
  Args:
20
+ name: Logger name
21
+ level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
22
+ log_file: Optional file path for log output
23
+ format_string: Optional custom format string
24
 
25
  Returns:
26
+ Configured logger instance
27
  """
28
+ logger = logging.getLogger(name)
 
 
 
 
 
 
 
29
 
30
+ # Clear any existing handlers to avoid duplicates
31
+ logger.handlers.clear()
32
 
33
+ # Set logging level
34
+ logger.setLevel(getattr(logging, level.upper()))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
+ # Create formatter
37
+ if format_string is None:
38
+ format_string = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
 
 
 
39
 
40
+ formatter = logging.Formatter(format_string)
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ # Console handler
43
+ console_handler = logging.StreamHandler(sys.stdout)
44
+ console_handler.setFormatter(formatter)
45
+ logger.addHandler(console_handler)
 
 
 
 
 
46
 
47
+ # File handler (optional)
48
+ if log_file:
49
+ try:
50
+ # Create directory if it doesn't exist
51
+ log_path = Path(log_file)
52
+ log_path.parent.mkdir(parents=True, exist_ok=True)
53
+
54
+ file_handler = logging.FileHandler(log_file)
55
+ file_handler.setFormatter(formatter)
56
+ logger.addHandler(file_handler)
57
+ except Exception as e:
58
+ logger.warning(f"Could not create file handler for {log_file}: {e}")
59
 
60
+ # Prevent propagation to avoid duplicate logs
61
+ logger.propagate = False
62
+
63
+ return logger
 
64
 
65
+ def get_logger(name: str = "app") -> logging.Logger:
66
  """
67
+ Get an existing logger or create a basic one if it doesn't exist.
68
 
69
  Args:
70
+ name: Logger name
71
+
72
+ Returns:
73
+ Logger instance
74
  """
75
+ logger = logging.getLogger(name)
 
 
 
 
76
 
77
+ # If logger has no handlers, set up a basic one
78
+ if not logger.handlers:
79
+ logger = setup_logger(name)
80
 
81
+ return logger
 
82
 
83
+ def set_log_level(logger: logging.Logger, level: str) -> None:
84
  """
85
+ Set the logging level for a logger and all its handlers.
86
 
87
  Args:
88
+ logger: Logger instance
89
+ level: New logging level
90
  """
91
+ logger.setLevel(getattr(logging, level.upper()))
92
+ for handler in logger.handlers:
93
+ handler.setLevel(getattr(logging, level.upper()))
94
 
95
+ def add_file_handler(logger: logging.Logger, log_file: str) -> None:
96
  """
97
+ Add a file handler to an existing logger.
98
 
99
  Args:
100
+ logger: Logger instance
101
+ log_file: Path to log file
 
102
  """
103
+ try:
104
+ # Create directory if it doesn't exist
105
+ log_path = Path(log_file)
106
+ log_path.parent.mkdir(parents=True, exist_ok=True)
107
+
108
+ file_handler = logging.FileHandler(log_file)
109
+ formatter = logging.Formatter(
110
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
111
+ )
112
+ file_handler.setFormatter(formatter)
113
+ logger.addHandler(file_handler)
114
+ except Exception as e:
115
+ logger.warning(f"Could not add file handler for {log_file}: {e}")
116
+
117
+ # Create a default logger instance
118
+ default_logger = setup_logger("app", "INFO")
119
+
120
+ # Convenience functions using the default logger
121
+ def debug(message: str) -> None:
122
+ """Log a debug message."""
123
+ default_logger.debug(message)
124
+
125
+ def info(message: str) -> None:
126
+ """Log an info message."""
127
+ default_logger.info(message)
128
+
129
+ def warning(message: str) -> None:
130
+ """Log a warning message."""
131
+ default_logger.warning(message)
132
+
133
+ def error(message: str) -> None:
134
+ """Log an error message."""
135
+ default_logger.error(message)
136
+
137
+ def critical(message: str) -> None:
138
+ """Log a critical message."""
139
+ default_logger.critical(message)