示例#1
0
def test_tracer_reuse():
    # GIVEN tracer A, B were initialized
    # WHEN tracer B explicitly reuses A config
    # THEN tracer B attributes should be equal to tracer A
    service_name = "booking"
    tracer_a = Tracer(disabled=True, service=service_name)
    tracer_b = Tracer()

    assert id(tracer_a) != id(tracer_b)
    assert tracer_a.__dict__.items() == tracer_b.__dict__.items()
def test_tracer_custom_metadata(mocker, dummy_response, provider_stub):
    put_metadata_mock = mocker.MagicMock()
    annotation_key = "Booking response"
    annotation_value = {"bookingStatus": "CONFIRMED"}

    provider = provider_stub(put_metadata_mock=put_metadata_mock)
    tracer = Tracer(provider=provider, service="booking")
    tracer.put_metadata(annotation_key, annotation_value)

    assert put_metadata_mock.call_count == 1
    assert put_metadata_mock.call_args_list[0] == mocker.call(
        key=annotation_key, value=annotation_value, namespace="booking")
def test_tracer_custom_annotation(mocker, dummy_response, provider_stub):
    put_annotation_mock = mocker.MagicMock()
    annotation_key = "BookingId"
    annotation_value = "123456"

    provider = provider_stub(put_annotation_mock=put_annotation_mock)
    tracer = Tracer(provider=provider, service="booking")

    tracer.put_annotation(annotation_key, annotation_value)

    assert put_annotation_mock.call_count == 1
    assert put_annotation_mock.call_args == mocker.call(key=annotation_key,
                                                        value=annotation_value)
def test_tracer_patch(xray_patch_all_mock, xray_patch_mock, mocker):
    # GIVEN tracer is instantiated
    # WHEN default X-Ray provider client is mocked
    # THEN tracer should run just fine

    Tracer()
    assert xray_patch_all_mock.call_count == 1

    modules = ["boto3"]
    Tracer(service="booking", patch_modules=modules)

    assert xray_patch_mock.call_count == 1
    assert xray_patch_mock.call_args == mocker.call(modules)
def test_package_logger_format(stdout, capsys):
    set_package_logger(stream=stdout,
                       formatter=JsonFormatter(formatter="test"))
    Tracer(disabled=True)
    output = json.loads(stdout.getvalue().split("\n")[0])

    assert "test" in output["formatter"]
async def test_tracer_method_nested_async(mocker, dummy_response,
                                          provider_stub, in_subsegment_mock):
    provider = provider_stub(
        in_subsegment_async=in_subsegment_mock.in_subsegment)
    tracer = Tracer(provider=provider, service="booking")

    @tracer.capture_method
    async def greeting_2(name, message):
        return dummy_response

    @tracer.capture_method
    async def greeting(name, message):
        await greeting_2(name, message)
        return dummy_response

    await greeting(name="Foo", message="Bar")

    (
        in_subsegment_greeting_call_args,
        in_subsegment_greeting2_call_args,
    ) = in_subsegment_mock.in_subsegment.call_args_list
    put_metadata_greeting2_call_args, put_metadata_greeting_call_args = in_subsegment_mock.put_metadata.call_args_list

    assert in_subsegment_mock.in_subsegment.call_count == 2
    assert in_subsegment_greeting_call_args == mocker.call(name="## greeting")
    assert in_subsegment_greeting2_call_args == mocker.call(
        name="## greeting_2")

    assert in_subsegment_mock.put_metadata.call_count == 2
    assert put_metadata_greeting2_call_args == mocker.call(
        key="greeting_2 response", value=dummy_response, namespace="booking")
    assert put_metadata_greeting_call_args == mocker.call(
        key="greeting response", value=dummy_response, namespace="booking")
