def test_setup_no_service_name(root_logger, stdout): # GIVEN no service is explicitly defined # WHEN logger is setup # THEN service field should be "service_undefined" logger_setup() logger = logger_setup() logger.info("Hello") log = json.loads(stdout.getvalue()) assert "service_undefined" == log["service"]
def test_inject_lambda_context_log_event_request_env_var( monkeypatch, root_logger, stdout, lambda_context): # GIVEN a lambda function is decorated with logger instructed to log event # via POWERTOOLS_LOGGER_LOG_EVENT env # WHEN logger is setup # THEN logger should log event received from Lambda lambda_event = {"greeting": "hello"} monkeypatch.setenv("POWERTOOLS_LOGGER_LOG_EVENT", "true") logger = logger_setup() @logger_inject_lambda_context() def handler(event, context): logger.info("Hello") handler(lambda_event, lambda_context) # Given that our string buffer has many log statements separated by newline \n # We need to clean it before we can assert on stdout.seek(0) logs = [json.loads(line.strip()) for line in stdout.readlines()] event = {} for log in logs: if "greeting" in log["message"]: event = log["message"] assert event == lambda_event
def test_inject_lambda_context_log_no_request_by_default( monkeypatch, root_logger, stdout, lambda_context): # GIVEN a lambda function is decorated with logger # WHEN logger is setup # THEN logger should not log event received by lambda handler lambda_event = {"greeting": "hello"} logger = logger_setup() @logger_inject_lambda_context() def handler(event, context): logger.info("Hello") handler(lambda_event, lambda_context) # Given that our string buffer has many log statements separated by newline \n # We need to clean it before we can assert on stdout.seek(0) logs = [json.loads(line.strip()) for line in stdout.readlines()] event = {} for log in logs: if "greeting" in log["message"]: event = log["message"] assert event != lambda_event
def test_setup_service_name(root_logger, stdout): # GIVEN service is explicitly defined # WHEN logger is setup # THEN service field should be equals service given service_name = "payment" logger = logger_setup(service=service_name) logger.info("Hello") log = json.loads(stdout.getvalue()) assert service_name == log["service"]
def test_setup_service_env_var(monkeypatch, root_logger, stdout): # GIVEN service is explicitly defined via POWERTOOLS_SERVICE_NAME env # WHEN logger is setup # THEN service field should be equals POWERTOOLS_SERVICE_NAME value service_name = "payment" monkeypatch.setenv("POWERTOOLS_SERVICE_NAME", service_name) logger = logger_setup() logger.info("Hello") log = json.loads(stdout.getvalue()) assert service_name == log["service"]
def test_setup_sampling_rate(monkeypatch, root_logger, stdout): # GIVEN samping rate is explicitly defined via POWERTOOLS_LOGGER_SAMPLE_RATE env # WHEN logger is setup # THEN sampling rate should be equals POWERTOOLS_LOGGER_SAMPLE_RATE value and should sample debug logs sampling_rate = "1" monkeypatch.setenv("POWERTOOLS_LOGGER_SAMPLE_RATE", sampling_rate) monkeypatch.setenv("LOG_LEVEL", "INFO") logger = logger_setup() logger.debug("I am being sampled") log = json.loads(stdout.getvalue()) assert sampling_rate == log["sampling_rate"] assert "DEBUG" == log["level"] assert "I am being sampled" == log["message"]
def test_inject_lambda_context_log_event_request(root_logger, stdout, lambda_context): # GIVEN a lambda function is decorated with logger instructed to log event # WHEN logger is setup # THEN logger should log event received from Lambda lambda_event = {"greeting": "hello"} logger = logger_setup() @logger_inject_lambda_context(log_event=True) def handler(event, context): logger.info("Hello") handler(lambda_event, lambda_context) # Given that our string buffer has many log statements separated by newline \n # We need to clean it before we can assert on stdout.seek(0) logs = [json.loads(line.strip()) for line in stdout.readlines()] logged_event, _ = logs assert "greeting" in logged_event["message"]
def test_inject_lambda_cold_start(root_logger, stdout, lambda_context): # GIVEN a lambda function is decorated with logger, and called twice # WHEN logger is setup # THEN cold_start key should only be true in the first call from aws_lambda_powertools.logging import logger # # As we run tests in parallel global cold_start value can be false # # here we reset to simulate the correct behaviour # # since Lambda will only import our logger lib once per concurrent execution logger.is_cold_start = True logger = logger_setup() def custom_method(): logger.info("Hello from method") @logger_inject_lambda_context def handler(event, context): custom_method() logger.info("Hello") handler({}, lambda_context) handler({}, lambda_context) # Given that our string buffer has many log statements separated by newline \n # We need to clean it before we can assert on stdout.seek(0) logs = [json.loads(line.strip()) for line in stdout.readlines()] first_log, second_log, third_log, fourth_log = logs # First execution assert "true" == first_log["cold_start"] assert "true" == second_log["cold_start"] # Second execution assert "false" == third_log["cold_start"] assert "false" == fourth_log["cold_start"]
def test_inject_lambda_context(root_logger, stdout, lambda_context): # GIVEN a lambda function is decorated with logger # WHEN logger is setup # THEN lambda contextual info should always be in the logs logger_context_keys = ( "function_name", "function_memory_size", "function_arn", "function_request_id", ) logger = logger_setup() @logger_inject_lambda_context def handler(event, context): logger.info("Hello") handler({}, lambda_context) log = json.loads(stdout.getvalue()) for key in logger_context_keys: assert key in log
def test_logger_setup_deprecated(): # Should be removed when GA with pytest.raises(DeprecationWarning): logger_setup()
""" import os from typing import List import boto3 from boto3.dynamodb.types import TypeDeserializer from aws_lambda_powertools.tracing import Tracer from aws_lambda_powertools.logging import logger_setup, logger_inject_lambda_context from ecom.eventbridge import ddb_to_event # pylint: disable=import-error ENVIRONMENT = os.environ["ENVIRONMENT"] EVENT_BUS_NAME = os.environ["EVENT_BUS_NAME"] eventbridge = boto3.client("events") # pylint: disable=invalid-name type_deserializer = TypeDeserializer() # pylint: disable=invalid-name logger = logger_setup() # pylint: disable=invalid-name tracer = Tracer() # pylint: disable=invalid-name @tracer.capture_method def send_events(events: List[dict]): """ Send events to EventBridge """ logger.info("Sending %d events to EventBridge", len(events)) eventbridge.put_events(Entries=events) @logger_inject_lambda_context @tracer.capture_lambda_handler
import json import os import csv import io import hashlib import requests import boto3 from aws_lambda_powertools.logging import logger_setup, logger_inject_lambda_context logger = logger_setup() base_url = "https://raw.githubusercontent.com/keithrozario/Klayers/master/pipeline/config" @logger_inject_lambda_context def push_master(event, context): """ A push to master occurred """ stage = os.environ['STAGE'] bucket_name = os.environ['BUCKET_NAME'] filenames = ['packages.csv'] for config_file in filenames: config_url = f"{base_url}/{stage}/{config_file}" logger.info(f"Requesting latest config from {config_url}") response = requests.get(config_url) # Sanity check on csv file
# pylint: disable=import-error import os import json import re import ipaddress import boto3 from aws_lambda_powertools.logging import logger_setup, logger_inject_lambda_context logger = logger_setup(boto_level='CRITICAL') try: ROUTE_53_ZONE_ID = os.environ['ROUTE_53_ZONE_ID'] ROUTE_53_ZONE_NAME = os.environ['ROUTE_53_ZONE_NAME'] except KeyError as e: raise Exception('Missing required environment variables!') class InvalidRequest(Exception): pass class RequestHandler(object): def __init__(self, event, context): self.event = event self.context = context self.params = self.__get_parameters() self.route53 = boto3.client('route53') def __get_parameters(self):
import os import hmac import hashlib from lambda_cache import ssm import boto3 from aws_lambda_powertools.logging import logger_setup, logger_inject_lambda_context logger = logger_setup(service="github_webhook_authorizer") def check_sig(payload, sig, secret): h1 = hmac.new(bytearray(secret, 'utf-8'), bytearray(payload, 'utf-8'), hashlib.sha1) if hmac.compare_digest(h1.hexdigest(), sig[5:]): logger.info("Verified signature, Proceeding") return True else: logger.error("Invalid Signature, terminating") exit(1) return False @logger_inject_lambda_context @ssm.cache(os.environ['GITHUB_SECRET_PARAM']) def handler(event, context): """ Receives a POST from github, verifies the signature before placing message onto eventhub.
import json import requests from packaging.version import parse from aws_lambda_powertools.logging import logger_setup, logger_inject_lambda_context logger = logger_setup(service='check_Pypi') def get_latest_release(package): """ Args: package: Name of package to be queried returns: version: Version number of latest release that is **not** a pre-release as packaging.version """ req = requests.get(f"https://pypi.python.org/pypi/{package}/json") version = parse('0') license_info = None if req.status_code == requests.codes.ok: j = json.loads(req.text) releases = j.get('releases', []) for release in releases: ver = parse(release) if not ver.is_prerelease: version = max(version, ver) license_info = j.get('info', {}).get('license', None) if license_info is None: license_info = 'No-License-In-PyPI'