From 66e8b6b2ad7c02fa03ae094e9355b4f810d2512b Mon Sep 17 00:00:00 2001 From: Gordon Pham-Nguyen <4203037+gordonpn@users.noreply.github.com> Date: Thu, 6 Jun 2024 19:54:54 -0400 Subject: [PATCH 1/5] Add awsfirelens log driver to example documentation (#114) --- examples/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/README.md b/examples/README.md index 493bf86..4527755 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,7 +8,9 @@ With Docker images, using the `awslogs` log driver will send your container logs ## ECS and Fargate -With ECS and Fargate, you can use the `awslogs` log driver to have your logs sent to CloudWatch Logs on your behalf. After configuring your task to use the `awslogs` log driver, you may write your EMF logs to STDOUT and they will be processed. +With ECS and Fargate, you can use the `awsfirelens` (recommended) or `awslogs` log driver to have your logs sent to CloudWatch Logs on your behalf. After configuring the options for your preferred log driver, you may write your EMF logs to STDOUT and they will be processed. + +[`awsfirelens` documentation](https://github.com/aws/amazon-cloudwatch-logs-for-fluent-bit) [ECS documentation on `awslogs` log driver](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html) From 1836dd89b626e622327c1307a17b87170f4e307b Mon Sep 17 00:00:00 2001 From: Alin Radu <5991570+acradu@users.noreply.github.com> Date: Wed, 2 Oct 2024 10:51:29 -0700 Subject: [PATCH 2/5] Fix @metric_scope for generator and async generator functions (#113) Co-authored-by: Alin RADU --- aws_embedded_metrics/metric_scope/__init__.py | 55 +++++++++++++++---- tests/metric_scope/test_metric_scope.py | 37 +++++++++++++ 2 files changed, 82 insertions(+), 10 deletions(-) diff --git a/aws_embedded_metrics/metric_scope/__init__.py b/aws_embedded_metrics/metric_scope/__init__.py index 47044bc..b185f38 100644 --- a/aws_embedded_metrics/metric_scope/__init__.py +++ b/aws_embedded_metrics/metric_scope/__init__.py @@ -18,35 +18,70 @@ def metric_scope(fn): # type: ignore + if inspect.isasyncgenfunction(fn): + @wraps(fn) + async def async_gen_wrapper(*args, **kwargs): # type: ignore + logger = create_metrics_logger() + if "metrics" in inspect.signature(fn).parameters: + kwargs["metrics"] = logger + + try: + fn_gen = fn(*args, **kwargs) + while True: + result = await fn_gen.__anext__() + await logger.flush() + yield result + except Exception as ex: + await logger.flush() + if not isinstance(ex, StopIteration): + raise + + return async_gen_wrapper + + elif inspect.isgeneratorfunction(fn): + @wraps(fn) + def gen_wrapper(*args, **kwargs): # type: ignore + logger = create_metrics_logger() + if "metrics" in inspect.signature(fn).parameters: + kwargs["metrics"] = logger + + try: + fn_gen = fn(*args, **kwargs) + while True: + result = next(fn_gen) + asyncio.run(logger.flush()) + yield result + except Exception as ex: + asyncio.run(logger.flush()) + if not isinstance(ex, StopIteration): + raise - if asyncio.iscoroutinefunction(fn): + return gen_wrapper + elif asyncio.iscoroutinefunction(fn): @wraps(fn) - async def wrapper(*args, **kwargs): # type: ignore + async def async_wrapper(*args, **kwargs): # type: ignore logger = create_metrics_logger() if "metrics" in inspect.signature(fn).parameters: kwargs["metrics"] = logger + try: return await fn(*args, **kwargs) - except Exception as e: - raise e finally: await logger.flush() - return wrapper - else: + return async_wrapper + else: @wraps(fn) def wrapper(*args, **kwargs): # type: ignore logger = create_metrics_logger() if "metrics" in inspect.signature(fn).parameters: kwargs["metrics"] = logger + try: return fn(*args, **kwargs) - except Exception as e: - raise e finally: - loop = asyncio.get_event_loop() - loop.run_until_complete(logger.flush()) + asyncio.run(logger.flush()) return wrapper diff --git a/tests/metric_scope/test_metric_scope.py b/tests/metric_scope/test_metric_scope.py index 20bf131..9ebd1f1 100644 --- a/tests/metric_scope/test_metric_scope.py +++ b/tests/metric_scope/test_metric_scope.py @@ -168,6 +168,43 @@ def my_handler(metrics): actual_timestamp_second = int(round(logger.context.meta["Timestamp"] / 1000)) assert expected_timestamp_second == actual_timestamp_second + +def test_sync_scope_iterates_generator(mock_logger): + expected_results = [1, 2] + + @metric_scope + def my_handler(): + yield from expected_results + raise Exception("test exception") + + actual_results = [] + with pytest.raises(Exception, match="test exception"): + for result in my_handler(): + actual_results.append(result) + + assert actual_results == expected_results + assert InvocationTracker.invocations == 3 + + +@pytest.mark.asyncio +async def test_async_scope_iterates_async_generator(mock_logger): + expected_results = [1, 2] + + @metric_scope + async def my_handler(): + for item in expected_results: + yield item + await asyncio.sleep(1) + raise Exception("test exception") + + actual_results = [] + with pytest.raises(Exception, match="test exception"): + async for result in my_handler(): + actual_results.append(result) + + assert actual_results == expected_results + assert InvocationTracker.invocations == 3 + # Test helpers From 7bbcd3d137502a7f7acf4c36cd82dd81dbfa8188 Mon Sep 17 00:00:00 2001 From: seoberha Date: Wed, 5 Feb 2025 18:00:55 -0800 Subject: [PATCH 3/5] Bump version to 3.3.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 27c3417..7e8cc13 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name="aws-embedded-metrics", - version="3.2.0", + version="3.3.0", author="Amazon Web Services", author_email="jarnance@amazon.com", description="AWS Embedded Metrics Package", From a6043157977bc7b6bd964d38255bba76d107b8f9 Mon Sep 17 00:00:00 2001 From: Boxuan Hu Date: Fri, 7 Feb 2025 02:07:54 +0000 Subject: [PATCH 4/5] Replace User creds with Role creds for CWL agent --- bin/run-integ-tests.sh | 21 +++++++++++++++++++++ bin/start-agent.sh | 1 + tox.ini | 1 + 3 files changed, 23 insertions(+) diff --git a/bin/run-integ-tests.sh b/bin/run-integ-tests.sh index f8d5d98..51fb3de 100755 --- a/bin/run-integ-tests.sh +++ b/bin/run-integ-tests.sh @@ -18,6 +18,27 @@ status_code=0 # Configure and start the agent ################################### +# Check if IAM user credentials exist +if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then + echo "No IAM user credentials found, assuming we are running on CodeBuild pipeline, falling back to IAM role..." + + # Store the AWS STS assume-role output and extract credentials + CREDS=$(aws sts assume-role \ + --role-arn $Code_Build_Execution_Role_ARN \ + --role-session-name "session-$(uuidgen)" \ + --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' \ + --output text \ + --duration-seconds 3600) + + # Parse the output into separate variables + read AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN <<< $CREDS + + # Export the variables + export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN +else + echo "Using provided IAM user credentials..." +fi + $rootdir/bin/start-agent.sh ################################### diff --git a/bin/start-agent.sh b/bin/start-agent.sh index 0fb09a8..e4b0c7d 100755 --- a/bin/start-agent.sh +++ b/bin/start-agent.sh @@ -22,6 +22,7 @@ cd $rootdir/tests/integ/agent echo "[AmazonCloudWatchAgent] aws_access_key_id = $AWS_ACCESS_KEY_ID aws_secret_access_key = $AWS_SECRET_ACCESS_KEY +aws_session_token = $AWS_SESSION_TOKEN " > ./.aws/credentials echo "[profile AmazonCloudWatchAgent] diff --git a/tox.ini b/tox.ini index fe51c57..a8a60fc 100644 --- a/tox.ini +++ b/tox.ini @@ -23,6 +23,7 @@ passenv = AWS_REGION AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY + AWS_SESSION_TOKEN [testenv:flake8] basepython = python3.7 From e03ffdf32cd48f46bc1e53f855a191ca533a886a Mon Sep 17 00:00:00 2001 From: ZahidMirza95 <57571948+ZahidMirza95@users.noreply.github.com> Date: Wed, 26 Feb 2025 10:55:51 -0800 Subject: [PATCH 5/5] changed cw-agent dockerhub image to use ecr --- tests/canary/agent/container-definitions.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/canary/agent/container-definitions.json b/tests/canary/agent/container-definitions.json index 3b21fe9..facf927 100644 --- a/tests/canary/agent/container-definitions.json +++ b/tests/canary/agent/container-definitions.json @@ -30,7 +30,7 @@ }, { "name": "cloudwatch-agent-python", - "image": "amazon/cloudwatch-agent:latest", + "image": "public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest", "logConfiguration": { "logDriver": "awslogs", "options": { @@ -47,4 +47,4 @@ } ] } -] \ No newline at end of file +]