Пользовательские метрики журнала Cloudwatch не создаются с помощью boto3

Я пытаюсь написать AWS Lambda, который будет перебирать все группы журналов Cloudwatch, создавая фильтр показателей для поискового запроса в каждой группе журналов.

К сожалению, я обнаружил, что, хотя все мои вызовы put_metric_filter получают ответы HTTP 200, большинство вызовов не приводят к созданию ничего (4/15 вызовов, приводящих к созданию фильтра).

У меня есть AWS Lambda с этим файлом обработчика 'handler.py':

from __future__ import print_function
from basicExample import ManageMetricsAndAlarms

import json, logging

log = logging.getLogger()
log.setLevel(logging.INFO)

def handler(event, context):
  log.info("Received event {}".format(json.dumps(event)))
  mc = ManageMetricsAndAlarms(event, context)
  response = mc.main()
  return json.dumps(response)

Это вызывает класс ManageMetricsAndAlarms из basicExample.py, который отображает массив имен групп журналов, создавая метрику для каждой, которая фильтрует термин ERROR:

from __future__ import print_function

import boto3, os, sys, json, botocore, logging

log = logging.getLogger()
log.setLevel(logging.INFO)

class ManageMetricsAndAlarms:

  # -------------------------------------------------
  def __init__(self,event,context):
    self.event   = event

  # -------------------------------------------------
  def main(self):
    cloudwatch = boto3.resource('cloudwatch')
    metricsNamespace = 'ExampleMetrics'
    errorFilter = '{ $.levelname = "ERROR" }'

    # Supposing that I have log groups for 10 imaginatively named lambdas
    logGroupNames = [
      '/aws/lambda/Lambda-1', '/aws/lambda/Lambda-2', 
      '/aws/lambda/Lambda-3', '/aws/lambda/Lambda-4',
      '/aws/lambda/Lambda-5', '/aws/lambda/Lambda-6',
      '/aws/lambda/Lambda-7', '/aws/lambda/Lambda-8',
      '/aws/lambda/Lambda-9', '/aws/lambda/Lambda-10'
    ]

    # map over the log groups adding a metric filter for 'ERROR' to each
    responses = map(lambda lg: self.createErrorFilter(metricsNamespace, errorFilter, lg), logGroupNames)
    return responses

  # -------------------------------------------------

  def createErrorFilter(self, metricsNamespace, filterPattern, logGroup):
    metricName = logGroup + '_ErrorCount'
    logs_client = boto3.client('logs')

    log.info('Put metric filter ' + metricName + ' with filter $.levelname-ERROR on logGroup: ' + logGroup)
    errorFilter = logs_client.put_metric_filter(
        logGroupName = logGroup,
        filterName ='ERROR-filter',
        filterPattern = filterPattern,
        metricTransformations = [
            {
                'metricNamespace': metricsNamespace,
                'metricValue': '1',
                'metricName': metricName,
            }
        ]
    )
    log.info('errorFilter response: ' + json.dumps(errorFilter))

    return errorFilter

  # -------------------------------------------------

Я новичок в python, поэтому думаю, что пропустил что-то базовое, но любая помощь будет очень признательна!


person jamesw    schedule 01.06.2016    source источник
comment
Вы нашли решение? У меня точно такая же проблема   -  person drpexe    schedule 14.10.2016
comment
Не уверен, что ответ применим к вашему случаю, но я обнаружил, что метка времени в журналах CloudWatch указывается в микросекундах, а не в секундах. ТАК умножение его на 1000 сработало.   -  person drpexe    schedule 14.10.2016


Ответы (1)


Несколько вещей, которые следует учитывать:

  1. Зачем вам использовать лямбду? собираетесь ли вы ставить один и тот же фильтр каждую минуту / час на одни и те же лямбды? Как правило, сценарий следует выполнять только один раз (или сразу после развертывания новых лямбда-выражений.

  2. map - ленивый оценщик, поэтому вам понадобится что-то вроде
    list(map(function x: print(x), iterable)), если вы хотите выполнить функцию

Вот пример

import boto3


def createErrorFilter(metricsNamespace, filterPattern, logGroup):


    metricName = logGroup + '_example'
    logs_client = boto3.client('logs')

    errorFilter = logs_client.put_metric_filter(
    logGroupName = logGroup,
    filterName ='ERROR-filter',
    filterPattern = filterPattern,
    metricTransformations = [
        {
            'metricNamespace': metricsNamespace,
            'metricValue': '1',
            'metricName': metricName,
        }
    ]
    )
    print('ok')
    return 

cloudwatch = boto3.resource('cloudwatch')
metricsNamespace = 'ExampleMetrics-2'
errorFilter = 'ERROR'


logGroupNames = [
  '/aws/lambda/lambda1', '/aws/lambda/lambda2'
]

# map over the log groups adding a metric filter for 'ERROR' to each
responses = list(map(lambda lg: createErrorFilter(metricsNamespace, errorFilter, lg), logGroupNames))

person DaveR    schedule 14.01.2020