Cloud and Software Architecture, Soft skills, IOT and embedded
Log! Don't Print! Use the Python logging library
Get link
Facebook
Twitter
Pinterest
Email
Other Apps
Python has become one of the most popular application languages in IT, shadow-IT, and data science. Python developers continually improve their systems by iterating from example patterns to best practices.
The Python logging package should be used wherever print() statements were in the past. The logging package makes it possible to classify output at different severities. logging has the ability to enable and disable the generation of output at those different levels. This means you can create debug-level statements that are useful to programmers without letting those statements bleed into a production application. The referenced GitHub project shows how to load logging configurations, and how to change where logging goes based on those configurations.
Classify output by severity
Filter output generation by severity
Send data to different sinks based on the program module and the severity
Logging Design
Logging is routed through loggers that are instantiated in each python module. Those loggers are configured with one or more handlers. Each handler writes to its own log sink based on the filter criteria it was initialized with. This means a log message can be written out by 0 or more handlers depending on the logging level of the message and the filter message of the handlers.
Watch the video or read the Python logging documentation for an explanation of how levels work. I'm too tired to write it up right now.
Our log output format, handler configurations, and logger configurations are all stored in a yaml file. This file shows a variety of formatters and handlers. It contains a custom configuration for each python module that intends to log. Small programs can probably just run with the console logger and the root configuration. Larger or production programs will probably have something more detailed like this example.
The logging module must be initialized one time. Here we have a function that we can call on program startup to initialize the logging configuration.
importlogging
importlogging.config
importyaml
defload_logging():
withopen("logging_config.yaml", "r") asf:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
Creating a logger in main()
Load the logging module one time on startup. Here we demonstrate loading the config at the top of main()
importlogging
fromloggingconfigimportload_logging
def main():
load_logging()
logger = logging.getLogger(__name__)
Creating a logger in a Multi-processor Class
Each python file will need access to a logger. The sample program is a bunch of multi-processing modules. We can create a logger in the __init__() function. Non-class python files can just do it at the top.
Non-class python files also need to create a logger. In this case the module will actually be __main__ . Note that this example shows both initializing the logging system and creating the logger for this file.
if__name__ == "__main__":
load_logging()
logger = logging.getLogger(__name__)
Logging a message and deferring string construction
It is very important that you do not pre-construct logging strings. The logger will format the logging string only if the message is actually going to be sent to one of the sinks. A log of logging, especially debug(), will never make it past the handlers. The type of string formatting shown below will insure that the debug() log strings would never be created in those situations.
The Windows Subsystem for Linux operates as a virtual machine that can dynamically grow the amount of RAM to a maximum set at startup time. Microsoft sets a default maximum RAM available to 50% of the physical memory and a swap-space that is 1/4 of the maximum WSL RAM. You can scale those numbers up or down to allocate more or less RAM to the Linux instance. The first drawing shows the default WSL memory and swap space sizing. The images below show a developer machine that is running a dev environment in WSL2 and Docker Desktop. Docker Desktop has two of its own WSL modules that need to be accounted for. You can see that the memory would actually be oversubscribed, 3 x 50% if every VM used its maximum memory. The actual amount of memory used is significantly smaller allowing every piece to fit. Click to Enlarge The second drawing shows the memory allocation on my 64GB laptop. WSL Linux defaults to a maximum RAM size of 5
I wanted to access all my Azure resources without making any of them visible to the Internet. The easiest give my local machine access to everything on my Azure Virtual Network (VNET) was to connect to it over VPN. It turns out creating Azure VPN gateways and connecting to Azure VPN endpoints is easy. There are some subtleties in getting DNS name resolution to work that can confuse when first starting out. Setting the Stage There are a few ways to get to Azure endpoints and resources that are blocked from the internet. We can Create a Point-to-Site connection from our local machines to Azure Network Gateways Create a Site-to-Site network connection from our local networks to Azure Network Gateways. Use Bastion Hosts Use Cloud Shell Leave everything open to the internet. I chose a Point-to-Site (P2S) VPN connection that connects from my laptop to a VNet Gateway. That joins my laptop
Create Storage Spaces in Windows 10 Windows Server O/S contains Storage Spaces support for Server Spaces tiered storage. You can front slower spinning disks with smaller faster SSDs. Windows 10 has a Storage Spaces GUI Control Panel that does not include the tiered storage GUI. This means Powershell must be used for all configuration. https://github.com/freemansoft/win10-storage-spaces contains scripts that create tiered storage pools that integrate SSDs as caching drives and HDDs as storage drives. They assume you have at least one SSD and one HDD. The scripts automatically find all raw drives and add them to the pool. Some HDDs have their types incorrectly identified. The script can coerce them to be MediaType:HDD The entire virtual drive is added to the system as a single large volume You need at least 1 SSD and 1 HDD to run cached storage / Simple resiliency 2 SSD and 2 HDD to run cached storage / Mirror resiliency / 1 SSD and 2 HDD to run cached storage / Simple re
Comments
Post a Comment