Logging
Logging is a means of tracking events that happen when some software runs. Under the bench architecture, with multitenancy, it might get really complicated really fast to track down and eliminate any uncertainties. You may wan't to log events along with circumstantial, variable data.
DontManage implements Python's logging module to maintain bench and site wise logs. Version 13 uses Log Rotation to maintain the last 20 files along with the current running of 100kB each for the out of the box log files.
dontmanage.log_level
Maintains the log level of DontManage processes. To learn more about logging levels, you can check out Python's documentation.
dontmanage.utils.logger.set_log_level
dontmanage.utils.logger.set_log_level(level) can be used to set the log level and regenerate the loggers dynamically.
dontmanage.loggers
dontmanage.loggers maintains a dict of active loggers in your process. The key is the name of the logger, typically "{module}-{site}" and the value holds the Logger instance.
A web worker may have dontmanage.loggers such as the following if docs.dontmanageerp.com and dontmanageframework.com are the sites on the bench.
{
"dontmanage.web-docs.dontmanageerp.com": <logger dontmanage.web-docs.dontmanageerp.com="" (debug)="">,
"dontmanage.web-dontmanageframework.com": <logger dontmanage.web-dontmanageframework.com="" (debug)="">
}dontmanage.logger
dontmanage.logger(module, with_more_info, allow_site, filter, max_size, file_count)
Returns a logging.Logger object with Site and Bench level logging capabilities. If logger doesn't already exist, creates and updatesdontmanage.loggers.
Arguments:
module: Name of your logger and consequently your log file.
with_more_info: Will log the
Form Dictas additional information, typically useful for requests.allow_site: Pass site name to explicitly log under it's logs. If
Trueand unspecified, guesses which site the logs would be saved under.filter: Add a filter function for your logger.
max_size: Max file size of each log file in bytes.
file_count: Max count of log files to be retained via Log Rotation.
Usage
dontmanage.logger("dontmanage.web").debug({
"site": "dontmanageframework.com",
"remote_addr": "192.148.1.7",
"base_url": "https://dontmanageframework.com/docs/v14/user/en/api/logging",
"full_path": "/docs/v14/user/en/api/logging",
"method": "POST",
"scheme": "https",
"http_status_code": 200
})2020-07-31 16:06:55,067 DEBUG dontmanage.web {'site': 'dontmanageframework.com', 'remote_addr': '192.148.1.7', 'base_url': 'https://dontmanageframework.com/docs/v14/user/en/api/logging', 'full_path': '/docs/v14/user/en/api/logging', 'method': 'POST', 'scheme': 'https', 'http_status_code': 200}The above entry would be logged under ./logs/dontmanage.web.log and ./sites/dontmanageframework.com/logs/dontmanage.web.log files.
Usage specified as implemented in app.py#L102-L110
Example
Consider a scenario where you've written an API for updating a counter with the value sent by the user and return the updated value. Now you want to log information in the API, to make sure it's working as expected. So, you create a logger api to track events for the same.
dontmanage.utils.logger.set_log_level("DEBUG")
logger = dontmanage.logger("api", allow_site=True, file_count=50)
@dontmanage.whitelist()
def update(value):
user = dontmanage.session.user
logger.info(f"{user} accessed counter_app.update with value={value}")
current_value = dontmanage.get_single_value("Value", "counter")
updated_value = current_value + value
logger.debug(f"{current_value} + {value} = {updated_value}")
dontmanage.db.set_value("Value", "Value", "counter", updated_value)
logger.info(f"{user} updated value to {value}")
return updated_valueAPI calls made to this endpoint will now start getting logged in your api.log as follows
2020-07-31 16:06:55,067 INFO api gavin@dontmanage.io accessed counter_app.update with value 100
2020-07-31 16:06:55,067 DEBUG api 1000 + 100 = 1100
2020-07-31 16:06:55,068 INFO api gavin@dontmanage.io updated value to 1100Learn more about Logging in DontManage here