Skip to content

Commit 71575af

Browse files
Merge pull request #34 from FireTail-io/dev
[MAIN] change to not require code changes
2 parents 164b76c + a6f269d commit 71575af

File tree

12 files changed

+349
-25
lines changed

12 files changed

+349
-25
lines changed

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ build:
1919
rm -rf build
2020
GOOS=linux GOARCH=${ARCH} go build -o build/extensions/firetail-extension-${ARCH}
2121
chmod +x build/extensions/firetail-extension-${ARCH}
22+
cp firetail-wrapper.sh build/firetail-wrapper.sh
2223

2324
.PHONY: package
2425
package: build
25-
cd build && zip -r ../build/firetail-extension-${ARCH}-${VERSION}.zip extensions/
26+
cd build && zip -r ../build/firetail-extension-${ARCH}-${VERSION}.zip extensions/ firetail-wrapper.sh
2627

2728
.PHONY: publish
2829
publish:
@@ -34,4 +35,4 @@ public:
3435

3536
.PHONY: add
3637
add:
37-
aws lambda update-function-configuration --region ${AWS_REGION} --function-name ${FUNCTION_NAME} --layers ${LAYER_ARN}
38+
aws lambda update-function-configuration --region ${AWS_REGION} --function-name ${FUNCTION_NAME} --layers ${LAYER_ARN}

examples/minimal-python/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ This example demonstrates how to setup a simple HTTP GET endpoint. Once you fetc
2121
## Deploy
2222

2323
```bash
24-
pip3 install -t src/vendor -r aws_requirements.txt
2524
npm install
26-
serverless deploy
25+
serverless deploy --param firetail-token=YOUR_API_TOKEN
2726
```
2827

2928
The expected result should be similar to:

examples/minimal-python/aws_requirements.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

examples/minimal-python/handler.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,13 @@
33
import sys
44

55
# Deps in src/vendor
6-
sys.path.insert(0, 'src/vendor')
6+
sys.path.insert(0, "src/vendor")
77

8-
from firetail_lambda import firetail_handler, firetail_app # noqa: E402
9-
app = firetail_app()
108

11-
12-
@firetail_handler(app)
139
def endpoint(event, context):
1410
current_time = datetime.datetime.now().time()
1511
return {
1612
"statusCode": 200,
17-
"body": json.dumps({
18-
"message": "Hello, the current time is %s" % current_time
19-
}),
20-
"headers": {
21-
"Current-Time": "%s" % current_time
22-
}
13+
"body": json.dumps({"message": "Hello, the current time is %s" % current_time}),
14+
"headers": {"Current-Time": "%s" % current_time},
2315
}

examples/minimal-python/serverless.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ provider:
88
environment:
99
FIRETAIL_API_TOKEN: ${param:firetail-token}
1010
FIRETAIL_EXTENSION_DEBUG: TRUE
11+
AWS_LAMBDA_EXEC_WRAPPER: /opt/firetail-wrapper.sh
1112
tracing: true
1213
iamRoleStatements:
1314
- Effect: "Allow"

firetail-wrapper.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
args=("$@")
3+
export AWS_LAMBDA_RUNTIME_API="127.0.0.1:${FIRETAIL_LAMBDA_EXTENSION_PORT:-9009}"
4+
exec "${args[@]}"