def test_tracer_lambda_handler(mocker, dummy_response, xray_stub):
    put_metadata_mock = mocker.MagicMock()
    begin_subsegment_mock = mocker.MagicMock()
    end_subsegment_mock = mocker.MagicMock()

    xray_provider = xray_stub(
        put_metadata_mock=put_metadata_mock,
        begin_subsegment_mock=begin_subsegment_mock,
        end_subsegment_mock=end_subsegment_mock,
    )
    tracer = Tracer(provider=xray_provider, service="booking")

    @tracer.capture_lambda_handler
    def handler(event, context):
        return dummy_response

    handler({}, mocker.MagicMock())

    assert begin_subsegment_mock.call_count == 1
    assert begin_subsegment_mock.call_args == mocker.call(name="## handler")
    assert end_subsegment_mock.call_count == 1
    assert put_metadata_mock.call_args == mocker.call(
        key="lambda handler response",
        value=dummy_response,
        namespace="booking")
def test_package_logger(capsys):

    set_package_logger()
    Tracer(disabled=True)
    output = capsys.readouterr()

    assert "Tracing has been disabled" in output.out
示例#9
0
def test_tracer_env_vars(monkeypatch):
    # GIVEN tracer disabled, is run without parameters
    # WHEN service is explicitly defined
    # THEN tracer should have use that service name
    service_name = "booking"
    monkeypatch.setenv("POWERTOOLS_SERVICE_NAME", service_name)
    tracer_env_var = Tracer(disabled=True)

    assert tracer_env_var.service == service_name

    tracer_explicit = Tracer(disabled=True, service=service_name)
    assert tracer_explicit.service == service_name

    monkeypatch.setenv("POWERTOOLS_TRACE_DISABLED", "true")
    tracer = Tracer()

    assert bool(tracer.disabled) is True
示例#10
0
def test_capture_lambda_handler(dummy_response):
    # GIVEN tracer is disabled, and decorator is used
    # WHEN a lambda handler is run
    # THEN tracer should not raise an Exception
    tracer = Tracer(disabled=True)

    @tracer.capture_lambda_handler
    def handler(event, context):
        return dummy_response

    handler({}, {})
示例#11
0
def test_tracer_lambda_emulator(monkeypatch, mocker, dummy_response):
    # GIVEN tracer is run locally
    # WHEN a lambda function is run through SAM CLI
    # THEN tracer should not raise an Exception
    monkeypatch.setenv("AWS_SAM_LOCAL", "true")
    tracer = Tracer()

    @tracer.capture_lambda_handler
    def handler(event, context):
        return dummy_response

    handler({}, mocker.MagicMock())
def test_tracer_method_empty_response_metadata(mocker, provider_stub):
    put_metadata_mock = mocker.MagicMock()
    provider = provider_stub(put_metadata_mock=put_metadata_mock)
    tracer = Tracer(provider=provider)

    @tracer.capture_method
    def greeting(name, message):
        return

    greeting(name="Foo", message="Bar")

    assert put_metadata_mock.call_count == 0
示例#13
0
def test_capture_method(dummy_response):
    # GIVEN tracer is disabled, and method decorator is used
    # WHEN a function is run
    # THEN tracer should not raise an Exception

    tracer = Tracer(disabled=True)

    @tracer.capture_method
    def greeting(name, message):
        return dummy_response

    greeting(name="Foo", message="Bar")
def test_tracer_lambda_handler_empty_response_metadata(mocker, provider_stub):
    put_metadata_mock = mocker.MagicMock()
    provider = provider_stub(put_metadata_mock=put_metadata_mock)
    tracer = Tracer(provider=provider)

    @tracer.capture_lambda_handler
    def handler(event, context):
        return

    handler({}, mocker.MagicMock())

    assert put_metadata_mock.call_count == 0
示例#15
0
def test_tracer_metadata_disabled(dummy_response):
    # GIVEN tracer is disabled, and annotations/metadata are used
    # WHEN a lambda handler is run
    # THEN tracer should not raise an Exception and simply ignore
    tracer = Tracer(disabled=True)

    @tracer.capture_lambda_handler
    def handler(event, context):
        tracer.put_annotation("PaymentStatus", "SUCCESS")
        tracer.put_metadata("PaymentMetadata", "Metadata")
        return dummy_response

    handler({}, {})
