I have been playing around with this idea, and I created a Lambda Layer and using the Lambda Extension API and the newrelic-daemon executable. Its a very basic implementation, and there is indeed the occasional connection issue with cold starts, as the docs mention already
2021-04-08 11:22:17.607 +0000 (14 14) warning: daemon connect(fd=5 host=127.0.0.1, port=31339) returned -1 errno=ECONNREFUSED. Failed to connect to the newrelic-daemon. Please make sure that there is a properly configured newrelic-daemon running. For additional assistance, please see: https://newrelic.com/docs/php/newrelic-daemon-startup-modes
But for us this has been working really well, so I was wondering if the community could benefit from including the newrelic-daemon in this newrelic layer (and optionally use it)
We would need 2 additional files in the layer
extensions/bin/newrelic-daemon
extensions/newrelic.sh
where newrelic.sh is a bash script registering the Lambda Extension API and starting the daemon, based on this example
#!/bin/bash
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
set -euo pipefail
OWN_FILENAME="$(basename $0)"
LAMBDA_EXTENSION_NAME="$OWN_FILENAME" # (external) extension name has to match the filename
TMPFILE=/tmp/$OWN_FILENAME
# Graceful Shutdown
_term() {
echo "[${LAMBDA_EXTENSION_NAME}] Received SIGTERM"
# forward SIGTERM to child procs and exit
kill -TERM "$PID" 2>/dev/null
echo "[${LAMBDA_EXTENSION_NAME}] Exiting"
exit 0
}
forward_sigterm_and_wait() {
trap _term SIGTERM
wait "$PID"
trap - SIGTERM
}
# Registration
HEADERS="$(mktemp)"
echo "[${LAMBDA_EXTENSION_NAME}] Registering at http://${AWS_LAMBDA_RUNTIME_API}/2020-01-01/extension/register"
curl -sS -LD "$HEADERS" -XPOST "http://${AWS_LAMBDA_RUNTIME_API}/2020-01-01/extension/register" --header "Lambda-Extension-Name: ${LAMBDA_EXTENSION_NAME}" -d "{ \"events\": [\"INVOKE\", \"SHUTDOWN\"]}" > $TMPFILE
RESPONSE=$(<$TMPFILE)
HEADINFO=$(<$HEADERS)
# Extract Extension ID from response headers
EXTENSION_ID=$(grep -Fi Lambda-Extension-Identifier "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Start NewRelic Daemon and accept all connections
/opt/extensions/bin/newrelic-daemon --address=0.0.0.0:31339 --logfile=/proc/self/fd/2
# Event processing
while true
do
# Get an event. The HTTP request will block until one is received
curl -sS -L -XGET "http://${AWS_LAMBDA_RUNTIME_API}/2020-01-01/extension/event/next" --header "Lambda-Extension-Identifier: ${EXTENSION_ID}" > $TMPFILE &
PID=$!
forward_sigterm_and_wait
EVENT_DATA=$(<$TMPFILE)
if [[ $EVENT_DATA == *"SHUTDOWN"* ]]; then
echo "[extension: ${LAMBDA_EXTENSION_NAME}] Received SHUTDOWN event. Exiting." 1>&2;
exit 0 # Exit if we receive a SHUTDOWN event
fi
done
But than modified to only register if some environment var is set. Im also not a bash expert, I copied the example from amazon as starting point
Im curious to find out what you think about this, please share your thoughts!
I have been playing around with this idea, and I created a Lambda Layer and using the Lambda Extension API and the newrelic-daemon executable. Its a very basic implementation, and there is indeed the occasional connection issue with cold starts, as the docs mention already
But for us this has been working really well, so I was wondering if the community could benefit from including the newrelic-daemon in this newrelic layer (and optionally use it)
We would need 2 additional files in the layer extensions/bin/newrelic-daemon extensions/newrelic.sh
where
newrelic.sh
is a bash script registering the Lambda Extension API and starting the daemon, based on this exampleBut than modified to only register if some environment var is set. Im also not a bash expert, I copied the example from amazon as starting point
Im curious to find out what you think about this, please share your thoughts!