Записать логи в журнал выполнения функции
Примечание
Логирование тарифицируется. Подробнее см. в документации Yandex Cloud Logging.
- В консоли управления
перейдите в каталог, в котором находится функция. - Выберите сервис Cloud Functions.
- Выберите функцию, для которой хотите настроить логирование.
- Перейдите на вкладку Редактор.
- В блоке Логирование в поле Назначение выберите:
Не задано
— чтобы выключить логирование.Каталог
— чтобы записывать логи в лог-группу по умолчанию для каталога, в котором находится функция.- (Опционально) В поле Минимальный уровень логирования выберите минимальный уровень логирования.
Лог-группа
— чтобы записывать логи в пользовательскую лог-группу.- (Опционально) В поле Минимальный уровень логирования выберите минимальный уровень логирования.
- В поле Лог-группа выберите лог-группу, в которую будут записываться логи. Если у вас нет лог-группы, создайте ее.
- Нажмите кнопку Сохранить изменения.
Если минимальный уровень логирования задан, в журнал выполнения записываются логи указанного уровня и выше. Если минимальный уровень логирования не задан, в журнал выполнения записываются все логи функции.
Если у вас еще нет интерфейса командной строки Yandex Cloud, установите и инициализируйте его.
По умолчанию используется каталог, указанный в профиле CLI. Вы можете указать другой каталог с помощью параметра --folder-name
или --folder-id
.
Назначение логирования
Если в параметрах версии функции не указана пользовательская лог-группа или логирование не отключено, функция автоматически пишет все логи в лог-группу по умолчанию для каталога, в котором она находится.
Чтобы записывать логи в пользовательскую лог-группу, укажите идентификатор лог-группы в параметре --log-group-id
при создании версии функции. Лог-группа должна находиться в том же каталоге, в котором находится функция.
Минимальный уровень логирования
Чтобы задать минимальный уровень логирования, укажите его в параметре --min-log-level
при создании версии функции.
Если минимальный уровень логирования задан, в журнал выполнения записываются логи указанного уровня и выше. Если минимальный уровень логирования не задан, в журнал выполнения записываются все логи функции.
Отключение логирования
Чтобы отключить логирование, при создании версии функции укажите параметр --no-logging
.
Пример команды
Чтобы записывать логи в пользовательскую лог-группу, выполните команду:
yc serverless function version create \
--function-id <идентификатор_функции> \
--runtime <среда_выполнения> \
--entrypoint <точка_входа> \
--memory <объем_RAM> \
--source-path <ZIP-архив_c_кодом_функции> \
--log-group-id <идентификатор_лог-группы> \
--min-log-level <минимальный_уровень_логирования>
Где:
--function-id
— идентификатор функции.--runtime
— среда выполнения.--entrypoint
— точка входа, указывается в формате<имя_файла_без_расширения>.<имя_обработчика>
.--memory
— объем RAM.--source-path
— ZIP-архив c кодом функции и необходимыми зависимостями.--log-group-id
— идентификатор лог-группы, в которую будут записываться логи.--min-log-level
— минимальный уровень логирования. Необязательный параметр.
Результат:
done (4s)
id: d4ech7qdki6r********
function_id: d4e7tbg7m4np********
created_at: "2024-04-19T10:13:00.019Z"
runtime: python37
entrypoint: index.handler
resources:
memory: "134217728"
execution_timeout: 5s
image_size: "53248"
status: ACTIVE
tags:
- $latest
log_options:
log_group_id: e23u2vn449av********
min_level: DEBUG
Terraform
Terraform распространяется под лицензией Business Source License
Подробную информацию о ресурсах провайдера смотрите в документации на сайте Terraform
Если у вас еще нет Terraform, установите его и настройте провайдер Yandex Cloud.
Назначение логирования
Если в параметрах версии функции не указана пользовательская лог-группа или логирование не отключено, функция автоматически пишет все логи в лог-группу по умолчанию для каталога, в котором она находится.
Чтобы записывать логи в пользовательскую лог-группу, в блоке log_options
укажите идентификатор лог-группы в параметре log_group_id
при создании версии функции. Лог-группа должна находиться в том же каталоге, в котором находится функция.
Минимальный уровень логирования
Чтобы задать минимальный уровень логирования, укажите его в параметре log_group_id
при создании версии функции.
Если минимальный уровень логирования задан, в журнал выполнения записываются логи указанного уровня и выше. Если минимальный уровень логирования не задан, в журнал выполнения записываются все логи функции.
Отключение логирования
Чтобы отключить логирование, при создании версии функции в блоке log_options
укажите параметр disabled
со значением true
.
Пример
Чтобы записывать логи в пользовательскую лог-группу:
-
Откройте файл конфигурации Terraform и добавьте к описанию ресурса
yandex_function
блокlog_options
:Примеры структуры конфигурационного файла:
resource "yandex_function" "<имя_функции>" { name = "<имя_функции>" user_hash = "<произвольная_строка>" runtime = "<среда_выполнения>" entrypoint = "<точка_входа>" memory = "<объем_RAM>" content { zip_filename = "<имя_ZIP-архива>" } log_options { log_group_id = "<идентификатор_лог-группы>" min_level = "<минимальный_уровень_логирования>" } }
Где:
name
— имя функции.user_hash
— произвольная строка, определяющая версию функции.runtime
— среда выполнения функции.entrypoint
— имя функции в исходном коде, которая будет служить точкой входа в приложения.memory
— объем памяти в мегабайтах, отведенный для выполнения функции.content
— исходный код функции.zip_filename
— имя ZIP-архива, содержащего исходный код функции.
log_group_id
— идентификатор лог-группы, в которую будут записываться логи.min_level
— минимальный уровень логирования. Необязательный параметр.
Более подробную информацию о параметрах ресурса
yandex_function
см. в документации провайдера . -
Проверьте конфигурацию командой:
terraform validate
Если конфигурация является корректной, появится сообщение:
Success! The configuration is valid.
-
Выполните команду:
terraform plan
В терминале будет выведен список ресурсов с параметрами. На этом этапе изменения не будут внесены. Если в конфигурации есть ошибки, Terraform на них укажет.
-
Примените изменения конфигурации:
terraform apply
-
Подтвердите изменения: введите в терминал слово
yes
и нажмите Enter.
Чтобы записывать логи в журнал выполнения функции, воспользуйтесь методом REST API createVersion для ресурса Function или вызовом gRPC API FunctionService/LogOptions.
Структурированные логи
Кроме текстовых записей, в стандартный поток вывода (stdout
) и стандартный поток вывода ошибок (stderr
) можно писать структурированные логи.
Примеры функций
package.json
{
"name": "server-app",
"version": "1.0.0",
"dependencies": {
"winston": "^3.8.2"
}
}
index.js
const winston = require('winston');
const logger = winston.createLogger({
level: 'debug',
format: winston.format.json(),
transports: [new winston.transports.Console()],
});
module.exports.handler = async function (event, context) {
logger.info({"message": "My log message", "my-key": "my-value"})
return {
statusCode: 200,
body: 'Hello World!',
};
};
requirements.txt
python-json-logger==2.0.4
index.py
import logging
from pythonjsonlogger import jsonlogger
class YcLoggingFormatter(jsonlogger.JsonFormatter):
def add_fields(self, log_record, record, message_dict):
super(YcLoggingFormatter, self).add_fields(log_record, record, message_dict)
log_record['logger'] = record.name
log_record['level'] = str.replace(str.replace(record.levelname, "WARNING", "WARN"), "CRITICAL", "FATAL")
logHandler = logging.StreamHandler()
logHandler.setFormatter(YcLoggingFormatter('%(message)s %(level)s %(logger)s'))
logger = logging.getLogger('MyLogger')
logger.propagate = False
logger.addHandler(logHandler)
logger.setLevel(logging.DEBUG)
def handler(event, context):
logger.info("My log message", extra={"my-key": "my-value"})
return "Hello, world!"
index.go
package main
import (
"context"
"go.uber.org/zap"
)
type Response struct {
StatusCode int `json:"statusCode"`
Body interface{} `json:"body"`
}
func Handler(ctx context.Context) (*Response, error) {
config := zap.NewProductionConfig()
config.DisableCaller = true
config.Level.SetLevel(zap.DebugLevel)
logger, _ := config.Build()
defer logger.Sync()
logger.Info(
"My log message",
zap.String("my-key", "my-value"),
)
return &Response{
StatusCode: 200,
Body: "Hello, world!",
}, nil
}
pom.xml
...
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.19.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.19.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-layout-template-json</artifactId>
<version>2.19.0</version>
</dependency>
...
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<JsonTemplateLayout eventTemplateUri="classpath:YcLoggingLayout.json"/>
</Console>
</Appenders>
<Loggers>
<Root level="TRACE">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
YcLoggingLayout.json
{
"message": {
"$resolver": "message",
"stringified": true
},
"level": {
"$resolver": "level",
"field": "name"
},
"logger": {
"$resolver": "logger",
"field": "name"
},
"labels": {
"$resolver": "mdc",
"flatten": true,
"stringified": true
},
"tags": {
"$resolver": "ndc"
}
}
Handler.java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import java.util.function.Function;
public class Handler implements Function<String, String> {
private static final Logger logger = LogManager.getLogger();
@Override
public String apply(String s) {
ThreadContext.put("my-key", "my-value");
logger.info("My log message");
ThreadContext.clearAll();
return "Hello, world!";
}
}