Записать логи в журнал выполнения контейнера
Примечание
Логирование тарифицируется. Подробнее см. в документации Yandex Cloud Logging.
- В консоли управления
перейдите в каталог, в котором находится контейнер. - Выберите сервис Serverless Containers.
- Выберите контейнер, для которого хотите настроить логирование.
- Перейдите на вкладку Редактор.
- В блоке Логирование в поле Назначение выберите:
Не задано
— чтобы выключить логирование.Каталог
— чтобы записывать логи в лог-группу по умолчанию для каталога, в котором находится контейнер.- (Опционально) В поле Минимальный уровень логирования выберите минимальный уровень логирования.
Лог-группа
— чтобы записывать логи в пользовательскую лог-группу.- (Опционально) В поле Минимальный уровень логирования выберите минимальный уровень логирования.
- В поле Лог-группа выберите лог-группу, в которую будут записываться логи. Если у вас нет лог-группы, создайте ее.
- В верхней части страницы нажмите кнопку Создать ревизию.
Если минимальный уровень логирования задан, в журнал выполнения записываются логи указанного уровня и выше. Если минимальный уровень логирования не задан, в журнал выполнения записываются все логи контейнера.
Если у вас еще нет интерфейса командной строки Yandex Cloud, установите и инициализируйте его.
По умолчанию используется каталог, указанный в профиле CLI. Вы можете указать другой каталог с помощью параметра --folder-name
или --folder-id
.
Назначение логирования
Если в параметрах ревизии контейнера не указана пользовательская лог-группа или логирование не отключено, контейнер автоматически пишет все логи в лог-группу по умолчанию для каталога, в котором он находится.
Чтобы записывать логи в пользовательскую лог-группу, укажите идентификатор лог-группы в параметре --log-group-id
при создании ревизии контейнера. Лог-группа должна находиться в том же каталоге, в котором находится контейнер.
Минимальный уровень логирования
Чтобы задать минимальный уровень логирования, укажите его в параметре --min-log-level
при создании ревизии контейнера.
Если минимальный уровень логирования задан, в журнал выполнения записываются логи указанного уровня и выше. Если минимальный уровень логирования не задан, в журнал выполнения записываются все логи контейнера.
Отключение логирования
Чтобы отключить логирование, при создании ревизии контейнера укажите параметр --no-logging
.
Пример команды
Чтобы записывать логи в пользовательскую лог-группу, выполните команду:
yc serverless container revision deploy \
--container-id <идентификатор_контейнера> \
--image <URL_Docker-образа> \
--service-account-id <идентификатор_сервисного_аккаунта> \
--log-folder-id <идентификатор_каталога> \
--min-log-level <минимальный_уровень_логирования>
Где:
--container-id
— идентификатор контейнера. Чтобы узнать идентификатор, получите список контейнеров.--image
— URL Docker-образа.--service-account-id
— идентификатор сервисного аккаунта, у которого есть права на скачивание Docker-образа.--log-group-id
— идентификатор лог-группы, в которую будут записываться логи.--min-log-level
— минимальный уровень логирования. Необязательный параметр.
Результат:
done (5s)
id: bba9vrtrjlld********
container_id: bbanb9mvu1dl********
created_at: "2024-05-08T07:22:45.378Z"
image:
image_url: cr.yandex/crprip91p1q9********/ubuntu:hello
image_digest: sha256:aa55c46fba9b14b8d8de16e2f8a07d716edfb1dbbb9433b827214ad2********
resources:
memory: "1073741824"
cores: "1"
core_fraction: "100"
execution_timeout: 3s
service_account_id: ajeh91ebakk1********
status: ACTIVE
log_options:
log_group_id: e23824sf51g5********
min_level: ERROR
Terraform
Terraform распространяется под лицензией Business Source License
Подробную информацию о ресурсах провайдера смотрите в документации на сайте Terraform
Если у вас еще нет Terraform, установите его и настройте провайдер Yandex Cloud.
Назначение логирования
Если в параметрах ревизии контейнера не указана пользовательская лог-группа или логирование не отключено, контейнер автоматически пишет все логи в лог-группу по умолчанию для каталога, в котором он находится.
Чтобы записывать логи в пользовательскую лог-группу, в блоке log_options
укажите идентификатор лог-группы в параметре log_group_id
при создании ревизии контейнера. Лог-группа должна находиться в том же каталоге, в котором находится контейнер.
Минимальный уровень логирования
Чтобы задать минимальный уровень логирования, укажите его в параметре log_group_id
при создании ревизии контейнера.
Если минимальный уровень логирования задан, в журнал выполнения записываются логи указанного уровня и выше. Если минимальный уровень логирования не задан, в журнал выполнения записываются все логи контейнера.
Отключение логирования
Чтобы отключить логирование, при создании ревизии контейнера в блоке log_options
укажите параметр disabled
со значением true
.
Пример
Чтобы записывать логи в пользовательскую лог-группу:
-
Откройте файл конфигурации Terraform и добавьте к описанию ресурса
yandex_serverless_container
блокlog_options
:Пример структуры конфигурационного файла:
resource "yandex_serverless_container" "<имя_контейнера>" { name = "<имя_контейнера>" service_account_id = "<идентификатор_сервисного_аккаунта>" memory = <объем_RAM> image { url = "<URL_Docker-образа>" } log_options { folder_id = "<идентификатор_каталога>" min_level = "<минимальный_уровень_логирования>" } }
Где:
name
— имя контейнера.service_account_id
— идентификатор сервисного аккаунта, у которого есть права на скачивание Docker-образа.memory
— требуемая память. По умолчанию — 128 МБ.url
— URL Docker-образа.folder_id
— идентификатор каталога.min_level
— минимальный уровень логирования. Необязательный параметр.
Более подробную информацию о параметрах ресурса
yandex_serverless_container
см. в документации провайдера . -
Создайте ресурсы:
-
В терминале перейдите в папку, где вы отредактировали конфигурационный файл.
-
Проверьте корректность конфигурационного файла с помощью команды:
terraform validate
Если конфигурация является корректной, появится сообщение:
Success! The configuration is valid.
-
Выполните команду:
terraform plan
В терминале будет выведен список ресурсов с параметрами. На этом этапе изменения не будут внесены. Если в конфигурации есть ошибки, Terraform на них укажет.
-
Примените изменения конфигурации:
terraform apply
-
Подтвердите изменения: введите в терминале слово
yes
и нажмите Enter.
-
Чтобы записывать логи в журнал выполнения контейнера, воспользуйтесь методом REST API deployRevision для ресурса Container или вызовом gRPC API ContainerService/DeployRevision.
Структурированные логи
Кроме текстовых записей, в стандартный поток вывода (stdout
) и стандартный поток вывода ошибок (stderr
) можно писать структурированные логи.
Примеры приложений и Dockerfile
index.js
const winston = require('winston');
const express = require('express');
const logger = winston.createLogger({
level: 'debug',
format: winston.format.json(),
transports: [new winston.transports.Console()],
});
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.get("/", (req, res) => {
logger.info({"message": "My log message", "my-key": "my-value"})
return res.send("Hello, world!");
});
app.listen(process.env.PORT);
Dockerfile
FROM node:16-slim
WORKDIR /app
RUN npm install winston express
COPY ./index.js .
CMD [ "node", "index.js" ]
requirements.txt
python-json-logger==2.0.4
sanic==22.12.0
index.py
import logging
import os
from pythonjsonlogger import jsonlogger
from sanic import Sanic
from sanic.response import text
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")
app = Sanic(__name__)
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)
@app.route("/")
async def hello(request):
logger.info("My log message", extra={"my-key": "my-value"})
return text("Hello, world!", status=200)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=int(os.environ['PORT']), motd=False, access_log=False)
Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY ./index.py .
COPY ./requirements.txt .
RUN pip install --no-cache-dir --prefer-binary --requirement=./requirements.txt
CMD [ "python", "index.py" ]
index.go
package main
import (
"go.uber.org/zap"
"net/http"
"os"
)
func main() {
zapConfig := zap.NewProductionConfig()
zapConfig.DisableCaller = true
zapConfig.Level.SetLevel(zap.DebugLevel)
logger, _ := zapConfig.Build()
portStr := os.Getenv("PORT")
http.Handle("/", handler{logger})
http.ListenAndServe(":"+portStr, nil)
}
type handler struct {
logger *zap.Logger
}
func (h handler) ServeHTTP(writer http.ResponseWriter, _ *http.Request) {
h.logger.Info(
"My log message",
zap.String("my-key", "my-value"),
)
writer.WriteHeader(200)
_, _ = writer.Write([]byte("Hello, world!"))
}
Dockerfile
FROM golang:latest AS build
WORKDIR /app
ADD index.go .
ADD go.mod .
ADD go.sum .
RUN go build -a -tags netgo -ldflags '-w -extldflags "-static"' -o server-app *.go
FROM scratch
COPY --from=build /app/server-app /server-app
ENTRYPOINT ["/server-app"]