User Notes¶
This page has various different notes for using PyExpLabSys.
Setting up logging of your program¶
To set up logging of a program, it is possible to simply follow the standard library documentation. However, since many of the programs that uses PyExpLabSys are programs that runs for extended periods without monitoring, a more specific logging setup may be required. E.g. one that makes use of email handlers, so be notified by email in case of errors or warnings.
For that purpose, PyExpLabSys has the get_logger()
function in the
utilities
module that is a convinience function to set up a logger with one or
more of the commonly used log handlers i.e. a terminal handler, a rotating file handler
and email handlers. This may be used to things up and running in a hurry.
from PyExpLabSys.common import utilities
utilities.MAIL_HOST = 'my.mail.host'
utilities.WARNING_EMAIL = 'email-address-to-use-in-case-of-warnings@log.com'
utilities.ERROR_EMAIL = 'email-address-to-use-in-case-of-error@log.com'
# Returns a logger with terminal and emails handlers per default
LOG = utilities.get_logger('my_program_name')
# A rotating file handler can be added:
LOG = utilities.get_logger('my_program_name', file_log=True)
Activating PyExpLabSys library logging in you program¶
PyExpLabSys contains quite a few loggers and exposes a few convinience
functions in the utilities
module for listing and activating them. To
get a list of loggers that are relevant for the modules that you have
imported, you can use either the get_library_logger_names()
function,
which will return you a list or the print_library_logger_names()
function, which prints them out:
from PyExpLabSys.common import sockets
from PyExpLabSys.common.utilities import print_library_logger_names
print_library_logger_names()
produces the following output:
Current PyExpLabSys loggers
===========================
* PyExpLabSys.common.sockets.PullUDPHandler
* PyExpLabSys.common.sockets.DataPushSocket
* PyExpLabSys.common.sockets.PushUDPHandler
* PyExpLabSys.settings
* PyExpLabSys.common.sockets.DateDataPullSocket
* PyExpLabSys.common.sockets.CallBackThread
* PyExpLabSys.common
* PyExpLabSys.common.sockets.CommonDataPullSocket
* PyExpLabSys.common.sockets
* PyExpLabSys.common.sockets.DataPullSocket
* PyExpLabSys
* PyExpLabSys.common.sockets.LiveSocket
To activate a logger use the full path of the logger
e.g. PyExpLabSys.common.sockets.DataPullSocket
and remembers that the
loggers are configured as a tree, so activating PyExpLabSys.common.sockets
will activate all the loggers in that module and activating PyExpLabSys
will activate all PyExpLabSys library loggers.
There are now two ways to activate a logger. One is to configure one from
scratch, using the path of the logger and the same options as in
get_logger()
:
from PyExpLabSys.common import sockets
from PyExpLabSys.common.utilities import activate_library_logging
activate_library_logging(
'PyExpLabSys.common.sockets.DateDataPullSocket',
level='debug',
file_log=True,
file_name='socket_log.txt',
)
This would output all log message at debug level to a file called socket_log.txt.
The other way to activate a library logger is to ask it to enherit all the handlers and levels from an existing logger. This will send all the library log messages to the same destination:
from PyExpLabSys.common.utilities import get_logger, activate_library_logging
from PyExpLabSys.common import sockets
LOG = get_logger('my_program_name')
LOG.info('My program started')
# Configure a library logger to use the same handlers
activate_library_logging(
'PyExpLabSys.common.sockets.DateDataPullSocket',
logger_to_inherit_from=LOG,
)
It is still possible, when inheriting from an existing logger, to set a custom
level for the library logger, using the level
argument as in the example
above.
Using PyExpLabSys drivers outside of PyExpLabSys¶
All I wanted was a banana, but what I got was a gorilla holding a banana
The quote above, is often used to refer to the fact that it can be difficult to use a component from a “framework” separate from the framework.
PyExpLabSys is not a framework as such, but there are some common elements that
are used across different in principle independent modules. Specifically, most
of the drivers in PyExpLabSys will work just fine outside of PyExpLabSys, with a
few very minor modifications, by just copying the file to where the driver is to
be used. Most of the drivers make use of just one other PyExpLabSys module that
tie it to the package, the supported_versions
module. The only thing
that this module does, is to mark the specific driver as working with Python 2,
Python 3 or both, and make a check at run-time of the Python version and
possibly output a warning. It can therefore trivially be removed. To do this,
look to lines of code somewhat like this:
from PyExpLabSys.common.supported_versions import python2_and_3
python2_and_3(__file__)
and comment them out. The specific function that is imported and called, will vary depending on which versions is supported, but that should be fairly simple to figure out.