Skip to content

Commit 411de9d

Browse files
committed
feat: add decorator parameter log_level
1 parent 448f56b commit 411de9d

File tree

5 files changed

+58
-20
lines changed

5 files changed

+58
-20
lines changed

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ SHELL := /bin/bash
22
PYTHON = python3
33
PIP = $(PYTHON) -m pip
44

5+
ifeq ($(OS),Windows_NT)
6+
ACTIVATE_VENV = venv\Scripts\activate
7+
else
8+
ACTIVATE_VENV = source venv/bin/activate
9+
endif
10+
511
ifneq ("$(wildcard .env)","")
612
include .env
713
endif
@@ -18,7 +24,7 @@ init:
1824
make clean && \
1925
npm install && \
2026
python3.11 -m venv venv && \
21-
source venv/bin/activate && \
27+
$(ACTIVATE_VENV) && \
2228
pip install --upgrade pip && \
2329
make requirements && \
2430
pre-commit install

README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,33 @@ pip install secure-logger
3131

3232
### As a decorator
3333

34-
``` python
34+
```python
3535
from secure_logger.decorators import secure_logger
36+
import logging
3637

37-
class Foo(object):
38+
logging.getLogger(__name__)
39+
logging.basicConfig(level=logging.INFO)
3840

39-
@secure_logger()
41+
class Foo(object):
42+
@secure_logger(log_level='INFO')
4043
def bar(self, dict_data, list_data):
4144
pass
4245

4346
# call your method, passing some sensitive data
4447
dict_data = {
45-
'not_a_sensitive_key': 'you-can-see-me',
46-
'aws-access-key_id': conf.AWS_ACCESS_KEY_ID,
47-
'aws-secret-access-key': conf.AWS_SECRET_ACCESS_KEY
48+
"not_a_sensitive_key": "you-can-see-me",
49+
"aws-access-key-id": "i-am-hidden",
50+
"aws-secret-access-key": "so-am-i",
4851
}
49-
list_data = ['foo', 'bar']
52+
list_data = ["foo", "bar"]
5053
foo = Foo()
5154
foo.bar(dict_data=dict_data, list_data=list_data)
5255
```
5356

5457
Log output:
5558

56-
``` log
57-
INFO:secure_logger: __main__.Foo().bar() keyword args: {
59+
```console
60+
INFO:secure_logger: __main__.bar() ['<__main__.Foo object at 0x103474ac0>'] keyword args: {
5861
"dict_data": {
5962
"not_a_sensitive_key": "you-can-see-me",
6063
"aws-access-key-id": "*** -- secure_logger() -- ***",
@@ -64,7 +67,6 @@ INFO:secure_logger: __main__.Foo().bar() keyword args: {
6467
"foo",
6568
"bar"
6669
]
67-
}
6870
```
6971

7072
### As library functions

secure_logger/conf.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
]
3232
_SECURE_LOGGER_REDACTION_MESSAGE = "*** -- secure_logger() -- ***"
3333
_SECURE_LOGGER_INDENT = 4
34-
_SECURE_LOGGER_LOG_LEVEL = "DEBUG"
34+
_SECURE_LOGGER_LOG_LEVEL = "INFO"
3535

3636
# pylint: disable=protected-access
3737
_SECURE_LOGGER_LOG_LEVELS = [level for level in logging._nameToLevel if level != "NOTSET"]
@@ -40,6 +40,7 @@
4040
class Settings(BaseModel):
4141
"""Settings for secure_logger"""
4242

43+
logger_name: str = Field(LOGGER_NAME)
4344
secure_logger_sensitive_keys: list = Field(_SECURE_LOGGER_SENSITIVE_KEYS, env="SECURE_LOGGER_SENSITIVE_KEYS")
4445
secure_logger_redaction_message: str = Field(
4546
_SECURE_LOGGER_REDACTION_MESSAGE, env="SECURE_LOGGER_REDACTION_MESSAGE"
@@ -69,6 +70,17 @@ def logger(self):
6970
}
7071
return log_levels.get(self.secure_logger_logging_level, logging.debug)
7172

