Filtrowanie zdarzeń wyzwalających Lambdę

Filtrowanie zdarzeń wyzwalających Lambdę

Wczoraj AWS umożliwił filtrowanie zdarzeń pochodzących z usług SQS, DynamoDB oraz Kinesis, które wyzwalają wykonanie funkcji Lambda. Szkoda, że nie jakieś dwa tygodnie temu. Przydałoby się w jednym rozwiązaniu wdrożonym u klienta, gdzie filtrowanie zdarzeń wyzwalających Lambdę, a właściwie filtrowanie samych wiadomości, które były procesowane zaimplementowaliśmy wewnątrz funkcji.

To bardzo fajna możliwość. Pozwoli, w niektórych przypadkach dość znacząco, zmniejszyć koszty. Ponad to uprości implementację samych funkcji. Będzie w nich mniej warunków.

Przetestowałem to sobie, zobaczmy więc jak to wygląda.

Filtrowanie zdarzeń wyzwalających Lambdę

Na początek, za pomocą AWS SAM utworzyłem prosty stack składający się z funkcji Lambda, która będzie uruchamiana za pomocą eventów (wiadomości) z kolejki SQS.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  events-filtering

Globals:
  Function:
    Timeout: 5

Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: filtering/
      Handler: app.lambda_handler
      Runtime: python3.8
      Policies:
      - SQSPollerPolicy:
          QueueName:
            !GetAtt SqsQueue.QueueName
      Events:
        MySQSEvent:
          Type: SQS
          Properties:
            Queue: !GetAtt SqsQueue.Arn
            BatchSize: 1

  SqsQueue:
    Type: AWS::SQS::Queue

Outputs:
  Queue:
    Description: Queue URL
    Value: !Ref SqsQueue
  Lambda:
    Description: Lambda function name
    Value: !Ref Function

Sama funkcja nie robi nic, poza zapisaniem eventu do logu.

import json

def lambda_handler(event, context):
    print(json.dumps(event))

Po wdrożeniu na koncie w AWS sam deploy --guided dostałem adres URL do kolejki oraz nazwę samej funkcji. Przyda się to za chwilę.

Sprawdziłem w konsoli, moja kolejka była ustawiona jako trigger do funkcji.

Przygotowałem sobie dwa pliki z wiadomościami: sqs_event_ok.json oraz sqs_event_alarm.json. Ich zawartość była bardzo podobna, różniła się tylko wartością pola status.

{
    "text": "Message 1",
    "status": "OK"
}
{
    "text": "Message 1",
    "status": "Alarm"
}

Sprawdziłem czy wszystko działa jeszcze bez filtrowania wysyłając obie wiadomości do kolejki za pomocą poleceń aws sqs send-message --queue-url <QUEUE-URL> --message-body file://sqs_event_ok.json --region us-east-1 oraz aws sqs send-message --queue-url <QUEUE-URL> --message-body file://sqs_event_alarm.json --region us-east-1.


A następnie sprawdziłem jak wygląda log funkcji Lambda sam logs -n <NAZWA_FUNKCJI_LAMBDA>


Jak widać, obie wiadomości poprawnie uruchomiły funkcję.

Filtr

Nasz filtr będzie wybierał z kolejki tylko wiadomości, które mają ustawione pole status na wartość Alarm. Dodajemy więc do definicji eventu wyzwalającego Lambdę kilka linijek

Events:
  MySQSEvent:
    Type: SQS
    Properties:
      Queue: !GetAtt SqsQueue.Arn
      BatchSize: 1
      FilterCriteria: 
        Filters:
        - Pattern: "{\"body\":{\"status\": [\"Alarm\"]}}"

i robimy deployment do chmury sam deploy Więcej o składni samego filtrowania można przeczytać w dokumentacji.

Spróbujmy teraz wysłać wiadomość z wartością OK aws sqs send-message --queue-url <QUEUE-URL> --message-body file://sqs_event_ok.json --region us-east-1 i sprawdźmy szybko logi funkcji sam logs -n <NAZWA_FUNKCJI> -s '2min ago' --region us-east-1. W moim przypadku, nic w tych logach się nie pojawiło, czyli wiadomość nie wyzwoliła funkcji. O to nam chodziło.

Sprawdźmy więc jak zachowa się nasze rozwiązanie w przypadku wiadomości ustawionej jako alarm. Wysyłamy wiadomość aws sqs send-message --queue-url <QUEUE-URL> --message-body file://sqs_event_alarm.json --region us-east-1 i sprawdzamy ponownie logi sam logs -n <NAZWA_FUNKCJI> -s '2min ago' --region us-east-1


Tym razem, jak widać, wiadomość wyzwoliła funkcję.

Podobne filtry można ustawić także podczas definiowania triggera w konsoli AWS. Będzie on miał jednak trochę zamienioną składnię. Jako filtr wystarczy wpisać:


Do każdego źrodła możemy dodać do 5 filtrów. Wtedy zgodność z którymkolwiek z nich spowoduje wyzwolenie funkcji.

Comments are closed.