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} |