73+
def get_logger(self, log_level):
74+
"""Returns the logger function for the specified logging level"""
75+
log_levels = {
76+
"DEBUG": _logger.debug,
77+
"INFO": _logger.info,
78+
"WARNING": _logger.warning,
79+
"ERROR": _logger.error,
80+
"CRITICAL": _logger.critical,
81+
}
82+
return log_levels.get(log_level, logging.debug)
83+
7284
@property
7385
def logger_level(self) -> int:
7486
"""Returns the logger level for the specified logging level"""

secure_logger/decorators.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@
99
from secure_logger.masked_dict import masked_dict2str
1010

1111

12-
# module initializations
13-
logger = settings.logger
14-
15-
1612
def secure_logger(
13+
log_level: str = settings.secure_logger_logging_level,
1714
sensitive_keys: list = settings.secure_logger_sensitive_keys,
1815
indent: int = settings.secure_logger_indent,
1916
message: str = settings.secure_logger_redaction_message,
@@ -64,13 +61,18 @@ def wrapper(*args, **kwargs):
6461
name_spec = name_of_module + "." if name_of_module else ""
6562
name_spec += name_of_class + "." if name_of_class else ""
6663
name_spec += name_of_def + "()" if name_of_def else ""
67-
6864
if len(kwargs.keys()) > 0:
6965
kwargs_dict_repr = "keyword args: "
7066
kwargs_dict_repr += masked_dict2str(
7167
kwargs, sensitive_keys=sensitive_keys, indent=indent, message=message
7268
)
7369

70+
if log_level == settings.secure_logger_logging_level:
71+
logger = settings.logger
72+
else:
73+
logger = settings.get_logger(log_level)
74+
75+
print(logger.__name__)
7476
logger(
7577
"secure_logger: %s %s %s",
7678
name_spec,

secure_logger/tests/tests.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def test_decorator_output(self):
110110
settings.secure_logger_logging_level + ":decorator_logger:secure_logger: tests.mock_decorated_def() "
111111
"['<tests.TestModuleDefDecorator testMethod=test_decorator_output>', " + hello_world
112112
)
113-
with self.assertLogs(level=settings.logger_level) as cm:
113+
with self.assertLogs(logger=settings.logger_name, level=settings.logger_level) as cm:
114114
self.mock_decorated_def("hello world")
115115

116116
self.assertEqual(cm.output[0][0:100], expected_output[0:100])
@@ -126,7 +126,12 @@ class MockClass:
126126
def decorator_with_defaults(self, test_dict, test_list):
127127
"""Test class input parameter as objects."""
128128

129-
@secure_logger(sensitive_keys=["aws_secret_access_key"], indent=10, message="-- Forbidden! --")
129+
@secure_logger(
130+
log_level="INFO",
131+
sensitive_keys=["aws_secret_access_key"],
132+
indent=10,
133+
message="-- Forbidden! --",
134+
)
130135
def decorator_with_custom_params(self, test_dict, test_list):
131136
"""Test class input parameter as objects."""
132137

@@ -145,11 +150,22 @@ def test_class_method_with_default_params(self):
145150
"['<tests.TestClassMethodDecorator.MockClass"
146151
)
147152

148-
with self.assertLogs(level=settings.logger_level) as cm:
153+
with self.assertLogs(logger=settings.logger_name, level=settings.logger_level) as cm:
149154
self.mock_class.decorator_with_defaults(self.test_dict, self.test_list)
150155

151156
self.assertEqual(cm.output[0][0:100], expected_output[0:100])
152157

158+
def test_class_method_with_custom_params(self):
159+
"""Test class method with default parameters."""
160+
expected_output = (
161+
"INFO:decorator_logger:secure_logger: tests.decorator_with_custom_params() "
162+
"['<tests.TestClassMethodDecorator.MockClass"
163+
)
164+
with self.assertLogs(logger=settings.logger_name) as cm:
165+
self.mock_class.decorator_with_custom_params(self.test_dict, self.test_list)
166+
167+
self.assertEqual(cm.output[0][0:100], expected_output[0:100])
168+
153169

154170
class TestClassDecorator(unittest.TestCase):
155171
"""Test class logging."""

0 commit comments

Comments
 (0)