async def test_tracer_method_exception_metadata_async(mocker, provider_stub,
                                                      in_subsegment_mock):
    provider = provider_stub(
        in_subsegment_async=in_subsegment_mock.in_subsegment)
    tracer = Tracer(provider=provider, service="booking")

    @tracer.capture_method
    async def greeting(name, message):
        raise ValueError("test")

    with pytest.raises(ValueError):
        await greeting(name="Foo", message="Bar")

    put_metadata_mock_args = in_subsegment_mock.put_metadata.call_args[1]
    assert put_metadata_mock_args["key"] == "greeting error"
    assert put_metadata_mock_args["namespace"] == "booking"
async def test_tracer_method_nested_async_disabled(dummy_response):

    tracer = Tracer(service="booking", disabled=True)

    @tracer.capture_method
    async def greeting_2(name, message):
        return dummy_response

    @tracer.capture_method
    async def greeting(name, message):
        await greeting_2(name, message)
        return dummy_response

    ret = await greeting(name="Foo", message="Bar")

    assert ret == dummy_response
def test_tracer_lambda_handler_exception_metadata(mocker, provider_stub,
                                                  in_subsegment_mock):

    provider = provider_stub(in_subsegment=in_subsegment_mock.in_subsegment)
    tracer = Tracer(provider=provider, service="booking")

    @tracer.capture_lambda_handler
    def handler(event, context):
        raise ValueError("test")

    with pytest.raises(ValueError):
        handler({}, mocker.MagicMock())

    put_metadata_mock_args = in_subsegment_mock.put_metadata.call_args[1]
    assert put_metadata_mock_args["key"] == "booking error"
    assert put_metadata_mock_args["namespace"] == "booking"
def test_tracer_custom_annotation(mocker, dummy_response, xray_stub):
    put_annotation_mock = mocker.MagicMock()

    xray_provider = xray_stub(put_annotation_mock=put_annotation_mock)

    tracer = Tracer(provider=xray_provider, service="booking")
    annotation_key = "BookingId"
    annotation_value = "123456"

    @tracer.capture_lambda_handler
    def handler(event, context):
        tracer.put_annotation(annotation_key, annotation_value)
        return dummy_response

    handler({}, mocker.MagicMock())

    assert put_annotation_mock.call_count == 1
    assert put_annotation_mock.call_args == mocker.call(key=annotation_key, value=annotation_value)
def test_tracer_custom_metadata(mocker, dummy_response, xray_stub):
    put_metadata_mock = mocker.MagicMock()

    xray_provider = xray_stub(put_metadata_mock=put_metadata_mock)

    tracer = Tracer(provider=xray_provider, service="booking")
    annotation_key = "Booking response"
    annotation_value = {"bookingStatus": "CONFIRMED"}

    @tracer.capture_lambda_handler
    def handler(event, context):
        tracer.put_metadata(annotation_key, annotation_value)
        return dummy_response

    handler({}, mocker.MagicMock())

    assert put_metadata_mock.call_count == 2
    assert put_metadata_mock.call_args_list[0] == mocker.call(
        key=annotation_key, value=annotation_value, namespace="booking")
def test_tracer_lambda_handler(mocker, dummy_response, provider_stub,
                               in_subsegment_mock):
    provider = provider_stub(in_subsegment=in_subsegment_mock.in_subsegment)
    tracer = Tracer(provider=provider, service="booking")

    @tracer.capture_lambda_handler
    def handler(event, context):
        return dummy_response

    handler({}, mocker.MagicMock())

    assert in_subsegment_mock.in_subsegment.call_count == 1
    assert in_subsegment_mock.in_subsegment.call_args == mocker.call(
        name="## handler")
    assert in_subsegment_mock.put_metadata.call_args == mocker.call(
        key="handler response", value=dummy_response, namespace="booking")
    assert in_subsegment_mock.put_annotation.call_count == 1
    assert in_subsegment_mock.put_annotation.call_args == mocker.call(
        key="ColdStart", value=True)
示例#22
0
def test_tracer_method_nested_sync(mocker):
    # GIVEN tracer is disabled, decorator is used
    # WHEN multiple sync functions are nested
    # THEN tracer should not raise a Runtime Error
    tracer = Tracer(disabled=True)

    @tracer.capture_method
    def func_1():
        return 1

    @tracer.capture_method
    def func_2():
        return 2

    @tracer.capture_method
    def sums_values():
        return func_1() + func_2()

    sums_values()
