Function's Service Account should have role logging.writer
context.function_name DOES contain function id
Thanks to https://github.com/mcode-cc/python-yandex-cloud-logging library
Function's Service Account should have role logging.writer
context.function_name DOES contain function id
Thanks to https://github.com/mcode-cc/python-yandex-cloud-logging library
| import yandexcloud | |
| from pyclm.logging import Logger | |
| def handler(event, context): | |
| log = Logger( | |
| sdk=yandexcloud.SDK(), | |
| log_group_id="e23l2...", | |
| resource_type="serverless.function", | |
| resource_id=context.function_name, | |
| elements=1, | |
| period=0 | |
| ) | |
| log.error( | |
| "message test", | |
| request_id=context.request_id, | |
| version_id=context.function_version | |
| ) | |
| return {'statusCode': 200} |
| python-yandex-cloud-logging==0.1.0 | |
| # only for using_module.py | |
| git+https://github.com/vitkhab/[email protected]#egg=yc_cloud_logging_handler==0.1.0 |
| import yandexcloud | |
| from pyclm.logging import Logger | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| # Without nullifying root logger handlers log dubles would be produced: one entry to | |
| # Cloud Logging and one entry to Function logs (which also be shown in Cloud Logging) | |
| root_logger = logging.getLogger() | |
| root_logger.handlers = [] | |
| class YandexCloudLoggingHandler(logging.Handler): | |
| def __init__(self, log_group_id, resource_id, request_id, function_version): | |
| logging.Handler.__init__(self) | |
| self.request_id = request_id | |
| self.function_version = function_version | |
| self.logger = Logger( | |
| sdk=yandexcloud.SDK(), | |
| log_group_id=log_group_id, | |
| resource_type="serverless.function", | |
| resource_id=resource_id, | |
| elements=1, | |
| period=0 | |
| ) | |
| self.loggers = { | |
| "TRACE": self.logger.trace, | |
| "DEBUG": self.logger.debug, | |
| "INFO": self.logger.info, | |
| "WARN": self.logger.warn, | |
| "ERROR": self.logger.error, | |
| "FATAL": self.logger.fatal | |
| } | |
| def emit(self, record): | |
| msg = self.format(record) | |
| if record.levelname in self.loggers: | |
| self.loggers[record.levelname]( | |
| msg, | |
| request_id=self.request_id, | |
| version_id=self.function_version | |
| ) | |
| else: | |
| self.loggers["DEBUG"]( | |
| msg, | |
| request_id=self.request_id, | |
| version_id=self.function_version | |
| ) | |
| def push_info(): | |
| logger.info("test info message") | |
| def push_error(): | |
| logger.error("test error message") | |
| def handler(event, context): | |
| ycl_handler = YandexCloudLoggingHandler( | |
| log_group_id="e23l2k...", | |
| resource_id=context.function_name, | |
| request_id=context.request_id, | |
| function_version=context.function_version | |
| ) | |
| formatter = logging.Formatter("%(filename)s on %(lineno)s: %(message)s") | |
| ycl_handler.setFormatter(formatter) | |
| # I presume Cloud function stays in memory for sometime. If there are several | |
| # requests in a row there will be several handlers added. So check is needed. | |
| for handler in logger.handlers: | |
| if isinstance(handler, YandexCloudLoggingHandler): | |
| break | |
| else: | |
| logger.addHandler(ycl_handler) | |
| logger.setLevel(logging.INFO) | |
| push_info() | |
| push_error() | |
| return {'statusCode': 200} |
| from yc_cloud_logging_handler import YandexCloudLoggingHandler | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| # Without nullifying root logger handlers log dubles would be produced: one entry to | |
| # Cloud Logging and one entry to Function logs (which also be shown in Cloud Logging) | |
| root_logger = logging.getLogger() | |
| root_logger.handlers = [] | |
| def push_info(): | |
| logger.info("test info message") | |
| def push_error(): | |
| logger.error("test error message") | |
| def handler(event, context): | |
| ycl_handler = YandexCloudLoggingHandler( | |
| log_group_id="e23l2...", | |
| resource_id=context.function_name, | |
| request_id=context.request_id, | |
| function_version=context.function_version | |
| ) | |
| formatter = logging.Formatter("%(filename)s on %(lineno)s: %(message)s") | |
| ycl_handler.setFormatter(formatter) | |
| # I presume Cloud function stays in memory for sometime. If there are several | |
| # requests in a row there will be several handlers added. So check is needed. | |
| for handler in logger.handlers: | |
| if isinstance(handler, YandexCloudLoggingHandler): | |
| break | |
| else: | |
| logger.addHandler(ycl_handler) | |
| logger.setLevel(logging.INFO) | |
| push_info() | |
| push_error() | |
| return {'statusCode': 200} |