Openapi (7 части серии)
Все связанные с кодом этой статьи были добавлены в Серия Openapi репо, Открытый TF-пример Отказ
Прочитайте описание в последней главе, как запустить его и просмотреть результаты в журналах CloudWatch.
Спасибо за чтение!
- TL; доктор
- Тема разрыва
- Как вести вход на aw serverless
- Инфраструктурный код
- Конфигурация logs logs
- API Gateway
- Интеграция Openapi
- Корреляционный идентификатор
- Рекуга вручную в производстве
- Код выполнения
- Уровень журнала отладки в производстве
- Настройка идентификатора корреляции и переадресация
- Журнал агрегатор и поиск
- Пример
- CloudWatch Logs Insights
- Что дальше
- дальнейшее чтение
- Регистрация лучших практик
- Библиотеки журналов узлов и как-к:
- Главные журналы CloudWatch и мониторинг:
На мой взгляд, вход на AWS Serverless можно разбить на 4 области:
1) Код инфраструктуры Здесь нам нужно настроить услуги, которые поддерживают любые лесозаготовительные мероприятия. Такие как; — AWS CloudWatch журналы группы для AWS Lambda; Настраивает соответствующие группы и срок хранения журнала для обеспечения снижения затрат. — Спецификация Openapi Нам нужно иметь возможность пересылать отладку и регистрацию информации в заголовки. Мы можем смоделировать это как Параметры заголовка Отказ Таким образом, нет догадки работы в команде развития. 2) Код выполнения , Регистратор регистрации и выбранные стандарты. В основном, как мы воспоминаем и в какую структуру мы это делаем. Мы должны учитывать, что машины могут анализировать информацию. 3) Журнал агрегатор AWS CloudWatch Logs — это агрегатор, который мы будем использовать для этой статьи, но есть много сторонних альтернатив. 4) Журнал Поиск , что-то сломается (это всегда делает), как вы узнаете, где его сломаны и как это сломалось? Нам нужно иметь возможность связать информацию о регистрации в нескольких услугах на AWS.
Прежде чем мы попадем в каждую из этих районов, пара основных основных правил для регистрации вы должны подать заявку:
Используйте JSON Для каждого из ваших выходов журнала, чтобы сделать их доступными для поиска, например CloudWatch Logs Insights Отказ
- Стандартизировать форматирование, как это, например:
{
"message": "Sns message received",
"level": "info",
"service": "dev-example-user_receiver",
"operationName": "",
"version": "$LATEST",
"claims": "No Authorization Required",
"source": "",
"x_correlation_id": "12345",
"timestamp": "2020-02-09 13:37:22"
}
Используйте Регистрация рамок Это стандартизирует выход, но также можно легко отправить ваши журналы на другие выходы потоки, такие как S3, Kinesis, Elasticsearch ETC
- Уинстон Для узла/JavaScript является хорошей библиотекой, которая поддерживает несколько выходных потоков (I.E. «Транспортировка»).
Автоматизировать соответствующие «метаданные» поля как можно больше.
- Например. Для аутентифицированных вызовов API мы, вероятно, хотим знать, кто аутентифицирован, и где вызов возникла из (IP-адрес).
Анонимизуйте свои журналы , мы не хотим видеть информацию о кредитной карте в файлах журналов или адреса электронной почты.
- GDPR требует, чтобы каждый бит личной информации должен быть съемным, мы можем начать убедиться, что журналы могут начинаться с.
Оберните свой поставщик Библиотека для ваших проектов.
- Вы можете настроить журнал, и вы можете поменять библиотеки и выходить без необходимости перезаписать все ваши операторы журнала.
Чтобы начать с набору инфраструктуры, нам нужно включить несколько вещей, сначала для AWS Lambda. Затем для Gateway API, включив в журнал и настройки заголовка для ведения журнала и API.
Конфигурация logs logs
Убедитесь, что вы устанавливаете срок хранения в журналах, без этого параметра вы накапливаете много данных, и он может быстро потратить дорогу.
Сделайте следующее для каждой из ваших функций лямбда:
variable "log_retention_in_days" {
description = "How many days should logs be kept in CloudWatch"
type = number
default = 30
}
resource "aws_cloudwatch_log_group" "_" {
name = "/aws/lambda/${local.function_name}"
retention_in_days = var.log_retention_in_days
}
API Gateway
Рядом с включением подробных метрик CloudWatch (см. Последние недели Статья ), мы также можем конкретно установить уровень ведения журнала для этого развернутого этапа, есть 3 настроек; «OFF», «Информация» и «Ошибка». ID Рекомендую установить это на Ошибка в dev.tfvars Общие настройки развертывания:
api_throttling_rate_limit = 5 api_throttling_burst_limit = 10 api_metrics_enabled = true api_logging_level = "ERROR"
и затем в ресурсе настроек настроек, мы применяем его для сцены дев :
resource "aws_api_gateway_method_settings" "_" {
rest_api_id = aws_api_gateway_rest_api._.id
stage_name = aws_api_gateway_stage._.stage_name
method_path = "*/*"
settings {
throttling_burst_limit = var.api_throttling_burst_limit
throttling_rate_limit = var.api_throttling_rate_limit
metrics_enabled = var.api_metrics_enabled
logging_level = var.api_logging_level
}
}
Интеграция Openapi
Теперь на реальную реализацию API.
Корреляционный идентификатор
Идентификатор корреляции убедитесь, что мы сможем проследить все наши журналы (и, таким образом, выполнять) через цепь без сервеса. Если вызовы B, а затем C, мы можем увидеть все связанные в журнал, запросив на идентификатор корреляции. Подробнее об этом в последней главе, как запросить с AWS CloudWatch Logs Insights.
Чтобы убедиться, что каждый разработчик в вашей команде фактически использует заголовок идентификатора корреляции при вызове вашего API. Добавьте его в спецификацию openapi, как это:
components:
parameters:
correlationIdHeader:
description: Unique string that can trace execution across services
in: header
name: x-correlation-id
schema:
type: string
required: true
Затем в нашем пути API мы добавляем ссылку на параметр под Параметры ;
/user:
post:
operationId: postUser
description: Add a new user
parameters:
- $ref: '#/components/parameters/correlationIdHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/User'
x-amazon-apigateway-integration:
uri: "arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/${lambda_user_arn}/invocations"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
timeoutInMillis: ${lambda_user_timeout}
type: "aws_proxy"
responses:
200:
$ref: '#/components/responses/lambda'
400:
$ref: '#/components/responses/lambda'
500:
$ref: '#/components/responses/500APIError'
tags:
- User
Рекуга вручную в производстве
В производственной среде мы не хотим захватывать всю нашу регистрацию отладки, она будет очень дорого в высоких ситуациях нагрузки, поэтому мы хотим захватить только небольшой процент отладки, что мы все еще можем действовать на эту информацию в случае производства ошибки.
Во-первых, нам понадобится Уровень журнала отладки Параметр в заголовке вызовов API из спецификации вызова OPRAPI, аналогично идентификатору корреляции, вы можете указать заголовок уровня отладки с возможными значениями:
components:
parameters:
debugHeader:
description: Force debug level for this execution run
in: header
name: x-debug-level
schema:
type: string
enum: [error, debug, info]
required: false
Теперь мы можем захватить любую явную установить уровень отладки и принесите эту настройку по всей цепочке служб выполнения. Но к этому мы хотели бы автоматизировать, когда он должен установить уровень отладки. Мы можем установить это в программном обеспечении с помощью конфигурации частоты обратной частоты отладки, мы сделали в качестве переменной среды. Как сделать фактическую программную часть, мы раскроем следующую главу.
В наших dev.tfvars мы можем установить частоту дискретизации.
debug_sample_rate = 0.05
Это будет применяться к переменной среде AWS Lambda после развертывания:
module "lambda" {
source = "../../modules/lambda"
# Removed several parameters for brevity
lambda_environment_variables = {
NAMESPACE = var.namespace
REGION = var.region
COGNITO_USER_POOL_CLIENT_ID = var.cognito_user_pool_client_id
COGNITO_USER_POOL_ID = var.cognito_user_pool_id
DEBUG_SAMPLE_RATE = var.debug_sample_rate
SNS_TOPIC = module.sns.topic_arn
}
}
Теперь нам просто нужно включить частоту дискретизации и убедиться, что мы возьмем идентификатор корреляции и примените его к следующей точке интеграции.
Уровень журнала отладки в производстве
Для этого мы можем использовать Debug_sample_rate Переменная среды. В нашем коде лесозаготовки мы хотим убедиться, что мы захватываем этот параметр следующим образом:
Logger.prototype.setLogLevel = function () {
const logLevel = this.getLogLevel()
if (logLevel === undefined) {
if (process.env.NAMESPACE === 'prod') {
if (process.env.DEBUG_SAMPLE_RATE > Math.random()) {
return 'debug'
} else {
return 'error' // for Production environment
}
} else {
return 'debug' // for development and test environments
}
}
return logLevel
}
Чтобы убедиться, что это переносится через вызовы услуг, мы можем явно установить уровень журнала с заголовком в нашем API Gateway Звонки или через параметры в SNS С SQS , вызов услуг например. Это решение может быть передано и установлено с DEBUGLEVEL Переменная:
Logger.prototype.HTTP_DEBUG_HEADER = 'x-debug-level'
Logger.prototype.getLogLevel = function () {
if (this.isApiGateway()) return this.event.headers[this.HTTP_DEBUG_HEADER]
if (this.isSNS()) return this.event.Records[0].Sns.MessageAttributes.x_debug_level.Value
// add more relevant services here..
// No debug level set, revert to defaults
return undefined
}
Настройка идентификатора корреляции и переадресация
Мы видели, как идентификатор корреляции устанавливается на Gateway AWS API, мы используем заголовок, чтобы применить его в времени выполнения API.
Чтобы переслать его для AWS SNS, мы должны встроить его в реальную полезную нагрузку сообщений. У нас нет заголовков, которые мы можем здесь можно установить.
В Библиотека SNS Код, мы добавляем атрибут сообщения следующим образом:
var params = {
Message: message,
MessageAttributes: {
x_correlation_id: {
DataType: 'String',
StringValue: correlationId
}
},
TopicArn: topicARN
}
const results = await sns.publish(params).promise()
Для получения и обработки идентификатора корреляции на другом конце мы сделаем следующее в корреляционная библиотека :
CorrelationId.prototype.HTTP_CORRELATION_ID_HEADER = 'x-correlation-id'
CorrelationId.prototype.getCorrelationID = function () {
if (this.isApiGateway()) return this.event.headers[this.HTTP_CORRELATION_ID_HEADER]
if (this.isSNS()) return this.event.Records[0].Sns.MessageAttributes.x_correlation_id.Value
// No ID found
return undefined
}
Объект события AWS Lambda, в случае интеграции SNS, содержит набор записей, который содержит атрибут сообщения, который мы устанавливаем в библиотеке SNS немного ранее.
Теперь, когда все кусочки кода подходят вместе, мы можем развернуть это и выполнить API, чтобы увидеть, что происходит в нашем приложении без сервеса.
Пример
Если вы развернули решение, как указано в моем репо Отказ Импортируйте файл operapi YML в почтальон, файл находится в:
./services/api/example.yml
Обязательно замените параметр URL-адреса серверов с помощью API_URL Террафом выходной параметр, прежде чем у вас будет почтальон генерировать Тестовый люкс Отказ Таким образом, URL все правильно, а не указывает на http://example.com/
После создания, перейдите к Коллекции Тестовый случай вы генерировали, то «Пользователь»> «Пользователь» API. На вкладке «Заголовки» убедитесь, что измените заголовок X-Correlation-ID на все, что вам нравится. Нажмите кнопку «Отправить» и следите.
CloudWatch Logs Insights
В консоли AWS перейдите к CloudWatch, а затем понимание.
Чтобы найти сообщения, генерируемые функциями лямбда, мы можем сделать совпадение на корреляционном ID:
fields @message | parse @message '"correlation_id":"*"' as x_correlation_id | filter x_correlation_id == "12345"
Обратите внимание, что вы должны проводить «|» оба действия; Разбор и фильтр, чтобы запрос понять, как это обработать. Мы можем применить этот запрос через несколько групп журнала, таким образом мы можем найти все сообщения, связанные с этим конкретным выполнением.
В этом случае мы можем видеть, что два лямбда были выполнены; Первый в результате нашего вызова сообщения SNS SNS, вторая лямбда называлась через исходный AWI API API API:
Со всем этим вы должны быть в состоянии;
- Создайте/расширить структуру ведения журнала, которая работает через AWS безсердной инфраструктурой, а также код выполнения.
- Поиск ваших групп журналов эффективно с GloudWatch Logs Insights.
На следующей неделе я охвачу о том, как проводить отслеживание через ваш безсетевой ландшафт с рентгендом AWS, который я не добился до этой недели. Так что оставайся настроен на это.
Спасибо за чтение и до следующей недели!
Регистрация лучших практик
- https://logz.io/blog/logging-best-practices/
- https://www.loggly.com/blog/30-best-practices-logging-scale/
Библиотеки журналов узлов и как-к:
- https://blog.risingstack.com/node-js-logging-tutorial/
- https://www.loggly.com/blog/node-js-libraries-make-sophisticated-logging-simpler/
- https://github.com/winstonjs/winston
- https://github.com/lazywithclass/winston-cloudwatch
- https://thisdavej.com/using-winston-a-versatile-logging-library-for-node-js/
Главные журналы CloudWatch и мониторинг:
- https://www.metricly.com/best-practices-aws-lambda-monitoring/
- https://www.giladpeleg.com/blog/aws-lambda-cloudwatch-logs-insights/
- https://www.cloudforecast.io/blog/aws-cloudwatch-fine-tune-lambda-functions/
Openapi (7 части серии)
Оригинал: «https://dev.to/rolfstreefkerk/how-to-do-logging-on-aws-serverless-3pi3»