def test_tracer_method(mocker, dummy_response, xray_stub):
    put_metadata_mock = mocker.MagicMock()
    put_annotation_mock = mocker.MagicMock()
    begin_subsegment_mock = mocker.MagicMock()
    end_subsegment_mock = mocker.MagicMock()

    xray_provider = xray_stub(put_metadata_mock, put_annotation_mock,
                              begin_subsegment_mock, end_subsegment_mock)
    tracer = Tracer(provider=xray_provider, service="booking")

    @tracer.capture_method
    def greeting(name, message):
        return dummy_response

    greeting(name="Foo", message="Bar")

    assert begin_subsegment_mock.call_count == 1
    assert begin_subsegment_mock.call_args == mocker.call(name="## greeting")
    assert end_subsegment_mock.call_count == 1
    assert put_metadata_mock.call_args == mocker.call(key="greeting response",
                                                      value=dummy_response,
                                                      namespace="booking")
示例#24
0
def test_tracer_with_exception(mocker):
    # GIVEN tracer is disabled, decorator is used
    # WHEN a lambda handler or method returns an Exception
    # THEN tracer should reraise the same Exception
    class CustomException(Exception):
        pass

    tracer = Tracer(disabled=True)

    @tracer.capture_lambda_handler
    def handler(event, context):
        raise CustomException("test")

    @tracer.capture_method
    def greeting(name, message):
        raise CustomException("test")

    with pytest.raises(CustomException):
        handler({}, {})

    with pytest.raises(CustomException):
        greeting(name="Foo", message="Bar")
示例#25
0
#  distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
#  OF ANY KIND, either express or implied. See the License for the
#  specific language governing permissions and limitations under the
#  License.

import gettext

from ask_sdk_core.dispatch_components import AbstractRequestInterceptor
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import get_locale
from aws_lambda_powertools.logging import Logger
from aws_lambda_powertools.tracing import Tracer

# Logging/tracing configuration
logger = Logger(service="i18n interceptor")
tracer = Tracer(service="i18n interceptor")


class LocalizationInterceptor(AbstractRequestInterceptor):
    """Request interceptor to handle multiple locales."""

    def process(self, handler_input):
        """Parse locale information and add i18n manager to the request attributes."""

        # type: (HandlerInput) -> None
        logger.debug("In LocalizationInterceptor")
        locale = get_locale(handler_input)
        logger.debug({"Locale": locale})
        i18n = gettext.translation(
            "base", localedir="core/locales/", languages=[locale], fallback=True
        )
