Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to sleep between max quota requests #76

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/cloudwatch-logs-auto-subscribe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,7 @@ For more details, read this [post](https://theburningmonk.com/2019/05/how-to-inc
`FilterPattern`: (Optional) if specified, will override the filter pattern used to create the subscription.

`UnsubscribeOnDelete`: (Optional) whether to remove the subscription filters that were added by this app. Defaults to "false", allowed values are "true" or "false".

`SleepBetweenMaxQuotaRequests`: (optional) Amount of time in milliseconds to sleep after making {AwsMaxRequestsPerSecQuota} consecutive requests. It might be useful if an AWS account has a large amount of LogGroups or if experiencing Rate Exceeded throttling frequently. Suggested to use a value equal or bellow 1000, as quotas are per second. Defaults to 0.

`AwsMaxRequestsPerSecQuota`: (optional) AWS quota for the max number of requests per second on DescribeLogGroups. This parameter is only used when SleepBetweenMaxQuotaRequests is greater than 0. More info: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html. Defaults to 5.
15 changes: 13 additions & 2 deletions packages/cloudwatch-logs-auto-subscribe/functions/subscribe.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@ const cloudWatchLogs = require("./lib/cloudwatch-logs");
const log = require("@dazn/lambda-powertools-logger");

const { FILTER_NAME, DESTINATION_ARN } = process.env;
const SLEEP_BETWEEN_MAX_QUOTA_REQUESTS = parseInt(process.env.SLEEP_BETWEEN_MAX_QUOTA_REQUESTS, 10);
const AWS_MAX_REQUESTS_PER_SEC_QUOTA = parseInt(process.env.AWS_MAX_REQUESTS_PER_SEC_QUOTA, 10);

function sleep(milliseconds) {
return new Promise(r => setTimeout(r, milliseconds));
}

module.exports.existingLogGroups = async () => {
const logGroupNames = await cloudWatchLogs.getLogGroups();
for (const logGroupName of logGroupNames) {
for (let log_group_index = 0; log_group_index < logGroupNames.length; log_group_index++) {
const logGroupName = logGroupNames[log_group_index];
try {
if (await filter(logGroupName)) {
if (await filter(logGroupName)) {
await subscribe(logGroupName);
}
} catch(error) {
log.warn("cannot process existing log group, skipped...", { logGroupName }, error);
}
if (SLEEP_BETWEEN_MAX_QUOTA_REQUESTS && ((log_group_index + 1) % AWS_MAX_REQUESTS_PER_SEC_QUOTA == 0)) {
await sleep(SLEEP_BETWEEN_MAX_QUOTA_REQUESTS);
}
}
};

Expand Down Expand Up @@ -154,3 +164,4 @@ const unsubscribe = async (logGroupName) => {
log.error("failed to unsubscribe log group", { logGroupName }, err);
}
};

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ console.log = jest.fn();
beforeEach(() => {
process.env.RETRY_MIN_TIMEOUT = "100";
process.env.RETRY_MAX_TIMEOUT = "100";
process.env.SLEEP_BETWEEN_MAX_QUOTA_REQUESTS = "0";
process.env.AWS_MAX_REQUESTS_PER_SEC_QUOTA = "5";
process.env.FILTER_NAME = "ship-logs";
process.env.TAGS_MODE = "OR";
process.env.EXCLUDE_TAGS_MODE = "OR";
Expand Down
16 changes: 16 additions & 0 deletions packages/cloudwatch-logs-auto-subscribe/template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Globals:
FILTER_PATTERN: !Ref FilterPattern
ROLE_ARN: !GetAtt CloudWatchToKinesisRole.Arn
LOG_LEVEL: INFO
SLEEP_BETWEEN_MAX_QUOTA_REQUESTS: !Ref SleepBetweenMaxQuotaRequests
AWS_MAX_REQUESTS_PER_SEC_QUOTA: !Ref AwsMaxRequestsPerSecQuota

Conditions:
Unsubscribe: !Equals [!Ref UnsubscribeOnDelete, 'true']
Expand Down Expand Up @@ -271,3 +273,17 @@ Parameters:
Default: 6
Description: >
(optional) whether to increase the default lambda timeout".
SleepBetweenMaxQuotaRequests:
Type: Number
Default: 0
Description: >
(optional) Amount of time to sleep after making {AwsMaxRequestsPerSecQuota} consecutive requests.
It might be useful if an AWS account has a large amount of LogGroups or if experiencing Rate Exceeded throttling
frequently".
AwsMaxRequestsPerSecQuota:
Type: Number
Default: 5
Description: >
(optional) AWS quota for the max number of requests per second on DescribeLogGroups.
This parameter is only used when SleepBetweenMaxQuotaRequests is greater than 0.
More info: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html. Defaults to 5".