custom-python-logger 1.0.2__tar.gz → 1.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (18) hide show
  1. {custom_python_logger-1.0.2/custom_python_logger.egg-info → custom_python_logger-1.0.4}/PKG-INFO +1 -1
  2. custom_python_logger-1.0.4/custom_python_logger/__init__.py +3 -0
  3. custom_python_logger-1.0.4/custom_python_logger/logger.py +156 -0
  4. custom_python_logger-1.0.4/custom_python_logger/usage_example.py +39 -0
  5. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4/custom_python_logger.egg-info}/PKG-INFO +1 -1
  6. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/custom_python_logger.egg-info/SOURCES.txt +3 -0
  7. custom_python_logger-1.0.4/custom_python_logger.egg-info/top_level.txt +1 -0
  8. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/setup.py +3 -2
  9. custom_python_logger-1.0.2/custom_python_logger.egg-info/top_level.txt +0 -1
  10. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/LICENSE +0 -0
  11. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/MANIFEST.in +0 -0
  12. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/README.md +0 -0
  13. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/custom_python_logger.egg-info/dependency_links.txt +0 -0
  14. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/custom_python_logger.egg-info/requires.txt +0 -0
  15. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/pyproject.toml +0 -0
  16. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/requirements.txt +0 -0
  17. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/setup.cfg +0 -0
  18. {custom_python_logger-1.0.2 → custom_python_logger-1.0.4}/tests/test_logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: custom-python-logger
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: A custom logger with color support and additional features.
5
5
  Home-page: https://github.com/aviz92/custom-python-logger
6
6
  Author: Avi Zaguri