示例#26
0
"""

import os
import boto3
import requests
from aws_lambda_powertools.tracing import Tracer  # pylint: disable=import-error
from aws_lambda_powertools.logging.logger import Logger  # pylint: disable=import-error

API_URL = os.environ["API_URL"]
ENVIRONMENT = os.environ["ENVIRONMENT"]
TABLE_NAME = os.environ["TABLE_NAME"]

dynamodb = boto3.resource("dynamodb")  # pylint: disable=invalid-name
table = dynamodb.Table(TABLE_NAME)  # pylint: disable=invalid-name,no-member
logger = Logger()  # pylint: disable=invalid-name
tracer = Tracer()  # pylint: disable=invalid-name


@tracer.capture_method
def get_payment_token(order_id: str) -> str:
    """
    Retrieve the paymentToken from DynamoDB
    """

    response = table.get_item(Key={"orderId": order_id})

    return response["Item"]["paymentToken"]


@tracer.capture_method
def update_payment_amount(payment_token: str, amount: int) -> None:
示例#27
0
from typing import Dict, List, Optional

import hermes.backend.dict
from ask_sdk_core.exceptions import ApiClientException
from ask_sdk_model.services import ApiClient, ApiClientRequest
from aws_lambda_powertools.logging import Logger
from aws_lambda_powertools.tracing import Tracer
from marshmallow import ValidationError

from .cache.bmemcached import Backend as BmemcachedBackend
from .exceptions import GTFSDataError, NetworkDescriptionError, OperationMonitoringError
from .model.line_stops import LineDetails
from .model.passing_times import PassingTime, PointPassingTimes

logger = Logger(service="STIB service")
tracer = Tracer(service="STIB service")

ENVIRONMENT = environ["env"]
MEMCACHED_ENDPOINT = environ["cache_endpoint"]
MEMCACHED_USERNAME = environ["cache_username"]
MEMCACHED_PASSWORD = environ["cache_password"]


@tracer.capture_method
def initialize_cache() -> hermes.Hermes:
    if ENVIRONMENT == "Sandbox":
        logger.info(
            {
                "operation": "Setting Hermes caching backend",
                "environment": ENVIRONMENT.upper(),
                "backend": "Dictionary",
示例#28
0
class Utils:
    def __init__(self):
        self.logger = Logger()
        self.tracer = Tracer()

    def set_trace_id(self, lambda_handler):
        def get_trace_id(raw_trace_id):
            for t in raw_trace_id.split(';'):
                if t.startswith('Root'):
                    return t.split('=')[1]
            return None

        def decorate(event, context):
            if '_X_AMZN_TRACE_ID' in os.environ:
                if get_trace_id(os.environ['_X_AMZN_TRACE_ID']) is not None:
                    os.environ['trace_id'] = get_trace_id(
                        os.environ['_X_AMZN_TRACE_ID'])
            if 'trace_id' not in os.environ:
                START_TIME = time.time()
                HEX = hex(int(START_TIME))[2:]
                os.environ['trace_id'] = "0-{}-{}".format(
                    HEX, str(binascii.hexlify(urandom(12)), 'utf-8'))
            self.logger.structure_logs(append=True,
                                       trace_id=os.environ['trace_id'])
            self.logger.info(os.environ.get('trace_id'))
            response = lambda_handler(event, context)
            return response

        return decorate

    def api_gateway_response(self, lambda_handler):
        def decorate(event, context):
            response = lambda_handler(event, context)
            if isinstance(response, tuple):
                body = response[0]
                status = response[1]
            else:
                body = response
                status = 200

            if isinstance(body, Exception):
                if status == 200:
                    status = 400
                self.logger.exception(body)
                self.tracer.put_annotation("ErrorCode",
                                           body.__class__.__name__)
                self.tracer.put_annotation("ErrorMessage", "{}".format(body))
                res = {
                    "isBase64Encoded":
                    False,
                    "statusCode":
                    status,
                    'headers': {
                        "Access-Control-Allow-Origin": "*",
                        "Content-Type": "application/json"
                    },
                    'body':
                    json.dumps({
                        "Code": body.__class__.__name__,
                        "Message": "{}".format(body),
                        "TraceId": os.environ.get('trace_id')
                    })
                }

            else:
                if body is not None and isinstance(body, str) is False:
                    body = json.dumps(body)

                res = {
                    'isBase64Encoded': False,
                    'statusCode': status,
                    'headers': {
                        "Access-Control-Allow-Origin": "*",
                        "Content-Type": "application/json"
                    }
                }
                if body is not None:
                    res['body'] = body
            return res

        return decorate
示例#29
0
 def __init__(self):
     self.logger = Logger()
     self.tracer = Tracer()
示例#30
0
from typing import List, Optional

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_intent_name
from ask_sdk_model import Response
from aws_lambda_powertools.logging import Logger
from aws_lambda_powertools.tracing import Tracer

from ...data import data
from ...service.model.passing_times import PassingTime

# Logging/tracing configuration
logger = Logger(service="Get arrival time intent handler")
tracer = Tracer(service="Get arrival time intent handler")


class GetArrivalTimesNoPrefsIntentHandler(AbstractRequestHandler):
    """Handler for get arrival time Intent: no available preferences scenario."""
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool

        # Extract persistent attributes and check if they are all present
        attr = handler_input.attributes_manager.persistent_attributes
        attributes_are_present = ("favorite_stop_id" in attr
                                  and "favorite_line_id" in attr)
        return not attributes_are_present and is_intent_name(
            "GetArrivalTimesIntent")(handler_input)

    def handle(self, handler_input):