firetail/record_receiver.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package firetail
2+
3+
import "log"
4+
5+
// recordReceiver receives records from the client into batches & passes them to the batch callback. If the batch callback
6+
// returns an err, it does not remove the log entries from the batch.
7+
func RecordReceiver(recordsChannel chan Record, maxBatchSize int, firetailApiUrl, firetailApiToken string) {
8+
recordsBatch := []Record{}
9+
10+
for {
11+
newRecords, recordsRemaining := receiveRecords(recordsChannel, maxBatchSize-len(recordsBatch))
12+
recordsBatch = append(recordsBatch, newRecords...)
13+
14+
// If the batch is empty, but there's records remaining, then we continue; else we return.
15+
if len(recordsBatch) == 0 {
16+
if recordsRemaining {
17+
continue
18+
} else {
19+
return
20+
}
21+
}
22+
23+
// Give the batch to the batch callback. If it errs, we continue
24+
recordsSent, err := SendRecordsToSaaS(recordsBatch, firetailApiUrl, firetailApiToken)
25+
if err != nil {
26+
log.Println("Error sending records to Firetail:", err.Error())
27+
continue
28+
}
29+
log.Println("Successfully sent", recordsSent, "record(s) to Firetail.")
30+
31+
// If the batch callback succeeded, we can clear the batch!
32+
recordsBatch = []Record{}
33+
}
34+
}
35+
36+
// ReceiveRecords returns a slice of firetail Records up to the size of `limit`, and a boolean indicating that the channel
37+
// still has items to be read - it will only be `false` when the channel is closed & empty. It achieves this by continuously
38+
// reading from the log server's recordsChannel until it's empty, or the size limit has been reached.
39+
func receiveRecords(recordsChannel chan Record, limit int) ([]Record, bool) {
40+
records := []Record{}
41+
for {
42+
select {
43+
case record, open := <-recordsChannel:
44+
if !open {
45+
return records, false
46+
}
47+
records = append(records, record)
48+
if len(records) == limit {
49+
return records, true
50+
}
51+
default:
52+
return records, true
53+
}
54+
}
55+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ require (
1111

1212
require (
1313
github.com/davecgh/go-spew v1.1.1 // indirect
14+
github.com/go-chi/chi/v5 v5.2.1
1415
github.com/hashicorp/errwrap v1.0.0 // indirect
1516
github.com/pmezard/go-difflib v1.0.0 // indirect
1617
gopkg.in/yaml.v3 v3.0.1 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ github.com/aws/aws-lambda-go v1.34.1/go.mod h1:jwFe2KmMsHmffA1X2R09hH6lFzJQxzI8q
33
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
44
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
55
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6+
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
7+
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
68
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
79
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
810
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=

main.go

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package main
22

33
import (
44
"firetail-lambda-extension/extensionsapi"
5+
"firetail-lambda-extension/firetail"
56
"firetail-lambda-extension/logsapi"
7+
"firetail-lambda-extension/proxy"
68
"fmt"
79
"io/ioutil"
810
"log"
@@ -35,16 +37,36 @@ func main() {
3537
}
3638
log.Println("Registered extension, ID:", extensionClient.ExtensionID)
3739

38-
// Create a logsApiClient, start it & remember to shut it down when we're done
39-
logsApiClient, err := logsapi.NewClient(logsapi.Options{
40-
ExtensionID: extensionClient.ExtensionID,
41-
LogServerAddress: "sandbox:1234",
42-
})
43-
if err != nil {
44-
panic(err)
40+
// In legacy mode, we use the logs API. Otherwise, we use the new proxy client.
41+
if isLegacy, err := strconv.ParseBool(os.Getenv("FIRETAIL_EXTENSION_LEGACY")); err == nil && isLegacy {
42+
// Create a logsApiClient, start it & remember to shut it down when we're done
43+
logsApiClient, err := logsapi.NewClient(logsapi.Options{
44+
ExtensionID: extensionClient.ExtensionID,
45+
LogServerAddress: "sandbox:1234",
46+
})
47+
if err != nil {
48+
panic(err)
49+
}
50+
go logsApiClient.Start(ctx)
51+
defer logsApiClient.Shutdown(ctx)
52+
} else {
53+
firetailApiUrl, firetailApiUrlSet := os.LookupEnv("FIRETAIL_API_URL")
54+
if !firetailApiUrlSet {
55+
firetailApiUrl = logsapi.DefaultFiretailApiUrl
56+
}
57+
proxyServer, err := proxy.NewProxyServer()
58+
if err != nil {
59+
panic(err)
60+
}
61+
go proxyServer.ListenAndServe()
62+
defer proxyServer.Shutdown(ctx)
63+
go firetail.RecordReceiver(
64+
proxyServer.RecordsChannel,
65+
logsapi.DefaultMaxBatchSize,
66+
firetailApiUrl,
67+
os.Getenv("FIRETAIL_API_TOKEN"),
68+
)
4569
}
46-
go logsApiClient.Start(ctx)
47-
defer logsApiClient.Shutdown(ctx)
4870

4971
// awaitShutdown will block until a shutdown event is received, or the context is cancelled
5072
reason, err := awaitShutdown(extensionClient, ctx)

0 commit comments

Comments
 (0)