@@ -0,0 +1,3 @@
1
+ from custom_python_logger.logger import get_logger
2
+
3
+ __all__ = ["get_logger", "json_pretty_format"]
@@ -0,0 +1,156 @@
1
+ # logger.py
2
+ import json
3
+ import logging
4
+ import os
5
+ import time
6
+ from logging import LoggerAdapter, Logger
7
+ from pathlib import Path
8
+ from typing import Optional, Any
9
+ from colorlog import ColoredFormatter
10
+
11
+
12
+ def get_root_project_path() -> Path:
13
+ if 'venv' in str(Path(__file__)):
14
+ return Path(__file__).parents[5]
15
+ return Path(__file__).parent
16
+
17
+
18
+ def print_before_logger(project_name: str) -> None:
19
+ main_string = f'Start "{project_name}" Process'
20
+
21
+ number_of_ladder = "#" * len(f"### {main_string} ###")
22
+ print(f"\n{number_of_ladder}")
23
+ print(f"### {main_string} ###")
24
+ print(f"{number_of_ladder}\n")
25
+ time.sleep(0.3)
26
+
27
+
28
+ class CustomLoggerAdapter(logging.LoggerAdapter):
29
+ def exception(self, msg: str, *args, **kwargs):
30
+ level_no = 45
31
+ logging.addLevelName(level_no, "EXCEPTION")
32
+ kwargs.setdefault('stacklevel', 2)
33
+ self.log(level_no, msg, *args, exc_info=True, **kwargs)
34
+
35
+ def step(self, msg: str, *args, **kwargs):
36
+ level_no = 25
37
+ logging.addLevelName(level_no, "STEP")
38
+ kwargs.setdefault('stacklevel', 2)
39
+ self.log(level_no, msg, *args, exc_info=False, **kwargs)
40
+
41
+
42
+ def configure_logging(
43
+ log_format: str,
44
+ utc: bool,
45
+ log_level: int = logging.INFO,
46
+ log_file: Optional[str] = None,
47
+ console_output: bool = True,
48
+ ) -> None:
49
+ """
50
+ Configure global logging settings.
51
+
52
+ Args:
53
+ log_level: Logging level (default: INFO)
54
+ log_format: Format string for log messages
55
+ log_file: Path to log file (if None, no file logging)
56
+ console_output: Whether to output logs to console
57
+ utc: Whether to use UTC time for log timestamps
58
+ """
59
+ if utc:
60
+ logging.Formatter.converter = time.gmtime
61
+
62
+ root_logger = logging.getLogger()
63
+ root_logger.setLevel(log_level)
64
+
65
+ # Clear existing handlers
66
+ for handler in root_logger.handlers[:]:
67
+ root_logger.removeHandler(handler)
68
+
69
+ # Add file handler if specified
70
+ if log_file is not None:
71
+ log_file_formatter = logging.Formatter(log_format)
72
+
73
+ # Create directory if it doesn't exist
74
+ log_dir = os.path.dirname(log_file)
75
+ if log_dir and not os.path.exists(log_dir):
76
+ os.makedirs(log_dir)
77
+
78
+ file_handler = logging.FileHandler(log_file)
79
+
80
+ file_handler.setFormatter(log_file_formatter)
81
+ root_logger.addHandler(file_handler)
82
+
83
+ # Add console handler if specified
84
+ if console_output:
85
+ # log_console_formatter = logging.Formatter('%(log_color)s ' + log_format)
86
+ log_console_formatter = ColoredFormatter(
87
+ '%(log_color)s ' + log_format,
88
+ log_colors={
89
+ 'DEBUG': 'white',
90
+ 'INFO': 'green',
91
+ 'WARNING': 'yellow',
92
+ 'STEP': 'blue',
93
+ 'ERROR': 'red,bold',
94
+ 'EXCEPTION': 'light_red,bold',
95
+ 'CRITICAL': 'red,bg_white',
96
+ }
97
+ )
98
+
99
+ console_handler = logging.StreamHandler()
100
+ console_handler.setFormatter(log_console_formatter)
101
+ root_logger.addHandler(console_handler)
102
+
103
+
104
+ def get_logger(
105
+ project_name: str,
106
+ extra: Optional[dict[str, Any]] = None,
107
+ log_format: str = "%(asctime)s | %(levelname)-10s(l.%(levelno)s) | %(filename)s:%(lineno)s | %(message)s",
108
+ log_level: int = logging.INFO,
109
+ log_file: str = None,
110
+ console_output: bool = True,
111
+ utc: bool = False,
112
+ ) -> CustomLoggerAdapter[Logger | LoggerAdapter[Any] | Any] | Logger:
113
+ """
114
+ Get a named logger with optional extra context.
115
+
116
+ Args:
117
+ project_name: Name of the project
118
+ log_level: Optional specific log level
119
+ extra: Optional dictionary of extra context values
120
+ log_format: Format string for log messages
121
+ log_file: Path to log file (if None, no file logging)
122
+ console_output: Whether to output logs to console
123
+ utc: Whether to use UTC time for log timestamps
124
+
125
+ Returns:
126
+ Configured logger
127
+ """
128
+ print_before_logger(project_name=project_name)
129
+
130
+ if not log_file:
131
+ log_file = f'{get_root_project_path()}/logs/{project_name}.log'
132
+ log_file = log_file.lower().replace(' ', '_')
133
+
134
+ configure_logging(
135
+ log_level=logging.DEBUG,
136
+ log_format=log_format,
137
+ log_file=log_file,
138
+ console_output=console_output,
139
+ utc=utc
140
+ )
141
+
142
+ logger = logging.getLogger()
143
+
144
+ if log_level is not None:
145
+ logger.setLevel(log_level)
146
+
147
+ return CustomLoggerAdapter(logger, extra)
148
+
149
+
150
+ def json_pretty_format(
151
+ data: any,
152
+ indent: int = 4,
153
+ sort_keys: bool = True,
154
+ default: callable = None
155
+ ) -> str:
156
+ return json.dumps(data, indent=indent, sort_keys=sort_keys, default=default)
@@ -0,0 +1,39 @@
1
+ import logging
2
+
3
+
4
+ class LoggerTest:
5
+ def __init__(self):
6
+ self.logger = logging.getLogger(self.__class__.__name__)
7
+
8
+ def main(self):
9
+ self.logger.info('Hello World')
10
+ self.logger.debug('Hello World')
11
+
12
+
13
+ def main():
14
+ from custom_python_logger.logger import get_logger
15
+
16
+ logger = get_logger(
17
+ project_name='Logger Project Test',
18
+ log_level=logging.DEBUG,
19
+ # extra={'user': 'test_user'}
20
+ )
21
+
22
+ logger.debug("This is a debug message.")
23
+ logger.info("This is an info message.")
24
+ logger.step("This is a step message.")
25
+ logger.warning("This is a warning message.")
26
+
27
+ try:
28
+ _ = 1 / 0
29
+ except ZeroDivisionError:
30
+ logger.exception("This is an exception message.")
31
+
32
+ logger.critical("This is a critical message.")
33
+
34
+ logger_test = LoggerTest()
35
+ logger_test.main()
36
+
37
+
38
+ if __name__ == '__main__':
39
+ main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: custom-python-logger
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: A custom logger with color support and additional features.
5
5
  Home-page: https://github.com/aviz92/custom-python-logger
6
6
  Author: Avi Zaguri
@@ -4,6 +4,9 @@ README.md
4
4
  pyproject.toml
5
5
  requirements.txt
6
6
  setup.py
7
+ custom_python_logger/__init__.py
8
+ custom_python_logger/logger.py
9
+ custom_python_logger/usage_example.py
7
10
  custom_python_logger.egg-info/PKG-INFO
8
11
  custom_python_logger.egg-info/SOURCES.txt
9
12
  custom_python_logger.egg-info/dependency_links.txt
@@ -0,0 +1 @@
1
+ custom_python_logger
@@ -1,10 +1,11 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
- package_version = '1.0.2'
3
+ package_version = '1.0.4'
4
4
 
5
5
  package_name = 'custom-python-logger'
6
6
  package_description = 'A custom logger with color support and additional features.'
7
7
 
8
+ package_name_ = package_name.replace('-', '_')
8
9
  package_long_description_content_type = 'text/markdown'
9
10
  package_url = f'https://github.com/aviz92/{package_name}'
10
11
  package_python_requires = '>=3.11'
@@ -21,7 +22,7 @@ with open('README.md', 'r') as file:
21
22
  setup(
22
23
  name=package_name,
23
24
  version=package_version,
24
- packages=find_packages(include=[package_name, f'{package_name}.*']),
25
+ packages=find_packages(include=[package_name_, f'{package_name_}.*']),
25
26
  install_requires=package_install_requires,
26
27
  author=package_author,
27
28
  author_email='',