Skip to content
Merged
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
24 changes: 24 additions & 0 deletions apm-lambda-extension/extension/process_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,32 @@ import (
"log"
"os"
"strconv"
"strings"
)

type extensionConfig struct {
apmServerUrl string
apmServerSecretToken string
apmServerApiKey string
dataReceiverServerPort string
SendStrategy SendStrategy
dataReceiverTimeoutSeconds int
}

// SendStrategy represents the type of sending strategy the extension uses
type SendStrategy string

const (
// Background send strategy allows the extension to send remaining buffered
// agent data on the next function invocation
Background SendStrategy = "background"

// SyncFlush send strategy indicates that the extension will synchronously
// flush remaining buffered agent data when it receives a signal that the
// function is complete
SyncFlush SendStrategy = "syncflush"
)

func getIntFromEnv(name string) (int, error) {
strValue := os.Getenv(name)
value, err := strconv.Atoi(strValue)
Expand All @@ -54,11 +70,19 @@ func ProcessEnv() *extensionConfig {
normalizedApmLambdaServer = normalizedApmLambdaServer + "/"
}

// Get the send strategy, convert to lowercase
normalizedSendStrategy := SyncFlush
sendStrategy := strings.ToLower(os.Getenv("ELASTIC_APM_SEND_STRATEGY"))
if sendStrategy == string(Background) {
normalizedSendStrategy = Background
}

config := &extensionConfig{
apmServerUrl: normalizedApmLambdaServer,
apmServerSecretToken: os.Getenv("ELASTIC_APM_SECRET_TOKEN"),
apmServerApiKey: os.Getenv("ELASTIC_APM_API_KEY"),
dataReceiverServerPort: os.Getenv("ELASTIC_APM_DATA_RECEIVER_SERVER_PORT"),
SendStrategy: normalizedSendStrategy,
dataReceiverTimeoutSeconds: dataReceiverTimeoutSeconds,
}

Expand Down
19 changes: 19 additions & 0 deletions apm-lambda-extension/extension/process_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ func TestProcessEnv(t *testing.T) {
t.Fail()
}

if config.SendStrategy != SyncFlush {
t.Log("Default send strategy not set correctly")
t.Fail()
}

os.Setenv("ELASTIC_APM_DATA_RECEIVER_SERVER_PORT", ":8201")
config = ProcessEnv()
if config.dataReceiverServerPort != ":8201" {
Expand Down Expand Up @@ -87,4 +92,18 @@ func TestProcessEnv(t *testing.T) {
t.Log("API Key not set correctly")
t.Fail()
}

os.Setenv("ELASTIC_APM_SEND_STRATEGY", "Background")
config = ProcessEnv()
if config.SendStrategy != "background" {
t.Log("Send strategy not set correctly")
t.Fail()
}

os.Setenv("ELASTIC_APM_SEND_STRATEGY", "invalid")
config = ProcessEnv()
if config.SendStrategy != "syncflush" {
t.Log("Send strategy not set correctly")
t.Fail()
}
}
6 changes: 4 additions & 2 deletions apm-lambda-extension/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,10 @@ func main() {
log.Println("Time expired waiting for agent signal or runtimeDone event")
}

// Flush APM data now that the function invocation has completed
extension.FlushAPMData(client, agentDataChannel, config)
if config.SendStrategy == extension.SyncFlush {
// Flush APM data now that the function invocation has completed
extension.FlushAPMData(client, agentDataChannel, config)
}

close(funcDone)
close(runtimeDoneSignal)
Expand Down
17 changes: 17 additions & 0 deletions docs/aws-lambda-extension.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,23 @@ If unset, the APM Agent will automatically set the value based on `AWS_LAMBDA_FU

The timeout value, in seconds, for the Lambda Extension's server.

[discrete]
[[aws-lambda-send_strategy]]
==== `ELASTIC_APM_SEND_STRATEGY`

Whether to synchronously flush APM agent data from the extension to the APM server at the end of the function invocation.
The two accepted values are `background` and `syncflush`. The default is `syncflush`.
The `background` strategy indicates that the extension will not flush when it receives a signal that the function invocation
has completed. It will instead send any remaining buffered data on the next function invocation. The result is that, if the
function is not subsequently invoked for that Lambda environment, the buffered data will be lost. However, for lambda functions
that have a steadily frequent load pattern the extension could delay sending the data to the APM server to the next lambda
request and do the sending in parallel to the processing of that next request. This potentially would improve both the lambda
function response time and its throughput.
The other value, `syncflush` will synchronously flush all remaining buffered APM agent data to the APM server when the
extension receives a signal that the function invocation has completed. This strategy blocks the lambda function from receiving
the next request until the extension has flushed all the data. This has a negative effect on the throughput of the function,
though it ensures that all APM data is sent to the APM server.

[discrete]
[[aws-lambda-manual-instrumentation]]
== Manual Installation
Expand Down