From 1fba1f9ac18abd5f55a349782946950be45b4148 Mon Sep 17 00:00:00 2001 From: haihongren Date: Tue, 16 Nov 2021 18:01:34 +1100 Subject: [PATCH 01/33] improvement: Refactor CloudTrail log processing, support batching(compressed payload<1MB) for large file --- requirements.txt | 1 - src/handler.py | 33 ++++++++++++++++++--------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/requirements.txt b/requirements.txt index 245282d..9d033f6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,6 @@ docutils==0.15.2 idna==2.10 jmespath==0.10.0 multidict==4.7.6 -Pympler==0.9 python-dateutil==2.8.1 requests==2.24.0 s3transfer==0.3.3 diff --git a/src/handler.py b/src/handler.py index 4b3a816..f874da2 100644 --- a/src/handler.py +++ b/src/handler.py @@ -11,7 +11,6 @@ import logging from smart_open import open import re -from pympler import asizeof from dateutil import parser @@ -19,7 +18,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.1.1' +LOGGING_LAMBDA_VERSION = '1.1.2' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION @@ -212,22 +211,25 @@ async def _fetch_data_from_s3(bucket, key, context): log_batches = [] batch_request = [] batch_counter = 1 + log_batch_size = 0 start = time.time() - isCloudTrail = bool(re.search(".*CloudTrail.*\.json.gz$", key)) + isCloudTrail = bool(re.search(".*CloudTrail.*\.json.gz$", key)) with open(log_file_url, encoding='utf-8') as log_lines: + if isCloudTrail: + # This is a CloudTrail log - we need to apply special preprocessing + cloudtrail_events=json.loads(log_lines.read())["Records"] + for this_event in cloudtrail_events: + # Convert the eventTime to Posix time and pass it to New Relic as a timestamp attribute + this_event['timestamp']=time.mktime((parser.parse(this_event['eventTime'])).timetuple()) + log_lines = cloudtrail_events + for index, log in enumerate(log_lines): - if isCloudTrail: - # This is a CloudTrail log - we need to apply special preprocessing - cloudtrail_events=json.loads(log)["Records"] - for this_event in cloudtrail_events: - # Convert the eventTime to Posix time and pass it to New Relic as a timestamp attribute - this_event['timestamp']=time.mktime((parser.parse(this_event['eventTime'])).timetuple()) - log_batches.extend(cloudtrail_events) - else: - if index % 500 == 0: - logger.debug(f"index: {index}") - log_batches.append(log) - if asizeof.asizeof(log_batches) > (MAX_BATCH_SIZE * BATCH_SIZE_FACTOR): + log_batch_size += sys.getsizeof(log) + if index % 500 == 0: + logger.debug(f"index: {index}") + logger.debug(f"log_batch_size: {log_batch_size}") + log_batches.append(log) + if log_batch_size > (MAX_BATCH_SIZE * BATCH_SIZE_FACTOR): logger.debug(f"sending batch: {batch_counter}") data = {"context": s3MetaData, "entry": log_batches} batch_request.append(create_log_payload_request(data, session)) @@ -235,6 +237,7 @@ async def _fetch_data_from_s3(bucket, key, context): await asyncio.gather(*batch_request) batch_request = [] log_batches = [] + log_batch_size = 0 batch_counter += 1 data = {"context": s3MetaData, "entry": log_batches} batch_request.append(create_log_payload_request(data, session)) From 2ab02b226f2a570259d845990581c847e1ccfbbf Mon Sep 17 00:00:00 2001 From: haihongren Date: Thu, 18 Nov 2021 21:02:12 +1100 Subject: [PATCH 02/33] improvement: externalized BATCH_SIZE_FACTOR, added S3_CLOUDTRAIL_LOG_PATTERN, S3_IGNORE_PATTERN env variables BATCH_SIZE_FACTOR: affects uncompressed batch size, default: 1.5 S3_CLOUDTRAIL_LOG_PATTERN: regex pattern to match CloudTrail log file, default: .*CloudTrail.*\.json.gz$ S3_IGNORE_PATTERN: regex pattern to match log file to be ignored/skipped, default: $^ --- serverless.yml | 12 +++++++---- src/handler.py | 58 +++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/serverless.yml b/serverless.yml index 3602afe..0e0b056 100644 --- a/serverless.yml +++ b/serverless.yml @@ -26,12 +26,12 @@ provider: iamRoleStatements: - Effect: "Allow" Action: - - "s3:GetObject" + - "s3:GetObject" Resource: "arn:aws:s3:::${env:S3_BUCKET_NAME}/*" plugins: - serverless-python-requirements - + custom: pythonRequirements: dockerizePip: non-linux @@ -39,14 +39,18 @@ custom: functions: NewRelic-s3-log-ingestion: handler: src/handler.lambda_handler - environment: + environment: LICENSE_KEY: ${env:LICENSE_KEY} LOG_TYPE: ${env:LOG_TYPE} DEBUG_ENABLED: ${env:DEBUG_ENABLED} + S3_CLOUDTRAIL_LOG_PATTERN: ${env:S3_CLOUDTRAIL_LOG_PATTERN} + S3_IGNORE_PATTERN: ${env:S3_IGNORE_PATTERN} + BATCH_SIZE_FACTOR: ${env:BATCH_SIZE_FACTOR} + events: - s3: bucket: ${env:S3_BUCKET_NAME} event: s3:ObjectCreated:* rules: - prefix: ${env:S3_PREFIX, ""} - existing: true \ No newline at end of file + existing: true diff --git a/src/handler.py b/src/handler.py index f874da2..7886ef8 100644 --- a/src/handler.py +++ b/src/handler.py @@ -36,7 +36,7 @@ MAX_FILE_SIZE = 400 * 1000 * 1024 # Max batch size for sending requests (1MB) MAX_BATCH_SIZE = 1000 * 1024 -BATCH_SIZE_FACTOR = 1.5 + REQUEST_BATCH_SIZE = 25 completed_requests = 0 @@ -50,6 +50,41 @@ class BadRequestException(Exception): pass +def _is_ignore_log_file(key=None, regex_pattern=None): + """ + This functions checks whether this log file should be ignored based on regex pattern. + """ + if not regex_pattern: + regex_pattern = os.getenv("S3_IGNORE_PATTERN", "$^") + + return bool(re.search(regex_pattern, key)) + + +def _isCloudTrail(key=None, regex_pattern=None): + """ + This functions checks whether this log file is a CloudTrail log based on regex pattern. + """ + if not regex_pattern: + regex_pattern = os.getenv( + "S3_CLOUDTRAIL_LOG_PATTERN", ".*CloudTrail.*\.json.gz$") + + return bool(re.search(regex_pattern, key)) + +def _convert_float(s): + try: + f = float(s) + except ValueError: + f = 1.5 + return f + +def _get_batch_size_factor(batch_size_factor=None): + """ + This functions gets BATCH_SIZE_FACTOR from env vars. + """ + if batch_size_factor: + return batch_size_factor + return _convert_float(os.getenv("BATCH_SIZE_FACTOR", "1.5")) + def _get_license_key(license_key=None): """ This functions gets New Relic's license key from env vars. @@ -100,7 +135,9 @@ def _compress_payload(data): This method usually returns a list of one element, but can be bigger if the payload size is too big """ + logger.debug(f"uncompressed size: {sys.getsizeof(json.dumps(data).encode())}") payload = gzip.compress(json.dumps(data).encode()) + logger.debug(f"compressed size: {sys.getsizeof(payload)}") return payload @@ -201,7 +238,7 @@ async def _fetch_data_from_s3(bucket, key, context): logger.error( "The log file uploaded to S3 is larger than the supported max size of 400MB") return - + BATCH_SIZE_FACTOR = _get_batch_size_factor() s3MetaData = { "invoked_function_arn": context.invoked_function_arn, "s3_bucket_name": bucket @@ -213,24 +250,23 @@ async def _fetch_data_from_s3(bucket, key, context): batch_counter = 1 log_batch_size = 0 start = time.time() - isCloudTrail = bool(re.search(".*CloudTrail.*\.json.gz$", key)) with open(log_file_url, encoding='utf-8') as log_lines: - if isCloudTrail: + if _isCloudTrail(key): # This is a CloudTrail log - we need to apply special preprocessing cloudtrail_events=json.loads(log_lines.read())["Records"] for this_event in cloudtrail_events: # Convert the eventTime to Posix time and pass it to New Relic as a timestamp attribute - this_event['timestamp']=time.mktime((parser.parse(this_event['eventTime'])).timetuple()) + this_event['timestamp']=time.mktime((parser.parse(this_event['eventTime'])).timetuple()) log_lines = cloudtrail_events for index, log in enumerate(log_lines): - log_batch_size += sys.getsizeof(log) + log_batch_size += sys.getsizeof(str(log)) if index % 500 == 0: logger.debug(f"index: {index}") - logger.debug(f"log_batch_size: {log_batch_size}") + logger.debug(f"log_batch_size: {log_batch_size}") log_batches.append(log) if log_batch_size > (MAX_BATCH_SIZE * BATCH_SIZE_FACTOR): - logger.debug(f"sending batch: {batch_counter}") + logger.debug(f"sending batch: {batch_counter} log_batch_size: {log_batch_size}") data = {"context": s3MetaData, "entry": log_batches} batch_request.append(create_log_payload_request(data, session)) if len(batch_request) >= REQUEST_BATCH_SIZE: @@ -257,6 +293,12 @@ def lambda_handler(event, context): bucket = event['Records'][0]['s3']['bucket']['name'] key = urllib.parse.unquote_plus( event['Records'][0]['s3']['object']['key'], encoding='utf-8') + + # Allow user to skip log file using regex pattern set in env variable: S3_IGNORE_PATTERN + if _is_ignore_log_file(key): + logger.debug(f"Ignore log file based on S3_IGNORE_PATTERN: {key}") + return {'statusCode': 200, 'message': 'ignored this log'} + try: asyncio.run(_fetch_data_from_s3(bucket, key, context)) except KeyError as e: From 58cab14032f3506e7d8814b5ed8d6ec542143173 Mon Sep 17 00:00:00 2001 From: haihongren Date: Tue, 19 Jul 2022 09:16:20 +1000 Subject: [PATCH 03/33] added PermissionsBoundary and FunctionRole optional parameters --- requirements.txt => src/requirements.txt | 0 template.yml | 88 ++++++++++++++++++++---- 2 files changed, 76 insertions(+), 12 deletions(-) rename requirements.txt => src/requirements.txt (100%) diff --git a/requirements.txt b/src/requirements.txt similarity index 100% rename from requirements.txt rename to src/requirements.txt diff --git a/template.yml b/template.yml index ac8fe4a..933cc3b 100644 --- a/template.yml +++ b/template.yml @@ -1,6 +1,31 @@ AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: Sends log data from S3 to New Relic Logging. +Metadata: + AWS::ServerlessRepo::Application: + Name: NewRelic-log-ingestion-s3-RPB + Description: Send log data from a S3 bucket to New Relic Logging. + Author: New Relic + SpdxLicenseId: Apache-2.0 + LicenseUrl: LICENSE + ReadmeUrl: README.md + Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] + HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda + SemanticVersion: 1.1.10 + SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda + + AWS::CloudFormation::Interface: + ParameterGroups: + - + Label: + default: "Deployment Settings" + Parameters: + - NRLicenseKey + - FunctionRole + - PermissionsBoundary + - NRLogType + - DebugEnabled + Parameters: NRLicenseKey: Type: String @@ -14,23 +39,61 @@ Parameters: Type: String Description: A boolean to determine if you want to output debug messages in the CloudWatch console Default: "false" + FunctionRole: + Type: String + Description: | + (Optional) The ARN of an IAM role to use as this function's execution role. Should provide the AWSLambdaBasicExecutionRole policy. + If not specified, an appropriate Role will be created, which will require CAPABILITY_IAM to be acknowledged. + Default: '' + PermissionsBoundary: + Type: String + Description: | + (Optional) The ARN of a permissions boundary to use for this function's execution role. This property works only if the role is generated for you. + Default: '' + +Conditions: + NoRole: !Equals ['', !Ref FunctionRole] + NoCap: !Not [ !Equals ['', !Ref FunctionRole] ] + HasPermissionBoundary: !Not [ !Equals ['', !Ref PermissionsBoundary] ] -Metadata: - AWS::ServerlessRepo::Application: - Name: NewRelic-log-ingestion-s3 - Description: Send log data from a S3 bucket to New Relic Logging. - Author: New Relic - SpdxLicenseId: Apache-2.0 - LicenseUrl: LICENSE - ReadmeUrl: README.md - Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] - HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.1.1 - SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda Resources: + NewRelicLogIngestion: + Type: 'AWS::Serverless::Function' + Condition: NoCap + Properties: + Runtime: python3.8 + CodeUri: src/ + Handler: handler.lambda_handler + FunctionName: NewRelic-s3-log-ingestion + Timeout: 900 + MemorySize: 256 + Environment: + Variables: + LICENSE_KEY: !Ref NRLicenseKey + LOG_TYPE: !Ref NRLogType + DEBUG_ENABLED: !Ref DebugEnabled + PermissionsBoundary: !If [ HasPermissionBoundary, !Ref PermissionsBoundary, !Ref AWS::NoValue ] + Role: !Ref FunctionRole + Policies: + - Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - 's3:GetObject' + Resource: 'arn:aws:s3:::*' + Events: + BucketEvent1: + Type: S3 + Properties: + Bucket: + Ref: SourceLogBucket + Events: + - 's3:ObjectCreated:*' + NewRelicLogIngestionFunction: Type: 'AWS::Serverless::Function' + Condition: NoRole Properties: Runtime: python3.8 CodeUri: src/ @@ -43,6 +106,7 @@ Resources: LICENSE_KEY: !Ref NRLicenseKey LOG_TYPE: !Ref NRLogType DEBUG_ENABLED: !Ref DebugEnabled + PermissionsBoundary: !If [ HasPermissionBoundary, !Ref PermissionsBoundary, !Ref AWS::NoValue ] Policies: - Version: '2012-10-17' Statement: From 5301a0440695f2709b1ce2dbcdd8e8c93eb1050b Mon Sep 17 00:00:00 2001 From: haihongren Date: Wed, 27 Jul 2022 13:08:49 +1000 Subject: [PATCH 04/33] updated _get_batch_size_factor to fallback to original value set in var BATCH_SIZE_FACTOR --- src/handler.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/handler.py b/src/handler.py index 7886ef8..7c59b19 100644 --- a/src/handler.py +++ b/src/handler.py @@ -36,6 +36,7 @@ MAX_FILE_SIZE = 400 * 1000 * 1024 # Max batch size for sending requests (1MB) MAX_BATCH_SIZE = 1000 * 1024 +BATCH_SIZE_FACTOR = 1.5 REQUEST_BATCH_SIZE = 25 @@ -83,7 +84,7 @@ def _get_batch_size_factor(batch_size_factor=None): """ if batch_size_factor: return batch_size_factor - return _convert_float(os.getenv("BATCH_SIZE_FACTOR", "1.5")) + return _convert_float(os.getenv("BATCH_SIZE_FACTOR", BATCH_SIZE_FACTOR)) def _get_license_key(license_key=None): """ From be0965720ed9d07c6b9e9f4eac534b7f77385918 Mon Sep 17 00:00:00 2001 From: nedl86 <56379645+nedl86@users.noreply.github.com> Date: Fri, 5 Nov 2021 10:00:55 +1000 Subject: [PATCH 05/33] Increment version Incremented version to 1.1.2 --- src/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handler.py b/src/handler.py index 4b3a816..bdc630a 100644 --- a/src/handler.py +++ b/src/handler.py @@ -19,7 +19,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.1.1' +LOGGING_LAMBDA_VERSION = '1.1.2' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION From b8722d8e0c53fa8bada14a08c3026b005fc26698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Mon, 22 Aug 2022 15:43:03 +0200 Subject: [PATCH 06/33] Bump version to 1.1.3 --- src/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handler.py b/src/handler.py index 7c59b19..128f136 100644 --- a/src/handler.py +++ b/src/handler.py @@ -18,7 +18,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.1.2' +LOGGING_LAMBDA_VERSION = '1.1.3' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION From eee8ddbae2722e018e7962f33ef80bcf097776b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Wed, 24 Aug 2022 17:38:51 +0200 Subject: [PATCH 07/33] fix: Moving the requirements back to the src folder This is needed so SAM takes care of the dependency management when packaging --- requirements.txt => src/requirements.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename requirements.txt => src/requirements.txt (100%) diff --git a/requirements.txt b/src/requirements.txt similarity index 100% rename from requirements.txt rename to src/requirements.txt From cfd81eca8988edbbf57ac515e92f4a2291929212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Wed, 24 Aug 2022 17:44:32 +0200 Subject: [PATCH 08/33] fix: update the version to 1.1.2 in the template as well --- template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template.yml b/template.yml index ac8fe4a..a6f9716 100644 --- a/template.yml +++ b/template.yml @@ -25,7 +25,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.1.1 + SemanticVersion: 1.1.2 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda Resources: From b9c94010915804e6e04fba147af4c45c1abf12fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Thu, 25 Aug 2022 14:07:59 +0200 Subject: [PATCH 09/33] docs: Adding developer docs and makefile --- .gitignore | 4 ++- DEVELOPER.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 43 ++++++++++++++++++++++++++++++++ README.md | 8 +++++- test/mock.json | 20 +++++++++++++++ 5 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 DEVELOPER.md create mode 100644 Makefile create mode 100644 test/mock.json diff --git a/.gitignore b/.gitignore index 4e395d0..df855de 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,6 @@ packaged.yml # SAM .aws-sam/ #VS Code -.vscode/ \ No newline at end of file +.vscode/ +#JetBrains +.idea \ No newline at end of file diff --git a/DEVELOPER.md b/DEVELOPER.md new file mode 100644 index 0000000..b9fa474 --- /dev/null +++ b/DEVELOPER.md @@ -0,0 +1,66 @@ +# Developer + +This project uses [SAM](https://aws.amazon.com/serverless/sam/) tool for build, +run locally, package and publish. + +There is a serverless file to play locally as well, but here we will focus on +the [SAM](https://aws.amazon.com/serverless/sam/) way of doing it. + +## Requirements + +- Make + +### Local run / build + +- Docker +- AWS Account +- AWS Profile configured on your computer, remember that AWS uses the `default` + profile unless you specify it. You can specify usign `AWS_PROFILE` enviroment + variable. +- [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-reference.html#serverless-sam-cli) + +### Package + +- An AWS S3 bucket where the package will be uploaded + +### Publishing + +- For personal publishing is mandatory to update the function name on the + `template.yml` file to avoid collide with the New Relic official release of + this application. + +### Deploy + +- AWS Account and enough permissions to do the deploy, generated template will + need IAM capabilities. + +## Building it locally + +This will generate an image of the lambda application using a docker container +that you will be able to run locally. + +Just run `make build`. + +## Running locally + +You should have built the image locally as mentioned in the previous step. + +Then you need to have a "sample" event of a file in an S3 bucket so we can use +it, we provide a sample one in the test/mock.json but it wouldn't work if you +haven't access to the given S3 bucket. + +Then just run `LICENSE_KEY= TEST_FILE="./test/mock.json" make run-local` to run it locally. + +## Packaging + +Run `BUCKET= REGION= make package` + +## Deploying + +Run `REGION= STACK_NAME= make deploy` + +## Publishing + +Run `REGION= make publish` to publish your package. Remember to +update the function name before publishing it to do not collide with the New +Relic official application. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..94f4e67 --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +build: + sam build --use-container + +run: check-run-env + sam local invoke "NewRelicLogIngestionFunction" -e $(TEST_FILE) + +package: check-package-env + sam package --output-template-file packaged.yml --s3-bucket $(BUCKET) --region $(REGION) + +deploy: check-deploy-env + sam deploy --template-file packaged.yml --stack-name $(STACK_NAME) --region $(REGION) + +publish: check-publish-env + sam publish --template packaged.yml --region $(REGION) + +check-run-env: +ifndef LICENSE_KEY + $(error LICENSE_KEY is undefined) +endif +ifndef TEST_FILE + $(error TEST_FILE is undefined) +endif + +check-package-env: +ifndef REGION + $(error REGION is undefined) +endif +ifndef BUCKET + $(error BUCKET is undefined) +endif + +check-deploy-env: +ifndef REGION + $(error REGION is undefined) +endif +ifndef STACK_NAME + $(error STACK_NAME is undefined) +endif + +check-publish-env: +ifndef REGION + $(error REGION is undefined) +endif diff --git a/README.md b/README.md index b082562..0a11528 100644 --- a/README.md +++ b/README.md @@ -22,5 +22,11 @@ Contributions to improve s3-log-ingestion-lambda are encouraged! Keep in mind wh To execute our corporate CLA, which is required if your contribution is on behalf of a company, or if you have any questions, please drop us an email at opensource@newrelic.com. +## Developers + +For more information about how to contribute from the developer point of view, +we recommend you to take a look to the [DEVELOPER.md](./DEVELOPER.md) that +contains most of the info you'll need. + ## License -`s3-log-ingestion-lambda` is licensed under the [Apache 2.0](http://apache.org/licenses/LICENSE-2.0.txt) License. The s3-log-ingestion-lambda also uses source code from third party libraries. Full details on which libraries are used and the terms under which they are licensed can be found in the third party notices docume \ No newline at end of file +`s3-log-ingestion-lambda` is licensed under the [Apache 2.0](http://apache.org/licenses/LICENSE-2.0.txt) License. The s3-log-ingestion-lambda also uses source code from third party libraries. Full details on which libraries are used and the terms under which they are licensed can be found in the third party notices docume diff --git a/test/mock.json b/test/mock.json new file mode 100644 index 0000000..ed796d0 --- /dev/null +++ b/test/mock.json @@ -0,0 +1,20 @@ +{ + "Records": [ + { + "eventVersion": "2.1", + "eventSource": "aws:s3", + "awsRegion": "us-east-1", + "eventName": "ObjectCreated:Put", + "s3": { + "s3SchemaVersion": "1.0", + "bucket": { + "name": "s3-nr-log-test-bucket", + "arn": "arn:aws:s3:::s3-nr-log-test-bucket" + }, + "object": { + "key": "cloudflare-test-data.json.gz" + } + } + } + ] +} From 73db6041d8a2659adcb44fb132ba2a5a27bb052a Mon Sep 17 00:00:00 2001 From: Melissa Klein <43244625+melissaklein24@users.noreply.github.com> Date: Thu, 25 Aug 2022 11:16:46 -0400 Subject: [PATCH 10/33] Update README.md (#22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update README.md Updated to Community Plus header * Fix typo docume to document Co-authored-by: Daniel Rodríguez --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0a11528..9cf811c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Community Project header](https://github.com/newrelic/open-source-office/raw/master/examples/categories/images/Community_Project.png)](https://github.com/newrelic/open-source-office/blob/master/examples/categories/index.md#community-project) +[![Community Plus header](https://github.com/newrelic/opensource-website/raw/master/src/images/categories/Community_Plus.png)](https://opensource.newrelic.com/oss-category/#community-plus) # AWS Lambda for sending logs from S3 to New Relic @@ -29,4 +29,4 @@ we recommend you to take a look to the [DEVELOPER.md](./DEVELOPER.md) that contains most of the info you'll need. ## License -`s3-log-ingestion-lambda` is licensed under the [Apache 2.0](http://apache.org/licenses/LICENSE-2.0.txt) License. The s3-log-ingestion-lambda also uses source code from third party libraries. Full details on which libraries are used and the terms under which they are licensed can be found in the third party notices docume +`s3-log-ingestion-lambda` is licensed under the [Apache 2.0](http://apache.org/licenses/LICENSE-2.0.txt) License. The s3-log-ingestion-lambda also uses source code from third party libraries. Full details on which libraries are used and the terms under which they are licensed can be found in the third party notices document \ No newline at end of file From 380f52a48ba0f5bd8070cc5dd2ba2413553bc644 Mon Sep 17 00:00:00 2001 From: William-Hill Date: Thu, 25 Aug 2022 11:55:39 -0400 Subject: [PATCH 11/33] Updated vulnerable packages (#30) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Rodríguez --- src/requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/requirements.txt b/src/requirements.txt index 9d033f6..fa7be3b 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.6.2 +aiohttp==3.7.4 async-timeout==3.0.1 attrs==19.3.0 boto==2.49.0 @@ -16,5 +16,5 @@ s3transfer==0.3.3 six==1.15.0 smart-open==2.1.0 typing-extensions==3.7.4.2 -urllib3==1.25.10 +urllib3==1.26.5 yarl==1.5.1 From 2265011646bf793ee098f4aa37bb6a2197b19314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Thu, 25 Aug 2022 18:28:14 +0200 Subject: [PATCH 12/33] Upgrade dependencies versions because vulnerability issues (#42) * Upgrade dependencies versions because vulnerability issues * Version bump to v1.1.4 --- src/handler.py | 2 +- src/requirements.txt | 8 ++++---- template.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/handler.py b/src/handler.py index 128f136..2c52021 100644 --- a/src/handler.py +++ b/src/handler.py @@ -18,7 +18,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.1.3' +LOGGING_LAMBDA_VERSION = '1.1.4' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/src/requirements.txt b/src/requirements.txt index fa7be3b..a8e2652 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -2,8 +2,8 @@ aiohttp==3.7.4 async-timeout==3.0.1 attrs==19.3.0 boto==2.49.0 -boto3==1.14.40 -botocore==1.17.40 +boto3==1.24.59 +botocore==1.27.59 certifi==2020.6.20 chardet==3.0.4 docutils==0.15.2 @@ -11,8 +11,8 @@ idna==2.10 jmespath==0.10.0 multidict==4.7.6 python-dateutil==2.8.1 -requests==2.24.0 -s3transfer==0.3.3 +requests==2.28.1 +s3transfer==0.6.0 six==1.15.0 smart-open==2.1.0 typing-extensions==3.7.4.2 diff --git a/template.yml b/template.yml index 8b815d6..dc285a8 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.1.3 + SemanticVersion: 1.1.4 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: From 71c2c8ec89f9056bea7c874dd64e2495e86ffdc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Thu, 25 Aug 2022 19:25:03 +0200 Subject: [PATCH 13/33] Bump version to 1.1.5 --- src/handler.py | 2 +- template.yml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/handler.py b/src/handler.py index abb0244..27e7431 100644 --- a/src/handler.py +++ b/src/handler.py @@ -18,7 +18,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.1.4' +LOGGING_LAMBDA_VERSION = '1.1.5' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/template.yml b/template.yml index af0fa3f..1d2970a 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.1.4 + SemanticVersion: 1.1.5 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: @@ -76,6 +76,7 @@ Resources: LICENSE_KEY: !Ref NRLicenseKey LOG_TYPE: !Ref NRLogType DEBUG_ENABLED: !Ref DebugEnabled + ADDITIONAL_ATTRIBUTES: !Ref AdditionalTags PermissionsBoundary: !If [ HasPermissionBoundary, !Ref PermissionsBoundary, !Ref AWS::NoValue ] Role: !Ref FunctionRole Policies: From a6c9cdfadba98a2184b484bdcfedbf9a0f0dbd76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez?= Date: Fri, 26 Aug 2022 11:02:53 +0200 Subject: [PATCH 14/33] Update template to include CloudTrails config and AdditionalAttributes --- src/handler.py | 19 ++++++++++++------- template.yml | 32 +++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/handler.py b/src/handler.py index 27e7431..574e973 100644 --- a/src/handler.py +++ b/src/handler.py @@ -32,6 +32,11 @@ class InvalidArgumentException(Exception): def _format_error(e, text): return "{}. {}".format(e, text) +def _get_optional_env(key, default): + """ + Returns the default value even if the environment variable is set but empty + """ + return os.getenv(key, default) or default def _get_additional_attributes(attributes=None): """ @@ -45,7 +50,7 @@ def _get_additional_attributes(attributes=None): """ if attributes: return attributes - env_attributes = os.getenv("ADDITIONAL_ATTRIBUTES", "{}") + env_attributes = _get_optional_env("ADDITIONAL_ATTRIBUTES", "{}") try: return json.loads(env_attributes) except json.JSONDecodeError as e: @@ -88,7 +93,7 @@ def _is_ignore_log_file(key=None, regex_pattern=None): This functions checks whether this log file should be ignored based on regex pattern. """ if not regex_pattern: - regex_pattern = os.getenv("S3_IGNORE_PATTERN", "$^") + regex_pattern = _get_optional_env("S3_IGNORE_PATTERN", "$^") return bool(re.search(regex_pattern, key)) @@ -98,7 +103,7 @@ def _isCloudTrail(key=None, regex_pattern=None): This functions checks whether this log file is a CloudTrail log based on regex pattern. """ if not regex_pattern: - regex_pattern = os.getenv( + regex_pattern = _get_optional_env( "S3_CLOUDTRAIL_LOG_PATTERN", ".*CloudTrail.*\.json.gz$") return bool(re.search(regex_pattern, key)) @@ -116,7 +121,7 @@ def _get_batch_size_factor(batch_size_factor=None): """ if batch_size_factor: return batch_size_factor - return _convert_float(os.getenv("BATCH_SIZE_FACTOR", BATCH_SIZE_FACTOR)) + return _convert_float(_get_optional_env("BATCH_SIZE_FACTOR", BATCH_SIZE_FACTOR)) def _get_license_key(license_key=None): """ @@ -124,14 +129,14 @@ def _get_license_key(license_key=None): """ if license_key: return license_key - return os.getenv("LICENSE_KEY", "") + return _get_optional_env("LICENSE_KEY", "") def _get_log_type(log_type=None): """ This functions gets the New Relic logtype from env vars. """ - return log_type or os.getenv("LOG_TYPE") or os.getenv("LOGTYPE", "") + return log_type or _get_optional_env("LOG_TYPE", "") def _setting_console_logging_level(): @@ -139,7 +144,7 @@ def _setting_console_logging_level(): Determines whether or not debug logging should be enabled based on the env var. Defaults to false. """ - if os.getenv("DEBUG_ENABLED", "false").lower() == "true": + if _get_optional_env("DEBUG_ENABLED", "false").lower() == "true": print("enabling debug mode") logger.setLevel(logging.DEBUG) else: diff --git a/template.yml b/template.yml index 1d2970a..5304fce 100644 --- a/template.yml +++ b/template.yml @@ -39,21 +39,33 @@ Parameters: Type: String Description: A boolean to determine if you want to output debug messages in the CloudWatch console Default: "false" - AdditionalTags: + AdditionalAttributes: Type: String - Description: A string containing json object(string,string). These attributes will be added to New Relic payload. - Default: "{}" + Description: "(Optional) A string containing json object(string,string). These attributes will be added to New Relic payload." + Default: "" + S3CloudTrailLogPattern: + Type: String + Description: "(Optional) Regex pattern to check if the file is from CloudTrail" + Default: "" + S3IgnorePattern: + Type: String + Description: "(Optional) Regex pattern to ignore files" + Default: "" + BatchSizeFactor: + Type: String + Description: "(Optional) Indicates the expected compression factor of your logs. Used to check if logs could be sent to the API (that is limited to 1Mb of compressed data)" + Default: "" FunctionRole: Type: String Description: | (Optional) The ARN of an IAM role to use as this function's execution role. Should provide the AWSLambdaBasicExecutionRole policy. If not specified, an appropriate Role will be created, which will require CAPABILITY_IAM to be acknowledged. - Default: '' + Default: "" PermissionsBoundary: Type: String Description: | (Optional) The ARN of a permissions boundary to use for this function's execution role. This property works only if the role is generated for you. - Default: '' + Default: "" Conditions: NoRole: !Equals ['', !Ref FunctionRole] @@ -76,7 +88,10 @@ Resources: LICENSE_KEY: !Ref NRLicenseKey LOG_TYPE: !Ref NRLogType DEBUG_ENABLED: !Ref DebugEnabled - ADDITIONAL_ATTRIBUTES: !Ref AdditionalTags + S3_CLOUD_TRAIL_LOG_PATTERN: !Ref S3CloudTrailLogPattern + S3_IGNORE_PATTERN: !Ref S3IgnorePattern + BATCH_SIZE_FACTOR: !Ref BatchSizeFactor + ADDITIONAL_ATTRIBUTES: !Ref AdditionalAttributes PermissionsBoundary: !If [ HasPermissionBoundary, !Ref PermissionsBoundary, !Ref AWS::NoValue ] Role: !Ref FunctionRole Policies: @@ -110,7 +125,10 @@ Resources: LICENSE_KEY: !Ref NRLicenseKey LOG_TYPE: !Ref NRLogType DEBUG_ENABLED: !Ref DebugEnabled - ADDITIONAL_ATTRIBUTES: !Ref AdditionalTags + S3_CLOUD_TRAIL_LOG_PATTERN: !Ref S3CloudTrailLogPattern + S3_IGNORE_PATTERN: !Ref S3IgnorePattern + BATCH_SIZE_FACTOR: !Ref BatchSizeFactor + ADDITIONAL_ATTRIBUTES: !Ref AdditionalAttributes PermissionsBoundary: !If [ HasPermissionBoundary, !Ref PermissionsBoundary, !Ref AWS::NoValue ] Policies: - Version: '2012-10-17' From 51fa3162dc096877dc040cdc812f62e19bae9581 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 13 Apr 2023 11:24:56 +0200 Subject: [PATCH 15/33] Upgrade vulnerable dependencies (#53) --- src/handler.py | 2 +- src/requirements.txt | 8 ++++---- template.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/handler.py b/src/handler.py index 574e973..4cdb27f 100644 --- a/src/handler.py +++ b/src/handler.py @@ -18,7 +18,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.1.5' +LOGGING_LAMBDA_VERSION = '1.1.6' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/src/requirements.txt b/src/requirements.txt index a8e2652..f2053b4 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,10 +1,10 @@ -aiohttp==3.7.4 -async-timeout==3.0.1 +aiohttp==3.8.4 +async-timeout==4.0.2 attrs==19.3.0 boto==2.49.0 boto3==1.24.59 botocore==1.27.59 -certifi==2020.6.20 +certifi==2022.12.7 chardet==3.0.4 docutils==0.15.2 idna==2.10 @@ -16,5 +16,5 @@ s3transfer==0.6.0 six==1.15.0 smart-open==2.1.0 typing-extensions==3.7.4.2 -urllib3==1.26.5 +urllib3==1.26.15 yarl==1.5.1 diff --git a/template.yml b/template.yml index 5304fce..a5dec7c 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.1.5 + SemanticVersion: 1.1.6 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: From f18a243e551fc0e6eddefe7102f98f665e0faeb7 Mon Sep 17 00:00:00 2001 From: jsobrino Date: Thu, 16 Nov 2023 12:36:29 +0100 Subject: [PATCH 16/33] feat: bump Python runtime version to v3.11 --- DEVELOPER.md | 12 ++++++------ serverless.yml | 2 +- src/handler.py | 2 +- src/requirements.txt | 2 +- template.yml | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/DEVELOPER.md b/DEVELOPER.md index b9fa474..b4007fa 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -23,17 +23,17 @@ the [SAM](https://aws.amazon.com/serverless/sam/) way of doing it. - An AWS S3 bucket where the package will be uploaded +### Deploy + +- AWS Account and enough permissions to do the deploy, generated template will + need IAM capabilities. + ### Publishing - For personal publishing is mandatory to update the function name on the `template.yml` file to avoid collide with the New Relic official release of this application. -### Deploy - -- AWS Account and enough permissions to do the deploy, generated template will - need IAM capabilities. - ## Building it locally This will generate an image of the lambda application using a docker container @@ -49,7 +49,7 @@ Then you need to have a "sample" event of a file in an S3 bucket so we can use it, we provide a sample one in the test/mock.json but it wouldn't work if you haven't access to the given S3 bucket. -Then just run `LICENSE_KEY= TEST_FILE="./test/mock.json" make run-local` to run it locally. +Then just run `LICENSE_KEY= TEST_FILE="./test/mock.json" make run` to run it locally. ## Packaging diff --git a/serverless.yml b/serverless.yml index 8602a46..0e61d1c 100644 --- a/serverless.yml +++ b/serverless.yml @@ -22,7 +22,7 @@ service: ${env:SERVICE_NAME} provider: name: aws - runtime: python3.8 + runtime: python3.11 iamRoleStatements: - Effect: "Allow" Action: diff --git a/src/handler.py b/src/handler.py index 4cdb27f..a9d3b10 100644 --- a/src/handler.py +++ b/src/handler.py @@ -18,7 +18,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.1.6' +LOGGING_LAMBDA_VERSION = '1.2.0' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/src/requirements.txt b/src/requirements.txt index f2053b4..eb93f68 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -17,4 +17,4 @@ six==1.15.0 smart-open==2.1.0 typing-extensions==3.7.4.2 urllib3==1.26.15 -yarl==1.5.1 +yarl==1.9.1 diff --git a/template.yml b/template.yml index a5dec7c..2b5fa0d 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.1.6 + SemanticVersion: 1.2.0 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: @@ -77,7 +77,7 @@ Resources: Type: 'AWS::Serverless::Function' Condition: NoCap Properties: - Runtime: python3.8 + Runtime: python3.11 CodeUri: src/ Handler: handler.lambda_handler FunctionName: NewRelic-s3-log-ingestion @@ -114,7 +114,7 @@ Resources: Type: 'AWS::Serverless::Function' Condition: NoRole Properties: - Runtime: python3.8 + Runtime: python3.11 CodeUri: src/ Handler: handler.lambda_handler FunctionName: NewRelic-s3-log-ingestion From d54671e2193e86741a73dd9a1313d338601bddd6 Mon Sep 17 00:00:00 2001 From: spalanisamy Date: Mon, 22 Jan 2024 20:23:29 +0530 Subject: [PATCH 17/33] Issue with CloudTrail digest fixed --- serverless.yml | 2 +- src/handler.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/serverless.yml b/serverless.yml index 0e61d1c..302f14d 100644 --- a/serverless.yml +++ b/serverless.yml @@ -43,7 +43,7 @@ functions: LICENSE_KEY: ${env:LICENSE_KEY} LOG_TYPE: ${env:LOG_TYPE} DEBUG_ENABLED: ${env:DEBUG_ENABLED} - S3_CLOUDTRAIL_LOG_PATTERN: ${env:S3_CLOUDTRAIL_LOG_PATTERN} + S3_CLOUD_TRAIL_LOG_PATTERN: ${env:S3_CLOUD_TRAIL_LOG_PATTERN} S3_IGNORE_PATTERN: ${env:S3_IGNORE_PATTERN} BATCH_SIZE_FACTOR: ${env:BATCH_SIZE_FACTOR} ADDITIONAL_ATTRIBUTES: ${env:ADDITIONAL_ATTRIBUTES} diff --git a/src/handler.py b/src/handler.py index a9d3b10..d4beff5 100644 --- a/src/handler.py +++ b/src/handler.py @@ -104,10 +104,16 @@ def _isCloudTrail(key=None, regex_pattern=None): """ if not regex_pattern: regex_pattern = _get_optional_env( - "S3_CLOUDTRAIL_LOG_PATTERN", ".*CloudTrail.*\.json.gz$") + "S3_CLOUD_TRAIL_LOG_PATTERN", ".*_CloudTrail_.*\.json.gz$") return bool(re.search(regex_pattern, key)) +def _isCloudTrailDigest(key=None): + """ + This functions checks whether this log file is a CloudTrail-Digest based on regex pattern. + """ + return bool(re.search(".*_CloudTrail-Digest_.*\.json.gz$", key)) + def _convert_float(s): try: f = float(s) @@ -284,6 +290,9 @@ async def _fetch_data_from_s3(bucket, key, context): "s3_key": key } log_file_url = "s3://{}/{}".format(bucket, key) + if _isCloudTrailDigest(key): + # CloudTrail-Digest will not have any logs in it. Hence, no need to continue further + return async with aiohttp.ClientSession() as session: log_batches = [] batch_request = [] From f7efc582c87278f006b4eb34c1e4105fbc59b6c0 Mon Sep 17 00:00:00 2001 From: dsharma Date: Thu, 1 Feb 2024 15:44:59 +0530 Subject: [PATCH 18/33] Fix for library vulnerabilities --- src/requirements.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/requirements.txt b/src/requirements.txt index eb93f68..3a35d71 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,20 +1,20 @@ -aiohttp==3.8.4 +aiohttp==3.9.2 async-timeout==4.0.2 attrs==19.3.0 boto==2.49.0 -boto3==1.24.59 -botocore==1.27.59 -certifi==2022.12.7 +boto3==1.34.31 +botocore==1.34.31 +certifi==2023.7.22 chardet==3.0.4 docutils==0.15.2 idna==2.10 jmespath==0.10.0 multidict==4.7.6 python-dateutil==2.8.1 -requests==2.28.1 -s3transfer==0.6.0 +requests==2.31.0 +s3transfer==0.10.0 six==1.15.0 smart-open==2.1.0 typing-extensions==3.7.4.2 -urllib3==1.26.15 +urllib3==2.0.7 yarl==1.9.1 From adce9da3314a2fdf571c196be0bf1a861a4defa3 Mon Sep 17 00:00:00 2001 From: vpattupogula Date: Tue, 23 Apr 2024 10:18:41 +0530 Subject: [PATCH 19/33] fix: Fix for serverless python requirements file path --- serverless.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/serverless.yml b/serverless.yml index 302f14d..3772638 100644 --- a/serverless.yml +++ b/serverless.yml @@ -34,6 +34,7 @@ plugins: custom: pythonRequirements: + fileName: ./src/requirements.txt dockerizePip: non-linux functions: From c29711e1831fad523d180aa6649679b9020f0983 Mon Sep 17 00:00:00 2001 From: dsharma Date: Wed, 12 Jun 2024 20:13:03 +0530 Subject: [PATCH 20/33] version bump for aiohttp, idna & request library --- src/requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/requirements.txt b/src/requirements.txt index 3a35d71..bb88705 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.9.2 +aiohttp>=3.9.4 async-timeout==4.0.2 attrs==19.3.0 boto==2.49.0 @@ -7,11 +7,11 @@ botocore==1.34.31 certifi==2023.7.22 chardet==3.0.4 docutils==0.15.2 -idna==2.10 +idna>=3.7 jmespath==0.10.0 multidict==4.7.6 python-dateutil==2.8.1 -requests==2.31.0 +requests>=2.32.0 s3transfer==0.10.0 six==1.15.0 smart-open==2.1.0 From 67fd3e7f2b8675fada02ddd56a729f21963f3168 Mon Sep 17 00:00:00 2001 From: dsharma Date: Tue, 18 Jun 2024 13:34:25 +0530 Subject: [PATCH 21/33] version bump for aiohttp --- src/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/requirements.txt b/src/requirements.txt index bb88705..2f6ecb5 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,4 +1,4 @@ -aiohttp>=3.9.4 +aiohttp>=3.9.5 async-timeout==4.0.2 attrs==19.3.0 boto==2.49.0 From 2d8efbfac9fb714ec4822b0b0fa3e8d41db9fec6 Mon Sep 17 00:00:00 2001 From: Himanshu Rai Date: Wed, 16 Jul 2025 00:01:50 +0530 Subject: [PATCH 22/33] fixing vulnerabilities --- src/requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/requirements.txt b/src/requirements.txt index 2f6ecb5..4188ddb 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,13 +1,13 @@ -aiohttp>=3.9.5 +aiohttp>=3.10.11 async-timeout==4.0.2 attrs==19.3.0 boto==2.49.0 boto3==1.34.31 botocore==1.34.31 -certifi==2023.7.22 +certifi==2024.7.4 chardet==3.0.4 docutils==0.15.2 -idna>=3.7 +idna>=3.8 jmespath==0.10.0 multidict==4.7.6 python-dateutil==2.8.1 @@ -16,5 +16,5 @@ s3transfer==0.10.0 six==1.15.0 smart-open==2.1.0 typing-extensions==3.7.4.2 -urllib3==2.0.7 +urllib3==2.5.0 yarl==1.9.1 From d552c8de517e3a07975a7888961a43ca5bfd23c7 Mon Sep 17 00:00:00 2001 From: Himanshu Rai Date: Tue, 29 Jul 2025 16:44:00 +0530 Subject: [PATCH 23/33] fixing build issue --- src/requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/requirements.txt b/src/requirements.txt index 4188ddb..78d627f 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -2,8 +2,8 @@ aiohttp>=3.10.11 async-timeout==4.0.2 attrs==19.3.0 boto==2.49.0 -boto3==1.34.31 -botocore==1.34.31 +boto3>=1.34.31 +botocore>=1.34.31 certifi==2024.7.4 chardet==3.0.4 docutils==0.15.2 @@ -17,4 +17,4 @@ six==1.15.0 smart-open==2.1.0 typing-extensions==3.7.4.2 urllib3==2.5.0 -yarl==1.9.1 +yarl>=1.9.1 From 2cf0315b0dc677c11bafbe2c20bff2858fee814f Mon Sep 17 00:00:00 2001 From: Himanshu Rai Date: Wed, 26 Nov 2025 17:21:51 +0530 Subject: [PATCH 24/33] fixing CVEs --- src/handler.py | 2 +- src/requirements.txt | 32 +++++++++++++++----------------- template.yml | 2 +- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/handler.py b/src/handler.py index d4beff5..ad5ad16 100644 --- a/src/handler.py +++ b/src/handler.py @@ -18,7 +18,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.2.0' +LOGGING_LAMBDA_VERSION = '1.2.6' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/src/requirements.txt b/src/requirements.txt index 78d627f..4cb3a60 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,20 +1,18 @@ -aiohttp>=3.10.11 -async-timeout==4.0.2 -attrs==19.3.0 -boto==2.49.0 +aiohttp>=3.13.2 +async-timeout>=4.0.2 +attrs>=22.1.0 boto3>=1.34.31 botocore>=1.34.31 -certifi==2024.7.4 -chardet==3.0.4 -docutils==0.15.2 +certifi>=2024.7.4 +chardet>=5.0.0 idna>=3.8 -jmespath==0.10.0 -multidict==4.7.6 -python-dateutil==2.8.1 -requests>=2.32.0 -s3transfer==0.10.0 -six==1.15.0 -smart-open==2.1.0 -typing-extensions==3.7.4.2 -urllib3==2.5.0 -yarl>=1.9.1 +jmespath>=1.0.0 +multidict>=6.0.0 +python-dateutil>=2.8.2 +requests>=2.32.4 +s3transfer>=0.10.0 +six>=1.16.0 +smart_open>=5.2.0 +typing-extensions>=4.5.0 +urllib3>=2.2.0 +yarl>=1.9.1 \ No newline at end of file diff --git a/template.yml b/template.yml index 2b5fa0d..cd2207a 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.2.0 + SemanticVersion: 1.2.6 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: From 2c7ad3931267a70876544a8cbed9200282ba5acf Mon Sep 17 00:00:00 2001 From: pvoore Date: Mon, 22 Dec 2025 16:44:06 +0530 Subject: [PATCH 25/33] feat: Upgrade Lambda runtime to Python 3.12 --- CHANGELOG.md | 8 ++++++++ serverless.yml | 2 +- src/handler.py | 2 +- template.yml | 6 +++--- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d97afe3..f99669c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## Version 1.3.0 (2025-12-22) +- Upgraded runtime from Python 3.11 to Python 3.12 +- Updated to use Amazon Linux 2023 base (via Python 3.12 runtime) +- Python 3.11 deprecation date: June 30, 2026 +- Python 3.12 support extends until October 31, 2028 +- No code changes required - all dependencies compatible with Python 3.12 + +## Previous Versions - updated to last release 1.1.1 - updated semantic version - updated urls and lables diff --git a/serverless.yml b/serverless.yml index 3772638..bd2d7ff 100644 --- a/serverless.yml +++ b/serverless.yml @@ -22,7 +22,7 @@ service: ${env:SERVICE_NAME} provider: name: aws - runtime: python3.11 + runtime: python3.12 iamRoleStatements: - Effect: "Allow" Action: diff --git a/src/handler.py b/src/handler.py index ad5ad16..0e7b7ef 100644 --- a/src/handler.py +++ b/src/handler.py @@ -18,7 +18,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.2.6' +LOGGING_LAMBDA_VERSION = '1.3.0' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/template.yml b/template.yml index cd2207a..97c9e90 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.2.6 + SemanticVersion: 1.3.0 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: @@ -77,7 +77,7 @@ Resources: Type: 'AWS::Serverless::Function' Condition: NoCap Properties: - Runtime: python3.11 + Runtime: python3.12 CodeUri: src/ Handler: handler.lambda_handler FunctionName: NewRelic-s3-log-ingestion @@ -114,7 +114,7 @@ Resources: Type: 'AWS::Serverless::Function' Condition: NoRole Properties: - Runtime: python3.11 + Runtime: python3.12 CodeUri: src/ Handler: handler.lambda_handler FunctionName: NewRelic-s3-log-ingestion From 061e2f013bf2255e34ea36daec6420f7135ff9be Mon Sep 17 00:00:00 2001 From: lmaddikara Date: Tue, 5 May 2026 14:00:10 +0530 Subject: [PATCH 26/33] NR-560729 Add Japan region support for log ingestion endpoint --- src/handler.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/handler.py b/src/handler.py index 0e7b7ef..13c0e37 100644 --- a/src/handler.py +++ b/src/handler.py @@ -18,6 +18,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' +JP_LOGGING_INGEST_HOST = 'https://log-api.jp.newrelic.com/log/v1' LOGGING_LAMBDA_VERSION = '1.3.0' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", @@ -166,11 +167,12 @@ def _get_logging_endpoint(ingest_url=None): return ingest_url if "NR_LOGGING_ENDPOINT" in os.environ: return os.environ["NR_LOGGING_ENDPOINT"] - return ( - EU_LOGGING_INGEST_HOST - if _get_license_key().startswith("eu") - else US_LOGGING_INGEST_HOST - ) + license_key = _get_license_key() + if license_key.startswith("eu"): + return EU_LOGGING_INGEST_HOST + elif license_key.startswith("jp"): + return JP_LOGGING_INGEST_HOST + return US_LOGGING_INGEST_HOST def _compress_payload(data): From 1835c7e55c1c0549ecb99979b065a26039aab128 Mon Sep 17 00:00:00 2001 From: lmaddikara Date: Thu, 14 May 2026 12:45:27 +0530 Subject: [PATCH 27/33] Bump version to 1.4.0 for Japan region release --- src/handler.py | 2 +- template.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handler.py b/src/handler.py index 13c0e37..1193d0b 100644 --- a/src/handler.py +++ b/src/handler.py @@ -19,7 +19,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' JP_LOGGING_INGEST_HOST = 'https://log-api.jp.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.3.0' +LOGGING_LAMBDA_VERSION = '1.4.0' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/template.yml b/template.yml index 97c9e90..b3b035f 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.3.0 + SemanticVersion: 1.4.0 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: From 69b1b532d1c863f510419377d4e3f1c6ed35271c Mon Sep 17 00:00:00 2001 From: lmaddikara Date: Fri, 29 May 2026 13:35:58 +0530 Subject: [PATCH 28/33] NR-568859 Fix JP logging endpoint URL to use nr-data.net Update JP endpoint from log-api.jp.newrelic.com to log-api.jp.nr-data.net as the newrelic.com hostname has no DNS record. Bump version to 1.4.1. --- src/handler.py | 4 ++-- template.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/handler.py b/src/handler.py index 1193d0b..2385d28 100644 --- a/src/handler.py +++ b/src/handler.py @@ -18,8 +18,8 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' -JP_LOGGING_INGEST_HOST = 'https://log-api.jp.newrelic.com/log/v1' -LOGGING_LAMBDA_VERSION = '1.4.0' +JP_LOGGING_INGEST_HOST = 'https://log-api.jp.nr-data.net/log/v1' +LOGGING_LAMBDA_VERSION = '1.4.1' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/template.yml b/template.yml index b3b035f..a9b0200 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.4.0 + SemanticVersion: 1.4.1 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: From 5384914a30659743e9ed1beaa7feea1c1c9e69fc Mon Sep 17 00:00:00 2001 From: Himanshu Rai Date: Thu, 30 Jul 2026 12:10:58 +0530 Subject: [PATCH 29/33] Fix polynomial ReDoS in CloudTrail regex patterns (py/polynomial-redos) The CloudTrail and CloudTrail-Digest regex patterns used two greedy wildcards (.*) that could overlap, causing the regex engine to take exponentially longer on certain S3 key inputs. This is flagged by CodeQL as a Polynomial ReDoS vulnerability (py/polynomial-redos). Fixed by: - Removing the unnecessary leading .* (re.search already matches anywhere in the string) - Replacing the remaining .* with [^/]* so it only matches within a single path segment, preventing catastrophic backtracking - Escaping literal dots in .json.gz and using raw strings --- src/handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handler.py b/src/handler.py index 2385d28..7c6d6d9 100644 --- a/src/handler.py +++ b/src/handler.py @@ -105,7 +105,7 @@ def _isCloudTrail(key=None, regex_pattern=None): """ if not regex_pattern: regex_pattern = _get_optional_env( - "S3_CLOUD_TRAIL_LOG_PATTERN", ".*_CloudTrail_.*\.json.gz$") + "S3_CLOUD_TRAIL_LOG_PATTERN", r"_CloudTrail_[^/]*\.json\.gz$") return bool(re.search(regex_pattern, key)) @@ -113,7 +113,7 @@ def _isCloudTrailDigest(key=None): """ This functions checks whether this log file is a CloudTrail-Digest based on regex pattern. """ - return bool(re.search(".*_CloudTrail-Digest_.*\.json.gz$", key)) + return bool(re.search(r"_CloudTrail-Digest_[^/]*\.json\.gz$", key)) def _convert_float(s): try: From 6514198b44fff5f5a31c173abd4563aef9bb73a8 Mon Sep 17 00:00:00 2001 From: Himanshu Rai Date: Thu, 30 Jul 2026 12:28:20 +0530 Subject: [PATCH 30/33] Replace regex with string operations to fix polynomial ReDoS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeQL still flags re.search() with [^/]* because the engine tries every starting position in the string (O(n)) and at each match of the literal prefix, [^/]* backtracks up to O(n) characters — giving O(n^2) on inputs with repeated 'CloudTrail-Digest' substrings. Fix by using str.endswith() and 'in' checks for the default patterns, which are guaranteed O(n). A custom regex via S3_CLOUD_TRAIL_LOG_PATTERN env var is still supported for users who need it. --- src/handler.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/handler.py b/src/handler.py index 7c6d6d9..98dd645 100644 --- a/src/handler.py +++ b/src/handler.py @@ -104,16 +104,18 @@ def _isCloudTrail(key=None, regex_pattern=None): This functions checks whether this log file is a CloudTrail log based on regex pattern. """ if not regex_pattern: - regex_pattern = _get_optional_env( - "S3_CLOUD_TRAIL_LOG_PATTERN", r"_CloudTrail_[^/]*\.json\.gz$") - - return bool(re.search(regex_pattern, key)) + regex_pattern = os.getenv("S3_CLOUD_TRAIL_LOG_PATTERN", "") + if regex_pattern: + return bool(re.search(regex_pattern, key)) + # Default: string-based check avoids polynomial backtracking + return bool(key and key.endswith('.json.gz') and '_CloudTrail_' in key + and '_CloudTrail-Digest_' not in key) def _isCloudTrailDigest(key=None): """ This functions checks whether this log file is a CloudTrail-Digest based on regex pattern. """ - return bool(re.search(r"_CloudTrail-Digest_[^/]*\.json\.gz$", key)) + return bool(key and key.endswith('.json.gz') and '_CloudTrail-Digest_' in key) def _convert_float(s): try: From 6dcc3afd644800ffc4eb88f7cd6dd7b482e7810e Mon Sep 17 00:00:00 2001 From: Himanshu Rai Date: Fri, 31 Jul 2026 11:09:58 +0530 Subject: [PATCH 31/33] increasing version --- src/handler.py | 2 +- template.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handler.py b/src/handler.py index 98dd645..d7f2aa5 100644 --- a/src/handler.py +++ b/src/handler.py @@ -19,7 +19,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' JP_LOGGING_INGEST_HOST = 'https://log-api.jp.nr-data.net/log/v1' -LOGGING_LAMBDA_VERSION = '1.4.1' +LOGGING_LAMBDA_VERSION = '1.4.2' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/template.yml b/template.yml index a9b0200..72f886b 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.4.1 + SemanticVersion: 1.4.2 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: From 97e31e6770cd59679c679a83451c6e3ad04c29b5 Mon Sep 17 00:00:00 2001 From: rohit-bandlamudi-nr Date: Thu, 13 Aug 2026 16:51:29 +0530 Subject: [PATCH 32/33] fix: bump aiohttp to >=3.14.3 to resolve reported CVEs Customer security scanning flagged 11 CVEs against aiohttp in this Lambda (newrelic/aws_s3_log_ingestion_lambda#101). All are patched by 3.14.3 or earlier (highest first-patched version is 3.14.3, for CVE-2026-69244); it is also the current latest release on PyPI, matching the version newrelic/aws-log-ingestion is bumping to for the same customer report (newrelic/aws-log-ingestion#186). --- src/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/requirements.txt b/src/requirements.txt index 4cb3a60..08f93d4 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,4 +1,4 @@ -aiohttp>=3.13.2 +aiohttp>=3.14.3 async-timeout>=4.0.2 attrs>=22.1.0 boto3>=1.34.31 From 023c70963f31bd76fd76ec086a96546ad9292022 Mon Sep 17 00:00:00 2001 From: rohit-bandlamudi-nr Date: Thu, 20 Aug 2026 17:10:38 +0530 Subject: [PATCH 33/33] Bump lambda version to 1.4.3 Co-Authored-By: Claude Sonnet 5 --- src/handler.py | 2 +- template.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handler.py b/src/handler.py index d7f2aa5..25c0b09 100644 --- a/src/handler.py +++ b/src/handler.py @@ -19,7 +19,7 @@ US_LOGGING_INGEST_HOST = "https://log-api.newrelic.com/log/v1" EU_LOGGING_INGEST_HOST = 'https://log-api.eu.newrelic.com/log/v1' JP_LOGGING_INGEST_HOST = 'https://log-api.jp.nr-data.net/log/v1' -LOGGING_LAMBDA_VERSION = '1.4.2' +LOGGING_LAMBDA_VERSION = '1.4.3' LOGGING_PLUGIN_METADATA = { 'type': "s3-lambda", 'version': LOGGING_LAMBDA_VERSION diff --git a/template.yml b/template.yml index 72f886b..3008cf6 100644 --- a/template.yml +++ b/template.yml @@ -11,7 +11,7 @@ Metadata: ReadmeUrl: README.md Labels: ['newrelic', 'logs', 'logging', 'ingestion', 'lambda', 's3'] HomePageUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda - SemanticVersion: 1.4.2 + SemanticVersion: 1.4.3 SourceCodeUrl: https://github.com/newrelic/aws_s3_log_ingestion_lambda AWS::CloudFormation::Interface: