Skip to content

Commit

Permalink
Add python's newrelic_lambda package directly to layers. (newrelic#225)
Browse files Browse the repository at this point in the history
Co-authored-by: Uma Annamalai <[email protected]>
  • Loading branch information
TimPansino and umaannamalai authored Jul 29, 2024
1 parent 3a3eb14 commit 5e8e93d
Show file tree
Hide file tree
Showing 5 changed files with 499 additions and 11 deletions.
1 change: 1 addition & 0 deletions python/newrelic_lambda/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import newrelic_lambda.agent_protocol # noqa
74 changes: 74 additions & 0 deletions python/newrelic_lambda/agent_protocol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import logging
import os

from newrelic.common.encoding_utils import (
json_encode,
serverless_payload_encode,
)

try:
from newrelic.core.agent_protocol import ServerlessModeProtocol
except ImportError:
ServerlessModeProtocol = None

from newrelic.core.data_collector import ServerlessModeSession

NAMED_PIPE_PATH = "/tmp/newrelic-telemetry"

logger = logging.getLogger(__name__)


if ServerlessModeProtocol is not None:
# New Relic Agent >=5.16
def protocol_finalize(self):
for key in self.configuration.aws_lambda_metadata:
if key not in self._metadata:
self._metadata[key] = self.configuration.aws_lambda_metadata[key]

data = self.client.finalize()

payload = {
"metadata": self._metadata,
"data": data,
}

encoded = serverless_payload_encode(payload)
payload = json_encode((1, "NR_LAMBDA_MONITORING", encoded))

if os.path.exists(NAMED_PIPE_PATH):
try:
with open(NAMED_PIPE_PATH, "w") as named_pipe:
named_pipe.write(payload)
except IOError as e:
logger.error(
"Failed to write to named pipe %s: %s" % (NAMED_PIPE_PATH, e)
)
else:
print(payload)

return payload

ServerlessModeProtocol.finalize = protocol_finalize

else:
# New Relic Agent <5.16
def session_finalize(self):
encoded = serverless_payload_encode(self.payload)
payload = json_encode((1, "NR_LAMBDA_MONITORING", encoded))

if os.path.exists(NAMED_PIPE_PATH):
try:
with open(NAMED_PIPE_PATH, "w") as named_pipe:
named_pipe.write(payload)
except IOError as e:
logger.error(
"Failed to write to named pipe %s: %s" % (NAMED_PIPE_PATH, e)
)
else:
print(payload)

# Clear data after sending
self._data.clear()
return payload

ServerlessModeSession.finalize = session_finalize
128 changes: 128 additions & 0 deletions python/newrelic_lambda/event-sources.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
{
"alb": {
"attributes": {},
"name": "alb",
"required_keys": [
"httpMethod",
"requestContext.elb"
]
},
"apiGateway": {
"attributes": {
"aws.lambda.eventSource.accountId": "requestContext.accountId",
"aws.lambda.eventSource.apiId": "requestContext.apiId",
"aws.lambda.eventSource.resourceId": "requestContext.resourceId",
"aws.lambda.eventSource.resourcePath": "requestContext.resourcePath",
"aws.lambda.eventSource.stage": "requestContext.stage"
},
"name": "apiGateway",
"required_keys": [
"headers",
"httpMethod",
"path",
"requestContext",
"requestContext.stage"
]
},
"cloudFront": {
"attributes": {},
"name": "cloudFront",
"required_keys": [
"Records[0].cf"
]
},
"cloudWatchScheduled": {
"attributes": {
"aws.lambda.eventSource.account": "account",
"aws.lambda.eventSource.id": "id",
"aws.lambda.eventSource.region": "region",
"aws.lambda.eventSource.resource": "resources[0]",
"aws.lambda.eventSource.time": "time"
},
"name": "cloudWatch_scheduled",
"required_keys": [
"detail-type",
"source"
]
},
"dynamoStreams": {
"attributes": {
"aws.lambda.eventSource.length": "Records.length"
},
"name": "dynamo_streams",
"required_keys": [
"Records[0].dynamodb"
]
},
"firehose": {
"attributes": {
"aws.lambda.eventSource.length": "records.length",
"aws.lambda.eventSource.region": "region"
},
"name": "firehose",
"required_keys": [
"deliveryStreamArn",
"records[0].kinesisRecordMetadata"
]
},
"kinesis": {
"attributes": {
"aws.lambda.eventSource.length": "Records.length",
"aws.lambda.eventSource.region": "Records[0].awsRegion"
},
"name": "kinesis",
"required_keys": [
"Records[0].kinesis"
]
},
"s3": {
"attributes": {
"aws.lambda.eventSource.bucketName": "Records[0].s3.bucket.name",
"aws.lambda.eventSource.eventName": "Records[0].eventName",
"aws.lambda.eventSource.eventTime": "Records[0].eventTime",
"aws.lambda.eventSource.length": "Records.length",
"aws.lambda.eventSource.objectKey": "Records[0].s3.object.key",
"aws.lambda.eventSource.objectSequencer": "Records[0].s3.object.sequencer",
"aws.lambda.eventSource.objectSize": "Records[0].s3.object.size",
"aws.lambda.eventSource.region": "Records[0].awsRegion"
},
"name": "s3",
"required_keys": [
"Records[0].s3"
]
},
"ses": {
"attributes": {
"aws.lambda.eventSource.date": "Records[0].ses.mail.commonHeaders.date",
"aws.lambda.eventSource.length": "Records.length",
"aws.lambda.eventSource.messageId": "Records[0].ses.mail.commonHeaders.messageId",
"aws.lambda.eventSource.returnPath": "Records[0].ses.mail.commonHeaders.returnPath"
},
"name": "ses",
"required_keys": [
"Records[0].ses"
]
},
"sns": {
"attributes": {
"aws.lambda.eventSource.length": "Records.length",
"aws.lambda.eventSource.messageId": "Records[0].Sns.MessageId",
"aws.lambda.eventSource.timestamp": "Records[0].Sns.Timestamp",
"aws.lambda.eventSource.topicArn": "Records[0].Sns.TopicArn",
"aws.lambda.eventSource.type": "Records[0].Sns.Type"
},
"name": "sns",
"required_keys": [
"Records[0].Sns"
]
},
"sqs": {
"attributes": {
"aws.lambda.eventSource.length": "Records.length"
},
"name": "sqs",
"required_keys": [
"Records[0].receiptHandle"
]
}
}
Loading

0 comments on commit 5e8e93d

Please sign in to comment.