custom-python-logger 1.0.10__tar.gz → 2.0.0__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.
- custom_python_logger-2.0.0/PKG-INFO +139 -0
- custom_python_logger-2.0.0/README.md +112 -0
- custom_python_logger-2.0.0/custom_python_logger/__init__.py +15 -0
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/custom_python_logger/logger.py +48 -46
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/custom_python_logger/usage_example.py +10 -8
- custom_python_logger-2.0.0/custom_python_logger.egg-info/PKG-INFO +139 -0
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/custom_python_logger.egg-info/SOURCES.txt +3 -1
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/setup.py +1 -1
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/tests/test_logger.py +4 -4
- custom_python_logger-2.0.0/tests/test_logger_pytest.py +126 -0
- custom_python_logger-2.0.0/tests/test_usage_example_pytest.py +8 -0
- custom_python_logger-1.0.10/PKG-INFO +0 -83
- custom_python_logger-1.0.10/README.md +0 -56
- custom_python_logger-1.0.10/custom_python_logger/__init__.py +0 -10
- custom_python_logger-1.0.10/custom_python_logger.egg-info/PKG-INFO +0 -83
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/LICENSE +0 -0
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/MANIFEST.in +0 -0
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/custom_python_logger.egg-info/dependency_links.txt +0 -0
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/custom_python_logger.egg-info/requires.txt +0 -0
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/custom_python_logger.egg-info/top_level.txt +0 -0
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/pyproject.toml +0 -0
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/requirements.txt +0 -0
- {custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/setup.cfg +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: custom-python-logger
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: A custom logger with color support and additional features.
|
|
5
|
+
Home-page: https://github.com/aviz92/custom-python-logger
|
|
6
|
+
Author: Avi Zaguri
|
|
7
|
+
Author-email:
|
|
8
|
+
Project-URL: Repository, https://github.com/aviz92/custom-python-logger
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: setuptools
|
|
13
|
+
Requires-Dist: wheel
|
|
14
|
+
Requires-Dist: colorlog
|
|
15
|
+
Requires-Dist: pytest
|
|
16
|
+
Requires-Dist: pathlib
|
|
17
|
+
Requires-Dist: PyYAML
|
|
18
|
+
Dynamic: author
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
Dynamic: project-url
|
|
24
|
+
Dynamic: requires-dist
|
|
25
|
+
Dynamic: requires-python
|
|
26
|
+
Dynamic: summary
|
|
27
|
+
|
|
28
|
+
# custom-python-logger
|
|
29
|
+
A powerful and flexible Python logger with colored output, custom log levels, and advanced configuration options. <br>
|
|
30
|
+
Easily integrate structured, readable, and context-rich logging into your Python projects for better debugging and monitoring.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🚀 Features
|
|
35
|
+
- ✅ **Colored Output**: Beautiful, readable logs in your terminal using `colorlog`.
|
|
36
|
+
- ✅ **Custom Log Levels**: Includes `STEP` (for process steps) and `EXCEPTION` (for exception tracking) in addition to standard levels.
|
|
37
|
+
- ✅ **Flexible Output**: Log to console, file, or both. Supports custom log file paths and automatic log directory creation.
|
|
38
|
+
- ✅ **Contextual Logging**: Add extra fields (like user, environment, etc.) to every log message.
|
|
39
|
+
- ✅ **UTC Support**: Optionally log timestamps in UTC for consistency across environments.
|
|
40
|
+
- ✅ **Pretty Formatting**: Built-in helpers for pretty-printing JSON and YAML data in logs.
|
|
41
|
+
- ✅ **Easy Integration**: Simple API for getting a ready-to-use logger anywhere in your codebase.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 📦 Installation
|
|
46
|
+
```bash
|
|
47
|
+
pip install custom-python-logger
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
### 🔧 Usage
|
|
53
|
+
Here's a quick example of how to use `custom-python-logger` in your project:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
import logging
|
|
57
|
+
from custom_python_logger import build_logger, CustomLoggerAdapter
|
|
58
|
+
|
|
59
|
+
logger: CustomLoggerAdapter = build_logger(
|
|
60
|
+
project_name='Logger Project Test',
|
|
61
|
+
log_level=logging.DEBUG,
|
|
62
|
+
log_file=True,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
logger.debug("This is a debug message.")
|
|
66
|
+
logger.info("This is an info message.")
|
|
67
|
+
logger.step("This is a step message.")
|
|
68
|
+
logger.warning("This is a warning message.")
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
_ = 1 / 0
|
|
72
|
+
except ZeroDivisionError:
|
|
73
|
+
logger.exception("This is an exception message.")
|
|
74
|
+
|
|
75
|
+
logger.critical("This is a critical message.")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Advanced Usage
|
|
79
|
+
- Log to a file:
|
|
80
|
+
```python
|
|
81
|
+
from custom_python_logger import build_logger
|
|
82
|
+
|
|
83
|
+
logger = build_logger(project_name='MyApp', log_file=True)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- Use UTC timestamps:
|
|
87
|
+
```python
|
|
88
|
+
from custom_python_logger import build_logger
|
|
89
|
+
|
|
90
|
+
logger = build_logger(project_name='MyApp', log_file=True, utc=True)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- Add extra context:
|
|
94
|
+
```python
|
|
95
|
+
from custom_python_logger import build_logger
|
|
96
|
+
|
|
97
|
+
logger = build_logger(project_name='MyApp', log_file=True, utc=True, extra={'user': 'alice'})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- Pretty-print JSON or YAML:
|
|
101
|
+
```python
|
|
102
|
+
from custom_python_logger import build_logger, json_pretty_format, yaml_pretty_format
|
|
103
|
+
|
|
104
|
+
logger = build_logger(project_name='MyApp', utc=True, log_file=True)
|
|
105
|
+
|
|
106
|
+
logger.info(json_pretty_format({'foo': 'bar'}))
|
|
107
|
+
logger.info(yaml_pretty_format({'foo': 'bar'}))
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- use an existing logger (CustomLoggerAdapter) and set a custom name:
|
|
111
|
+
```python
|
|
112
|
+
from custom_python_logger import get_logger
|
|
113
|
+
|
|
114
|
+
logger = get_logger('some-name')
|
|
115
|
+
|
|
116
|
+
logger.debug("This is a debug message.")
|
|
117
|
+
logger.info("This is an info message.")
|
|
118
|
+
logger.step("This is a step message.")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 🤝 Contributing
|
|
124
|
+
If you have a helpful tool, pattern, or improvement to suggest:
|
|
125
|
+
Fork the repo <br>
|
|
126
|
+
Create a new branch <br>
|
|
127
|
+
Submit a pull request <br>
|
|
128
|
+
I welcome additions that promote clean, productive, and maintainable development. <br>
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 📄 License
|
|
133
|
+
MIT License — see [LICENSE](LICENSE) for details.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 🙏 Thanks
|
|
138
|
+
Thanks for exploring this repository! <br>
|
|
139
|
+
Happy coding! <br>
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# custom-python-logger
|
|
2
|
+
A powerful and flexible Python logger with colored output, custom log levels, and advanced configuration options. <br>
|
|
3
|
+
Easily integrate structured, readable, and context-rich logging into your Python projects for better debugging and monitoring.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚀 Features
|
|
8
|
+
- ✅ **Colored Output**: Beautiful, readable logs in your terminal using `colorlog`.
|
|
9
|
+
- ✅ **Custom Log Levels**: Includes `STEP` (for process steps) and `EXCEPTION` (for exception tracking) in addition to standard levels.
|
|
10
|
+
- ✅ **Flexible Output**: Log to console, file, or both. Supports custom log file paths and automatic log directory creation.
|
|
11
|
+
- ✅ **Contextual Logging**: Add extra fields (like user, environment, etc.) to every log message.
|
|
12
|
+
- ✅ **UTC Support**: Optionally log timestamps in UTC for consistency across environments.
|
|
13
|
+
- ✅ **Pretty Formatting**: Built-in helpers for pretty-printing JSON and YAML data in logs.
|
|
14
|
+
- ✅ **Easy Integration**: Simple API for getting a ready-to-use logger anywhere in your codebase.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 📦 Installation
|
|
19
|
+
```bash
|
|
20
|
+
pip install custom-python-logger
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
### 🔧 Usage
|
|
26
|
+
Here's a quick example of how to use `custom-python-logger` in your project:
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
import logging
|
|
30
|
+
from custom_python_logger import build_logger, CustomLoggerAdapter
|
|
31
|
+
|
|
32
|
+
logger: CustomLoggerAdapter = build_logger(
|
|
33
|
+
project_name='Logger Project Test',
|
|
34
|
+
log_level=logging.DEBUG,
|
|
35
|
+
log_file=True,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
logger.debug("This is a debug message.")
|
|
39
|
+
logger.info("This is an info message.")
|
|
40
|
+
logger.step("This is a step message.")
|
|
41
|
+
logger.warning("This is a warning message.")
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
_ = 1 / 0
|
|
45
|
+
except ZeroDivisionError:
|
|
46
|
+
logger.exception("This is an exception message.")
|
|
47
|
+
|
|
48
|
+
logger.critical("This is a critical message.")
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### Advanced Usage
|
|
52
|
+
- Log to a file:
|
|
53
|
+
```python
|
|
54
|
+
from custom_python_logger import build_logger
|
|
55
|
+
|
|
56
|
+
logger = build_logger(project_name='MyApp', log_file=True)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- Use UTC timestamps:
|
|
60
|
+
```python
|
|
61
|
+
from custom_python_logger import build_logger
|
|
62
|
+
|
|
63
|
+
logger = build_logger(project_name='MyApp', log_file=True, utc=True)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- Add extra context:
|
|
67
|
+
```python
|
|
68
|
+
from custom_python_logger import build_logger
|
|
69
|
+
|
|
70
|
+
logger = build_logger(project_name='MyApp', log_file=True, utc=True, extra={'user': 'alice'})
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
- Pretty-print JSON or YAML:
|
|
74
|
+
```python
|
|
75
|
+
from custom_python_logger import build_logger, json_pretty_format, yaml_pretty_format
|
|
76
|
+
|
|
77
|
+
logger = build_logger(project_name='MyApp', utc=True, log_file=True)
|
|
78
|
+
|
|
79
|
+
logger.info(json_pretty_format({'foo': 'bar'}))
|
|
80
|
+
logger.info(yaml_pretty_format({'foo': 'bar'}))
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- use an existing logger (CustomLoggerAdapter) and set a custom name:
|
|
84
|
+
```python
|
|
85
|
+
from custom_python_logger import get_logger
|
|
86
|
+
|
|
87
|
+
logger = get_logger('some-name')
|
|
88
|
+
|
|
89
|
+
logger.debug("This is a debug message.")
|
|
90
|
+
logger.info("This is an info message.")
|
|
91
|
+
logger.step("This is a step message.")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 🤝 Contributing
|
|
97
|
+
If you have a helpful tool, pattern, or improvement to suggest:
|
|
98
|
+
Fork the repo <br>
|
|
99
|
+
Create a new branch <br>
|
|
100
|
+
Submit a pull request <br>
|
|
101
|
+
I welcome additions that promote clean, productive, and maintainable development. <br>
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 📄 License
|
|
106
|
+
MIT License — see [LICENSE](LICENSE) for details.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 🙏 Thanks
|
|
111
|
+
Thanks for exploring this repository! <br>
|
|
112
|
+
Happy coding! <br>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from custom_python_logger.logger import (
|
|
2
|
+
CustomLoggerAdapter,
|
|
3
|
+
build_logger,
|
|
4
|
+
get_logger,
|
|
5
|
+
json_pretty_format,
|
|
6
|
+
yaml_pretty_format,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"build_logger",
|
|
11
|
+
"get_logger",
|
|
12
|
+
"CustomLoggerAdapter",
|
|
13
|
+
"json_pretty_format",
|
|
14
|
+
"yaml_pretty_format",
|
|
15
|
+
]
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
# logger.py
|
|
2
1
|
import json
|
|
3
2
|
import logging
|
|
4
3
|
import os
|
|
5
4
|
import time
|
|
6
|
-
from logging import
|
|
5
|
+
from logging import Logger, LoggerAdapter
|
|
7
6
|
from pathlib import Path
|
|
8
|
-
from typing import
|
|
7
|
+
from typing import Any, Callable, Optional
|
|
8
|
+
|
|
9
9
|
import yaml
|
|
10
10
|
from colorlog import ColoredFormatter
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
def get_project_path_by_file(marker: str = ".git") -> Path:
|
|
14
|
+
path = Path(__file__).resolve()
|
|
15
|
+
for parent in path.parents:
|
|
16
|
+
if (parent / marker).exists():
|
|
17
|
+
return parent
|
|
18
|
+
raise RuntimeError(f"Project root with marker '{marker}' not found.")
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
def print_before_logger(project_name: str) -> None:
|
|
@@ -30,23 +32,23 @@ class CustomLoggerAdapter(logging.LoggerAdapter):
|
|
|
30
32
|
def exception(self, msg: str, *args, **kwargs):
|
|
31
33
|
level_no = 45
|
|
32
34
|
logging.addLevelName(level_no, "EXCEPTION")
|
|
33
|
-
kwargs.setdefault(
|
|
35
|
+
kwargs.setdefault("stacklevel", 2)
|
|
34
36
|
self.log(level_no, msg, *args, exc_info=True, **kwargs)
|
|
35
37
|
|
|
36
38
|
def step(self, msg: str, *args, **kwargs):
|
|
37
39
|
level_no = 25
|
|
38
40
|
logging.addLevelName(level_no, "STEP")
|
|
39
|
-
kwargs.setdefault(
|
|
41
|
+
kwargs.setdefault("stacklevel", 2)
|
|
40
42
|
self.log(level_no, msg, *args, exc_info=False, **kwargs)
|
|
41
43
|
|
|
42
44
|
|
|
43
45
|
def configure_logging(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
log_format: str,
|
|
47
|
+
utc: bool,
|
|
48
|
+
log_level: int = logging.INFO,
|
|
49
|
+
log_file: bool = False,
|
|
50
|
+
log_file_path: Optional[str] = None,
|
|
51
|
+
console_output: bool = True,
|
|
50
52
|
) -> None:
|
|
51
53
|
"""
|
|
52
54
|
Configure global logging settings.
|
|
@@ -87,16 +89,16 @@ def configure_logging(
|
|
|
87
89
|
if console_output:
|
|
88
90
|
# log_console_formatter = logging.Formatter('%(log_color)s ' + log_format)
|
|
89
91
|
log_console_formatter = ColoredFormatter(
|
|
90
|
-
|
|
92
|
+
"%(log_color)s " + log_format,
|
|
91
93
|
log_colors={
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
94
|
+
"DEBUG": "white",
|
|
95
|
+
"INFO": "green",
|
|
96
|
+
"WARNING": "yellow",
|
|
97
|
+
"STEP": "blue",
|
|
98
|
+
"ERROR": "red,bold",
|
|
99
|
+
"EXCEPTION": "light_red,bold",
|
|
100
|
+
"CRITICAL": "red,bg_white",
|
|
101
|
+
},
|
|
100
102
|
)
|
|
101
103
|
|
|
102
104
|
console_handler = logging.StreamHandler()
|
|
@@ -104,16 +106,16 @@ def configure_logging(
|
|
|
104
106
|
root_logger.addHandler(console_handler)
|
|
105
107
|
|
|
106
108
|
|
|
107
|
-
def
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
) -> CustomLoggerAdapter
|
|
109
|
+
def build_logger(
|
|
110
|
+
project_name: str,
|
|
111
|
+
extra: Optional[dict[str, Any]] = None,
|
|
112
|
+
log_format: str = "%(asctime)s | %(levelname)-10s(l.%(levelno)s) | %(name)s | %(filename)s:%(lineno)s | %(message)s",
|
|
113
|
+
log_level: int = logging.INFO,
|
|
114
|
+
log_file: bool = False,
|
|
115
|
+
log_file_path: str = None,
|
|
116
|
+
console_output: bool = True,
|
|
117
|
+
utc: bool = False,
|
|
118
|
+
) -> CustomLoggerAdapter | Logger:
|
|
117
119
|
"""
|
|
118
120
|
Get a named logger with optional extra context.
|
|
119
121
|
|
|
@@ -133,8 +135,8 @@ def get_logger(
|
|
|
133
135
|
print_before_logger(project_name=project_name)
|
|
134
136
|
|
|
135
137
|
if not log_file_path:
|
|
136
|
-
log_file_path = f
|
|
137
|
-
log_file_path = log_file_path.lower().replace(
|
|
138
|
+
log_file_path = f"{get_project_path_by_file()}/logs/{project_name}.log"
|
|
139
|
+
log_file_path = log_file_path.lower().replace(" ", "_")
|
|
138
140
|
|
|
139
141
|
configure_logging(
|
|
140
142
|
log_level=logging.DEBUG,
|
|
@@ -142,7 +144,7 @@ def get_logger(
|
|
|
142
144
|
log_file=log_file,
|
|
143
145
|
log_file_path=log_file_path,
|
|
144
146
|
console_output=console_output,
|
|
145
|
-
utc=utc
|
|
147
|
+
utc=utc,
|
|
146
148
|
)
|
|
147
149
|
|
|
148
150
|
logger = logging.getLogger()
|
|
@@ -153,19 +155,19 @@ def get_logger(
|
|
|
153
155
|
return CustomLoggerAdapter(logger, extra)
|
|
154
156
|
|
|
155
157
|
|
|
158
|
+
def get_logger(name: str) -> CustomLoggerAdapter:
|
|
159
|
+
return CustomLoggerAdapter(logging.getLogger(name), {})
|
|
160
|
+
|
|
161
|
+
|
|
156
162
|
def json_pretty_format(
|
|
157
|
-
|
|
158
|
-
indent: int = 4,
|
|
159
|
-
sort_keys: bool = True,
|
|
160
|
-
default: callable = None
|
|
163
|
+
data: Any, indent: int = 4, sort_keys: bool = True, default: Callable = None
|
|
161
164
|
) -> str:
|
|
162
165
|
return json.dumps(data, indent=indent, sort_keys=sort_keys, default=default)
|
|
163
166
|
|
|
164
167
|
|
|
165
168
|
def yaml_pretty_format(
|
|
166
|
-
|
|
167
|
-
indent: int = 4,
|
|
168
|
-
sort_keys: bool = False,
|
|
169
|
-
allow_unicode=True
|
|
169
|
+
data: Any, indent: int = 4, sort_keys: bool = False, allow_unicode=True
|
|
170
170
|
) -> str:
|
|
171
|
-
return yaml.dump(
|
|
171
|
+
return yaml.dump(
|
|
172
|
+
data, sort_keys=sort_keys, indent=indent, allow_unicode=allow_unicode
|
|
173
|
+
)
|
{custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/custom_python_logger/usage_example.py
RENAMED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
|
+
from custom_python_logger import build_logger, get_logger
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
class LoggerTest:
|
|
5
7
|
def __init__(self):
|
|
6
|
-
self.logger =
|
|
8
|
+
self.logger = get_logger(self.__class__.__name__)
|
|
7
9
|
|
|
8
10
|
def main(self):
|
|
9
|
-
self.logger.
|
|
10
|
-
self.logger.
|
|
11
|
+
self.logger.debug("Hello World")
|
|
12
|
+
self.logger.info("Hello World")
|
|
13
|
+
self.logger.step("Hello World")
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
def main():
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
logger = get_logger(
|
|
17
|
-
project_name='Logger Project Test',
|
|
17
|
+
logger = build_logger(
|
|
18
|
+
project_name="Logger Project Test",
|
|
18
19
|
log_level=logging.DEBUG,
|
|
20
|
+
log_file=True,
|
|
19
21
|
# extra={'user': 'test_user'}
|
|
20
22
|
)
|
|
21
23
|
|
|
@@ -35,5 +37,5 @@ def main():
|
|
|
35
37
|
logger_test.main()
|
|
36
38
|
|
|
37
39
|
|
|
38
|
-
if __name__ ==
|
|
40
|
+
if __name__ == "__main__":
|
|
39
41
|
main()
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: custom-python-logger
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: A custom logger with color support and additional features.
|
|
5
|
+
Home-page: https://github.com/aviz92/custom-python-logger
|
|
6
|
+
Author: Avi Zaguri
|
|
7
|
+
Author-email:
|
|
8
|
+
Project-URL: Repository, https://github.com/aviz92/custom-python-logger
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: setuptools
|
|
13
|
+
Requires-Dist: wheel
|
|
14
|
+
Requires-Dist: colorlog
|
|
15
|
+
Requires-Dist: pytest
|
|
16
|
+
Requires-Dist: pathlib
|
|
17
|
+
Requires-Dist: PyYAML
|
|
18
|
+
Dynamic: author
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
Dynamic: project-url
|
|
24
|
+
Dynamic: requires-dist
|
|
25
|
+
Dynamic: requires-python
|
|
26
|
+
Dynamic: summary
|
|
27
|
+
|
|
28
|
+
# custom-python-logger
|
|
29
|
+
A powerful and flexible Python logger with colored output, custom log levels, and advanced configuration options. <br>
|
|
30
|
+
Easily integrate structured, readable, and context-rich logging into your Python projects for better debugging and monitoring.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🚀 Features
|
|
35
|
+
- ✅ **Colored Output**: Beautiful, readable logs in your terminal using `colorlog`.
|
|
36
|
+
- ✅ **Custom Log Levels**: Includes `STEP` (for process steps) and `EXCEPTION` (for exception tracking) in addition to standard levels.
|
|
37
|
+
- ✅ **Flexible Output**: Log to console, file, or both. Supports custom log file paths and automatic log directory creation.
|
|
38
|
+
- ✅ **Contextual Logging**: Add extra fields (like user, environment, etc.) to every log message.
|
|
39
|
+
- ✅ **UTC Support**: Optionally log timestamps in UTC for consistency across environments.
|
|
40
|
+
- ✅ **Pretty Formatting**: Built-in helpers for pretty-printing JSON and YAML data in logs.
|
|
41
|
+
- ✅ **Easy Integration**: Simple API for getting a ready-to-use logger anywhere in your codebase.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 📦 Installation
|
|
46
|
+
```bash
|
|
47
|
+
pip install custom-python-logger
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
### 🔧 Usage
|
|
53
|
+
Here's a quick example of how to use `custom-python-logger` in your project:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
import logging
|
|
57
|
+
from custom_python_logger import build_logger, CustomLoggerAdapter
|
|
58
|
+
|
|
59
|
+
logger: CustomLoggerAdapter = build_logger(
|
|
60
|
+
project_name='Logger Project Test',
|
|
61
|
+
log_level=logging.DEBUG,
|
|
62
|
+
log_file=True,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
logger.debug("This is a debug message.")
|
|
66
|
+
logger.info("This is an info message.")
|
|
67
|
+
logger.step("This is a step message.")
|
|
68
|
+
logger.warning("This is a warning message.")
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
_ = 1 / 0
|
|
72
|
+
except ZeroDivisionError:
|
|
73
|
+
logger.exception("This is an exception message.")
|
|
74
|
+
|
|
75
|
+
logger.critical("This is a critical message.")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Advanced Usage
|
|
79
|
+
- Log to a file:
|
|
80
|
+
```python
|
|
81
|
+
from custom_python_logger import build_logger
|
|
82
|
+
|
|
83
|
+
logger = build_logger(project_name='MyApp', log_file=True)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- Use UTC timestamps:
|
|
87
|
+
```python
|
|
88
|
+
from custom_python_logger import build_logger
|
|
89
|
+
|
|
90
|
+
logger = build_logger(project_name='MyApp', log_file=True, utc=True)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- Add extra context:
|
|
94
|
+
```python
|
|
95
|
+
from custom_python_logger import build_logger
|
|
96
|
+
|
|
97
|
+
logger = build_logger(project_name='MyApp', log_file=True, utc=True, extra={'user': 'alice'})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- Pretty-print JSON or YAML:
|
|
101
|
+
```python
|
|
102
|
+
from custom_python_logger import build_logger, json_pretty_format, yaml_pretty_format
|
|
103
|
+
|
|
104
|
+
logger = build_logger(project_name='MyApp', utc=True, log_file=True)
|
|
105
|
+
|
|
106
|
+
logger.info(json_pretty_format({'foo': 'bar'}))
|
|
107
|
+
logger.info(yaml_pretty_format({'foo': 'bar'}))
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- use an existing logger (CustomLoggerAdapter) and set a custom name:
|
|
111
|
+
```python
|
|
112
|
+
from custom_python_logger import get_logger
|
|
113
|
+
|
|
114
|
+
logger = get_logger('some-name')
|
|
115
|
+
|
|
116
|
+
logger.debug("This is a debug message.")
|
|
117
|
+
logger.info("This is an info message.")
|
|
118
|
+
logger.step("This is a step message.")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 🤝 Contributing
|
|
124
|
+
If you have a helpful tool, pattern, or improvement to suggest:
|
|
125
|
+
Fork the repo <br>
|
|
126
|
+
Create a new branch <br>
|
|
127
|
+
Submit a pull request <br>
|
|
128
|
+
I welcome additions that promote clean, productive, and maintainable development. <br>
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 📄 License
|
|
133
|
+
MIT License — see [LICENSE](LICENSE) for details.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 🙏 Thanks
|
|
138
|
+
Thanks for exploring this repository! <br>
|
|
139
|
+
Happy coding! <br>
|
{custom_python_logger-1.0.10 → custom_python_logger-2.0.0}/custom_python_logger.egg-info/SOURCES.txt
RENAMED
|
@@ -12,4 +12,6 @@ custom_python_logger.egg-info/SOURCES.txt
|
|
|
12
12
|
custom_python_logger.egg-info/dependency_links.txt
|
|
13
13
|
custom_python_logger.egg-info/requires.txt
|
|
14
14
|
custom_python_logger.egg-info/top_level.txt
|
|
15
|
-
tests/test_logger.py
|
|
15
|
+
tests/test_logger.py
|
|
16
|
+
tests/test_logger_pytest.py
|
|
17
|
+
tests/test_usage_example_pytest.py
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import unittest
|
|
2
|
-
from custom_python_logger import
|
|
2
|
+
from custom_python_logger import build_logger
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class TestLogger(unittest.TestCase):
|
|
6
6
|
def test_logger_creation(self):
|
|
7
|
-
logger =
|
|
7
|
+
logger = build_logger(project_name='TestProject')
|
|
8
8
|
self.assertIsNotNone(logger)
|
|
9
9
|
self.assertEqual(logger.name, 'root')
|
|
10
10
|
|
|
11
11
|
def test_step_log(self):
|
|
12
|
-
logger =
|
|
12
|
+
logger = build_logger(project_name='TestProject')
|
|
13
13
|
logger.step('Testing step log')
|
|
14
14
|
self.assertTrue(True) # You can add more specific checks for actual logging output
|
|
15
15
|
|
|
16
16
|
def test_exception_log(self):
|
|
17
|
-
logger =
|
|
17
|
+
logger = build_logger(project_name='TestProject')
|
|
18
18
|
try:
|
|
19
19
|
raise ValueError("Test exception")
|
|
20
20
|
except ValueError as e:
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
import time
|
|
5
|
+
from datetime import timezone
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from custom_python_logger import (
|
|
10
|
+
CustomLoggerAdapter,
|
|
11
|
+
build_logger,
|
|
12
|
+
json_pretty_format,
|
|
13
|
+
yaml_pretty_format,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.fixture
|
|
18
|
+
def temp_log_file():
|
|
19
|
+
with tempfile.NamedTemporaryFile(delete=False) as f:
|
|
20
|
+
yield f.name
|
|
21
|
+
os.remove(f.name)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_logger_creation():
|
|
25
|
+
logger = build_logger(project_name="PytestTest")
|
|
26
|
+
assert logger is not None
|
|
27
|
+
assert isinstance(logger, CustomLoggerAdapter)
|
|
28
|
+
assert hasattr(logger, "step")
|
|
29
|
+
assert hasattr(logger, "exception")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_step_log(caplog):
|
|
33
|
+
logger = build_logger(project_name="PytestTest", console_output=False)
|
|
34
|
+
if not isinstance(logger, CustomLoggerAdapter):
|
|
35
|
+
raise AssertionError("Logger is not a CustomLoggerAdapter")
|
|
36
|
+
# Attach caplog.handler
|
|
37
|
+
logging.getLogger().addHandler(caplog.handler)
|
|
38
|
+
with caplog.at_level(logging.INFO):
|
|
39
|
+
logger.step("Step message")
|
|
40
|
+
assert any("Step message" in m for m in caplog.messages)
|
|
41
|
+
assert any("STEP" in r.levelname for r in caplog.records)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_step_log_2(caplog):
|
|
45
|
+
logger = build_logger(project_name="TestProject", console_output=False)
|
|
46
|
+
if not isinstance(logger, CustomLoggerAdapter):
|
|
47
|
+
raise AssertionError("Logger is not a CustomLoggerAdapter")
|
|
48
|
+
logging.getLogger().addHandler(caplog.handler)
|
|
49
|
+
with caplog.at_level(logging.INFO):
|
|
50
|
+
logger.step("Testing step log")
|
|
51
|
+
assert any("Testing step log" in m for m in caplog.messages)
|
|
52
|
+
assert any("STEP" in r.levelname for r in caplog.records)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_exception_log(caplog):
|
|
56
|
+
logger = build_logger(project_name="PytestTest", console_output=False)
|
|
57
|
+
logging.getLogger().addHandler(caplog.handler)
|
|
58
|
+
with caplog.at_level(logging.ERROR):
|
|
59
|
+
try:
|
|
60
|
+
raise RuntimeError("fail")
|
|
61
|
+
except RuntimeError:
|
|
62
|
+
logger.exception("Exception message")
|
|
63
|
+
assert any("Exception message" in m for m in caplog.messages)
|
|
64
|
+
assert any("EXCEPTION" in r.levelname for r in caplog.records)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_exception_log_2(caplog):
|
|
68
|
+
logger = build_logger(project_name="TestProject", console_output=False)
|
|
69
|
+
logging.getLogger().addHandler(caplog.handler)
|
|
70
|
+
with caplog.at_level(logging.ERROR):
|
|
71
|
+
try:
|
|
72
|
+
raise ValueError("Test exception")
|
|
73
|
+
except ValueError as e:
|
|
74
|
+
logger.exception(f"Exception occurred: {e}")
|
|
75
|
+
assert any("Exception occurred: Test exception" in m for m in caplog.messages)
|
|
76
|
+
assert any("EXCEPTION" in r.levelname for r in caplog.records)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def test_log_to_file(temp_log_file):
|
|
80
|
+
logger = build_logger(
|
|
81
|
+
project_name="FileTest", log_file=True, log_file_path=temp_log_file
|
|
82
|
+
)
|
|
83
|
+
logger.info("File log message")
|
|
84
|
+
time.sleep(0.1)
|
|
85
|
+
with open(temp_log_file) as f:
|
|
86
|
+
content = f.read()
|
|
87
|
+
assert "File log message" in content
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_utc_logging(temp_log_file):
|
|
91
|
+
logger = build_logger(
|
|
92
|
+
project_name="UTCTest", log_file=True, log_file_path=temp_log_file, utc=True
|
|
93
|
+
)
|
|
94
|
+
logger.info("UTC log message")
|
|
95
|
+
time.sleep(0.1)
|
|
96
|
+
with open(temp_log_file) as f:
|
|
97
|
+
content = f.read()
|
|
98
|
+
assert "UTC log message" in content
|
|
99
|
+
# Check for a year in UTC (should be close to now)
|
|
100
|
+
import datetime
|
|
101
|
+
|
|
102
|
+
now_utc = datetime.datetime.now(tz=timezone.utc).strftime("%Y")
|
|
103
|
+
assert now_utc in content
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_extra_context(caplog):
|
|
107
|
+
logger = build_logger(
|
|
108
|
+
project_name="ExtraTest", extra={"user": "pytest"}, console_output=False
|
|
109
|
+
)
|
|
110
|
+
logging.getLogger().addHandler(caplog.handler)
|
|
111
|
+
with caplog.at_level(logging.INFO):
|
|
112
|
+
logger.info("With extra")
|
|
113
|
+
assert any("With extra" in m for m in caplog.messages)
|
|
114
|
+
# The extra field is not in the default format, but test that logger works with extra
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_json_pretty_format():
|
|
118
|
+
data = {"a": 1, "b": 2}
|
|
119
|
+
result = json_pretty_format(data)
|
|
120
|
+
assert "{" in result and "a" in result and "b" in result
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def test_yaml_pretty_format():
|
|
124
|
+
data = {"a": 1, "b": 2}
|
|
125
|
+
result = yaml_pretty_format(data)
|
|
126
|
+
assert "a:" in result and "b:" in result
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from custom_python_logger.usage_example import main
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_usage_example_runs(monkeypatch):
|
|
5
|
+
# Patch print and time.sleep to avoid side effects
|
|
6
|
+
monkeypatch.setattr("builtins.print", lambda *a, **k: None)
|
|
7
|
+
monkeypatch.setattr("time.sleep", lambda x: None)
|
|
8
|
+
main() # Should not raise
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: custom-python-logger
|
|
3
|
-
Version: 1.0.10
|
|
4
|
-
Summary: A custom logger with color support and additional features.
|
|
5
|
-
Home-page: https://github.com/aviz92/custom-python-logger
|
|
6
|
-
Author: Avi Zaguri
|
|
7
|
-
Author-email:
|
|
8
|
-
Project-URL: Repository, https://github.com/aviz92/custom-python-logger
|
|
9
|
-
Requires-Python: >=3.11
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
License-File: LICENSE
|
|
12
|
-
Requires-Dist: setuptools
|
|
13
|
-
Requires-Dist: wheel
|
|
14
|
-
Requires-Dist: colorlog
|
|
15
|
-
Requires-Dist: pytest
|
|
16
|
-
Requires-Dist: pathlib
|
|
17
|
-
Requires-Dist: PyYAML
|
|
18
|
-
Dynamic: author
|
|
19
|
-
Dynamic: description
|
|
20
|
-
Dynamic: description-content-type
|
|
21
|
-
Dynamic: home-page
|
|
22
|
-
Dynamic: license-file
|
|
23
|
-
Dynamic: project-url
|
|
24
|
-
Dynamic: requires-dist
|
|
25
|
-
Dynamic: requires-python
|
|
26
|
-
Dynamic: summary
|
|
27
|
-
|
|
28
|
-
# Custom Logger
|
|
29
|
-
A Python logger with colored output and additional log levels. <br>
|
|
30
|
-
The logger supports custom log levels like `STEP` and `EXCEPTION` and can be easily integrated into your Python projects.
|
|
31
|
-
|
|
32
|
-
## Installation
|
|
33
|
-
You can install the package using pip:
|
|
34
|
-
```bash
|
|
35
|
-
pip install custom-python-logger
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Usage
|
|
39
|
-
```python
|
|
40
|
-
import logging
|
|
41
|
-
from custom_python_logger.logger import get_logger, CustomLoggerAdapter
|
|
42
|
-
|
|
43
|
-
logger: CustomLoggerAdapter = CustomLoggerAdapter(logging.getLogger(__name__))
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def main():
|
|
47
|
-
logger.debug("This is a debug message.")
|
|
48
|
-
logger.info("This is an info message.")
|
|
49
|
-
logger.step("This is a step message.")
|
|
50
|
-
logger.warning("This is a warning message.")
|
|
51
|
-
|
|
52
|
-
try:
|
|
53
|
-
_ = 1 / 0
|
|
54
|
-
except ZeroDivisionError:
|
|
55
|
-
logger.exception("This is an exception message.")
|
|
56
|
-
|
|
57
|
-
logger.critical("This is a critical message.")
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if __name__ == '__main__':
|
|
61
|
-
_ = get_logger(
|
|
62
|
-
project_name='Logger Project Test',
|
|
63
|
-
log_level=logging.DEBUG,
|
|
64
|
-
extra={'user': 'test_user'}
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
main()
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
## 🤝 Contributing
|
|
73
|
-
If you have a helpful tool, pattern, or improvement to suggest:
|
|
74
|
-
Fork the repo <br>
|
|
75
|
-
Create a new branch <br>
|
|
76
|
-
Submit a pull request <br>
|
|
77
|
-
I welcome additions that promote clean, productive, and maintainable development. <br>
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## 🙏 Thanks
|
|
82
|
-
Thanks for exploring this repository! <br>
|
|
83
|
-
Happy coding! <br>
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# Custom Logger
|
|
2
|
-
A Python logger with colored output and additional log levels. <br>
|
|
3
|
-
The logger supports custom log levels like `STEP` and `EXCEPTION` and can be easily integrated into your Python projects.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
You can install the package using pip:
|
|
7
|
-
```bash
|
|
8
|
-
pip install custom-python-logger
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
```python
|
|
13
|
-
import logging
|
|
14
|
-
from custom_python_logger.logger import get_logger, CustomLoggerAdapter
|
|
15
|
-
|
|
16
|
-
logger: CustomLoggerAdapter = CustomLoggerAdapter(logging.getLogger(__name__))
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def main():
|
|
20
|
-
logger.debug("This is a debug message.")
|
|
21
|
-
logger.info("This is an info message.")
|
|
22
|
-
logger.step("This is a step message.")
|
|
23
|
-
logger.warning("This is a warning message.")
|
|
24
|
-
|
|
25
|
-
try:
|
|
26
|
-
_ = 1 / 0
|
|
27
|
-
except ZeroDivisionError:
|
|
28
|
-
logger.exception("This is an exception message.")
|
|
29
|
-
|
|
30
|
-
logger.critical("This is a critical message.")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if __name__ == '__main__':
|
|
34
|
-
_ = get_logger(
|
|
35
|
-
project_name='Logger Project Test',
|
|
36
|
-
log_level=logging.DEBUG,
|
|
37
|
-
extra={'user': 'test_user'}
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
main()
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## 🤝 Contributing
|
|
46
|
-
If you have a helpful tool, pattern, or improvement to suggest:
|
|
47
|
-
Fork the repo <br>
|
|
48
|
-
Create a new branch <br>
|
|
49
|
-
Submit a pull request <br>
|
|
50
|
-
I welcome additions that promote clean, productive, and maintainable development. <br>
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## 🙏 Thanks
|
|
55
|
-
Thanks for exploring this repository! <br>
|
|
56
|
-
Happy coding! <br>
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: custom-python-logger
|
|
3
|
-
Version: 1.0.10
|
|
4
|
-
Summary: A custom logger with color support and additional features.
|
|
5
|
-
Home-page: https://github.com/aviz92/custom-python-logger
|
|
6
|
-
Author: Avi Zaguri
|
|
7
|
-
Author-email:
|
|
8
|
-
Project-URL: Repository, https://github.com/aviz92/custom-python-logger
|
|
9
|
-
Requires-Python: >=3.11
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
License-File: LICENSE
|
|
12
|
-
Requires-Dist: setuptools
|
|
13
|
-
Requires-Dist: wheel
|
|
14
|
-
Requires-Dist: colorlog
|
|
15
|
-
Requires-Dist: pytest
|
|
16
|
-
Requires-Dist: pathlib
|
|
17
|
-
Requires-Dist: PyYAML
|
|
18
|
-
Dynamic: author
|
|
19
|
-
Dynamic: description
|
|
20
|
-
Dynamic: description-content-type
|
|
21
|
-
Dynamic: home-page
|
|
22
|
-
Dynamic: license-file
|
|
23
|
-
Dynamic: project-url
|
|
24
|
-
Dynamic: requires-dist
|
|
25
|
-
Dynamic: requires-python
|
|
26
|
-
Dynamic: summary
|
|
27
|
-
|
|
28
|
-
# Custom Logger
|
|
29
|
-
A Python logger with colored output and additional log levels. <br>
|
|
30
|
-
The logger supports custom log levels like `STEP` and `EXCEPTION` and can be easily integrated into your Python projects.
|
|
31
|
-
|
|
32
|
-
## Installation
|
|
33
|
-
You can install the package using pip:
|
|
34
|
-
```bash
|
|
35
|
-
pip install custom-python-logger
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Usage
|
|
39
|
-
```python
|
|
40
|
-
import logging
|
|
41
|
-
from custom_python_logger.logger import get_logger, CustomLoggerAdapter
|
|
42
|
-
|
|
43
|
-
logger: CustomLoggerAdapter = CustomLoggerAdapter(logging.getLogger(__name__))
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def main():
|
|
47
|
-
logger.debug("This is a debug message.")
|
|
48
|
-
logger.info("This is an info message.")
|
|
49
|
-
logger.step("This is a step message.")
|
|
50
|
-
logger.warning("This is a warning message.")
|
|
51
|
-
|
|
52
|
-
try:
|
|
53
|
-
_ = 1 / 0
|
|
54
|
-
except ZeroDivisionError:
|
|
55
|
-
logger.exception("This is an exception message.")
|
|
56
|
-
|
|
57
|
-
logger.critical("This is a critical message.")
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if __name__ == '__main__':
|
|
61
|
-
_ = get_logger(
|
|
62
|
-
project_name='Logger Project Test',
|
|
63
|
-
log_level=logging.DEBUG,
|
|
64
|
-
extra={'user': 'test_user'}
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
main()
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
## 🤝 Contributing
|
|
73
|
-
If you have a helpful tool, pattern, or improvement to suggest:
|
|
74
|
-
Fork the repo <br>
|
|
75
|
-
Create a new branch <br>
|
|
76
|
-
Submit a pull request <br>
|
|
77
|
-
I welcome additions that promote clean, productive, and maintainable development. <br>
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## 🙏 Thanks
|
|
82
|
-
Thanks for exploring this repository! <br>
|
|
83
|
-
Happy coding! <br>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|