Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Add-on for Python logging, supporting indentation and generic logging of function entry/exit
This package provides some enhancements to standard Python logging:
logging_plus is available on PyPI.
Use pip to install:
pip install logging-plus
In order to use this logging add-on, you only need to import logging_plus in addition to logging and instantiate a Logger instance from logging_plus rather than logging.
Then your python code will look, for example, as follows:
#!/usr/bin/python3
import logging
import logging_plus #Specific for logging_plus
logger = logging_plus.getLogger('my_logger') #Specific for logging_plus
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s %(name)-20s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
The only lines which are specific for logging_plus are marked.
In order to automatically log entry and exit of functions, the following line needs to be added after the first import of logging_plus:
logging_plus.registerAutoLogEntryExit()
This can be deactivated through
logging_plus.unregisterAutoLogEntryExit()
Logging of function entry and exit is generic and automatic and does not require any coding.
It is implemented by registering a logging function as system trace function (sys.settrace(autoLogEntryExit)
).
ATTENTION: Since this function may also be used by Python debuggers, it may be necessary to skip this statement when debugging.
Logging of function entry and exit uses a logger with the name of the module in which the function is located (__name__
).
Logging of function entry and exit uses logging.DEBUG level
When activated, the mechanism for automatic logging of function entry and exit is active in all functions within program control flow.
A lot of logging output would, therefore, also be produced by the logging module itself as well as the functions called from there. Since this is normally not of interest, logging in specific infrastructure modules and subordinate functions is deactivated by default.
The following statement activates entry/exit logging for all modules.
logging_plus.noInfrastructureLogging = False
This affects logging in the following modules as well as any functions in a call stack originating from these modules:
During shutdown of the Python interpreter, a special sequence of actions is followed:
Automatic logging of function entry and exit may cause issues when this would be tried in functions which are run during the shutdown process.
For example, class finalizers __del__()
, called during garbage collection, could cause logging issues if a logging file handler is involved, because at this time the shutdown process has already closed any open file handlers.
To avoid such issues, logging_plus registers two atexit
routines:
atexit.register(removeFileHandlers)
which removes any file handlers found in any of the active loggersatexit.register(unregisterAutoLogEntryExit)
which disables automatic entry/exit loggingThese routines are executed in step 4, above, before garbage collection, with the following consequences in case that objects are not finalized explicitely but during garbage collection:
__del__()
) entry/exit.NOTE: in case of explicitely finalizing object instances by using del myObj
to remove all references to an instance, logging within __del__()
is done like in any other function.
(see also chapter 3.3 in https://docs.python.org/3/reference/datamodel.html#index-70)
The following is the logging output from the test module under ./tests with automatic entry/exit logging activated.
The file output can be found at ./tests/logTest.log. The file output for a run with full logging is in ./tests/logTestFull.log
2020-12-13 12:37:40,048 root DEBUG Start
2020-12-13 12:37:40,057 logTestMod DEBUG >>> Entry __init__ (/home/pi/dev/py-logging-plus/tests/logTestMod/__init__.py - line 7 - module logTestMod)
2020-12-13 12:37:40,086 logTestMod DEBUG ## Explicit log: A - Initializing MyClass
2020-12-13 12:37:40,093 logTestMod DEBUG <<< Exit __init__ : Return value: None
2020-12-13 12:37:40,095 logTestMod DEBUG >>> Entry __init__ (/home/pi/dev/py-logging-plus/tests/logTestMod/__init__.py - line 27 - module logTestMod)
2020-12-13 12:37:40,124 logTestMod DEBUG ## Explicit log: F - Initializing subclass MySpecialClass(MyClass)
2020-12-13 12:37:40,132 logTestMod DEBUG >>> Entry __init__ (/home/pi/dev/py-logging-plus/tests/logTestMod/__init__.py - line 7 - module logTestMod)
2020-12-13 12:37:40,170 logTestMod DEBUG ## Explicit log: A - Initializing MyClass
2020-12-13 12:37:40,177 logTestMod DEBUG <<< Exit __init__ : Return value: None
2020-12-13 12:37:40,179 logTestMod DEBUG <<< Exit __init__ : Return value: None
2020-12-13 12:37:40,180 logTestMod DEBUG >>> Entry status (/home/pi/dev/py-logging-plus/tests/logTestMod/__init__.py - line 13 - module logTestMod)
2020-12-13 12:37:40,210 logTestMod DEBUG ## Explicit log: C - getter of MyClass
2020-12-13 12:37:40,217 logTestMod DEBUG <<< Exit status : Return value: 1
2020-12-13 12:37:40,219 logTestMod DEBUG >>> Entry status (/home/pi/dev/py-logging-plus/tests/logTestMod/__init__.py - line 18 - module logTestMod)
2020-12-13 12:37:40,248 logTestMod DEBUG ## Explicit log: D - setter of MyClass
2020-12-13 12:37:40,256 logTestMod DEBUG <<< Exit status : Return value: None
2020-12-13 12:37:40,257 logTestMod DEBUG >>> Entry doSomething (/home/pi/dev/py-logging-plus/tests/logTestMod/__init__.py - line 23 - module logTestMod)
2020-12-13 12:37:40,287 logTestMod DEBUG ## Explicit log: E - MyClass method call
2020-12-13 12:37:40,295 logTestMod DEBUG <<< Exit doSomething : Return value: None
2020-12-13 12:37:40,296 __main__ DEBUG >>> Entry func (logTest.py - line 26 - module __main__)
2020-12-13 12:37:40,327 root DEBUG ## Explicit log: 5 ** 2 = 25
2020-12-13 12:37:40,335 __main__ DEBUG <<< Exit func : Return value: 25
2020-12-13 12:37:40,337 logTestMod DEBUG >>> Entry __del__ (/home/pi/dev/py-logging-plus/tests/logTestMod/__init__.py - line 10 - module logTestMod)
2020-12-13 12:37:40,367 logTestMod DEBUG ## Explicit log: B - Finalizing MyClass
2020-12-13 12:37:40,374 logTestMod DEBUG <<< Exit __del__ : Return value: None
2020-12-13 12:37:40,377 threading DEBUG >>> Entry _shutdown (/usr/lib/python3.7/threading.py - line 1263 - module threading)
2020-12-13 12:37:40,378 threading DEBUG >>> Entry _stop (/usr/lib/python3.7/threading.py - line 968 - module threading)
2020-12-13 12:37:40,380 threading DEBUG <<< Exit _stop : Return value: None
2020-12-13 12:37:40,381 threading DEBUG >>> Entry _pickSomeNonDaemonThread (/usr/lib/python3.7/threading.py - line 1284 - module threading)
2020-12-13 12:37:40,383 threading DEBUG >>> Entry enumerate (/usr/lib/python3.7/threading.py - line 1244 - module threading)
2020-12-13 12:37:40,384 threading DEBUG <<< Exit enumerate : Return value: [<_MainThread(MainThread, stopped 547789455376)>]
2020-12-13 12:37:40,386 threading DEBUG >>> Entry daemon (/usr/lib/python3.7/threading.py - line 1104 - module threading)
2020-12-13 12:37:40,387 threading DEBUG <<< Exit daemon : Return value: False
2020-12-13 12:37:40,389 threading DEBUG >>> Entry is_alive (/usr/lib/python3.7/threading.py - line 1080 - module threading)
2020-12-13 12:37:40,391 threading DEBUG <<< Exit is_alive : Return value: False
2020-12-13 12:37:40,392 threading DEBUG <<< Exit _pickSomeNonDaemonThread : Return value: None
2020-12-13 12:37:40,393 threading DEBUG <<< Exit _shutdown : Return value: None
2020-12-13 12:37:40,407 logTestMod DEBUG ## Explicit log: G - Finalizing subclass MySpecialClass(MyClass)
2020-12-13 12:37:40,408 logTestMod DEBUG ## Explicit log: B - Finalizing MyClass
The last two lines in this example originate from explicit logging calls in finalizers called during garbage collection.
In case of an explicit call of del obj
, also entry and exit of the finalizers are logged automatically as seen for timestamp 2020-12-13 12:37:40,337.
FAQs
Add-on for Python logging, supporting indentation and generic logging of function entry/exit
We found that logging-plus demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.