Skip to content

Commit 54b52af

Browse files
Incorporating code review comments
1 parent 054bf8c commit 54b52af

File tree

3 files changed

+39
-28
lines changed

3 files changed

+39
-28
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ In this repository you will find a number of demos and sample projects from AWS
5555

5656
* [Demo: Logs to Amazon S3 extension: container image ](s3-logs-extension-demo-container-image/): Demo logs extension to receive logs directly from Lambda and send them to S3. This example packages the extension and function as separate container images. The demo is deployed using AWS SAM.
5757

58-
* [Demo: Logs to Kinesis firehose Logs API extension](kinesisfirehose-logs-extension-demo/): How to get a basic logs API extension for AWS Kinesis Firehose written in Go. The extension explains the overall approach to streamline and and centralize log collection using Kinesis firehose. The extension runs a local HTTP listener and subscribes to a stream of function and platform logs using the Logs API. It buffers them and sends them to Kinesis firehose periodically. The demo gets deployed using AWS SAM.
58+
* [Demo: Logs to Kinesis firehose Logs API extension](kinesisfirehose-logs-extension-demo/): How to get a basic logs API extension for Amazon Kinesis Data Firehose written in Go. The extension explains the overall approach to streamline and centralize log collection using Amazon Kinesis Data firehose. The extension runs a local HTTP listener and subscribes to a stream of function and platform logs using the Logs API. It buffers them and sends them to Amazon Kinesis Data firehose periodically, which streams logs to Amazon S3. The demo gets deployed using AWS SAM.
5959

6060
### Other extension examples
6161

kinesisfirehose-logs-extension-demo/README.md

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
# Centralize log collection with Kinesis Firehose using Lambda Extensions
1+
# Centralize log collection with Amazon Kinesis Data Firehose using Lambda Extensions
22

33
## Introduction
44

5-
This pattern walks through an approach to centralize log collection for lambda function with Kinesis firehose using external extensions. The provided code sample shows how to get send logs directly to kinesis firehose without sending them to AWS CloudWatch service.
5+
This pattern walks through an approach to centralize log collection for Lambda function with Kinesis firehose using external extensions. The provided code sample shows how to get send logs directly to Kinesis firehose without sending them to AWS CloudWatch service.
66

77
> Note: This is a simple example extension to help you investigate an approach to centralize the log aggregation. This example code is not production ready. Use it with your own discretion after testing thoroughly.
88
99
This sample extension:
1010

1111
* Subscribes to receive `platform` and `function` logs.
1212
* Runs with a main, and a helper goroutine: The main goroutine registers to `ExtensionAPI` and process its `invoke` and `shutdown` events. The helper goroutine:
13-
* starts a local HTTP server at the provided port (default 1234) that receives requests from Logs API with `NextEvent` method call
13+
* starts a local HTTP server at the provided port (default 1234, the port can be overridden with Lambda environment variable `HTTP_LOGS_LISTENER_PORT` ) that receives requests from Logs API with `NextEvent` method call
1414
* puts the logs in a synchronized queue (Producer) to be processed by the main goroutine (Consumer)
15-
* The main goroutine writes the received logs to AWS Kinesis firehose, which gets stored in AWS S3
15+
* The main goroutine writes the received logs to Amazon Kinesis firehose, which gets stored in Amazon S3
1616

1717
## Amazon Kinesis Data firehose
1818

@@ -31,24 +31,24 @@ Lambda Extensions, a new way to easily integrate Lambda with your favorite monit
3131

3232
read more about it [here](https://aws.amazon.com/blogs/compute/introducing-aws-lambda-extensions-in-preview/)
3333

34-
> Note: The code sample provided part of this pattern uses **external** extension to listen to log events from the lambda function
34+
> Note: The code sample provided part of this pattern uses **external** extension to listen to log events from the Lambda function
3535
3636
## Need to centralize log collection
3737

38-
Having a centralized log collection mechanism using kinesis firehose provides the following benefits:
38+
Having a centralized log collecting mechanism using Kinesis firehose provides the following benefits:
3939

40-
* Helps to collect logs from different sources in one place. Even though the sample provided sends logs from Lambda, log routers like `Fluentbit` and `Firelens` can send logs directly to kinesis firehose from container orchestrators like `EKS` and `ECS`.
40+
* Helps to collect logs from different sources in one place. Even though the sample provided sends logs from Lambda, log routers like `Fluentbit` and `Firelens` can send logs directly to Kinesis Data firehose from container orchestrators like `EKS` and `ECS`.
4141
* Define and standardize the transformations before the log gets delivered to downstream systems like S3, elastic search, redshift, etc
4242
* Provides a secure storage area for log data, before it gets written out to the disk. In the event of machine/application failure, we still have access to the logs emitted from the source machine/application
4343

4444
## Architecture
4545

4646
### AWS Services
4747

48-
* AWS Lambda
49-
* AWS Lambda extension
50-
* AWS KinesisFirehose
51-
* AWS S3
48+
* Amazon Lambda
49+
* Amazon Lambda extension
50+
* Amazon Kinesis Data Firehose
51+
* Amazon S3
5252

5353
### High level architecture
5454

@@ -64,7 +64,7 @@ Once deployed the overall flow looks like below:
6464

6565
> Note: Firehose stream name gets specified as an environment variable (`AWS_KINESIS_STREAM_NAME`)
6666
67-
* The lambda function won't be able to send any logs events to AWS CloudWatch service due to the following explict `DENY` policy:
67+
* The Lambda function won't be able to send any logs events to Amazon CloudWatch service due to the following explicit `DENY` policy:
6868

6969
```yaml
7070
Sid: CloudWatchLogsDeny
@@ -91,8 +91,9 @@ AWS SAM template available part of the root directory can be used for deploying
9191
Check out the code by running the following command:
9292

9393
```bash
94-
mkdir kinesisfirehose-logs-extension-demo && cd kinesisfirehose-logs-extension-demo
95-
git clone https://github.com/hariohmprasath/load-testing-serverless-apps.git .
94+
mkdir aws-lambda-extensions && cd aws-lambda-extensions
95+
git clone https://github.com/aws-samples/aws-lambda-extensions.git .
96+
cd kinesisfirehose-logs-extension-demo
9697
```
9798

9899
Run the following command from the root directory
@@ -128,7 +129,7 @@ Commands you can use next
128129

129130
### Deployment
130131

131-
Run the following command to deploy the sample lambda function with the extension
132+
Run the following command to deploy the sample Lambda function with the extension
132133

133134
```bash
134135
sam deploy --guided
@@ -183,7 +184,7 @@ aws lambda invoke \
183184
--log-type Tail
184185
```
185186

186-
>Note: Make sure to replace `function-name` with the actual lambda function name
187+
>Note: Make sure to replace `function-name` with the actual Lambda function name
187188

188189
The function should return ```"StatusCode": 200```, with the below output
189190

@@ -195,15 +196,15 @@ The function should return ```"StatusCode": 200```, with the below output
195196
}
196197
```
197198

198-
In a few minutes after the successfully invocation of the lambda function, we should start seeing the log messages from the example extension written to an S3 bucket.
199+
In a few minutes after the successful invocation of the Lambda function, we should start seeing the log messages from the example extension sent to Amazon Data Firehose which sends the messages to a Amazon S3 bucket.
199200

200201
* Login to AWS console:
201202
* Navigate to the S3 bucket mentioned under the parameter `BucketName` in the SAM output.
202-
* We can see the logs successly written to the S3 bucket, partitioned based on date in `GZIP` format.
203+
* We can see the logs successfully written to the S3 bucket, partitioned based on date in `GZIP` format.
203204
![s3](images/S3.png)
204205

205206
* Navigate to `"/aws/lambda/${functionname}"` log group inside AWS CloudWatch service.
206-
* We shouldn't see any logs created under this log group as we have denied access to write any logs from the lambda function.
207+
* We shouldn't see any logs created under this log group as we have denied access to write any logs from the Lambda function.
207208
![cloudwatch](images/CloudWatch.png)
208209

209210
## Cleanup

kinesisfirehose-logs-extension-demo/agent/http.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import (
1717
"github.com/golang-collections/go-datastructures/queue"
1818
)
1919

20-
// DefaultHttpListenerPort is used to set the URL where the logs will be sent by Logs API
21-
const DefaultHttpListenerPort = "1234"
20+
// HttpListenerPort - Env variable to override the default logs http listener port
21+
const HttpListenerPort = "HTTP_LOGS_LISTENER_PORT"
2222

2323
// LogsApiHttpListener is used to listen to the Logs API using HTTP
2424
type LogsApiHttpListener struct {
@@ -37,12 +37,13 @@ func NewLogsApiHttpListener(lq *queue.Queue) (*LogsApiHttpListener, error) {
3737
}
3838

3939
func ListenOnAddress() string {
40+
httpListenerPort:= listenerPort()
4041
env_aws_local, ok := os.LookupEnv("AWS_SAM_LOCAL")
4142
if ok && "true" == env_aws_local {
42-
return ":" + DefaultHttpListenerPort
43+
return ":" + httpListenerPort
4344
}
4445

45-
return "sandbox:" + DefaultHttpListenerPort
46+
return "sandbox.localdomain:" + httpListenerPort
4647
}
4748

4849
// Start initiates the server in a goroutine where the logs will be sent
@@ -143,12 +144,10 @@ func (a HttpAgent) Init(agentID string) error {
143144
MaxBytes: 262144,
144145
TimeoutMS: 1000,
145146
}
146-
if err != nil {
147-
return err
148-
}
147+
149148
destination := logsapi.Destination{
150149
Protocol: logsapi.HttpProto,
151-
URI: logsapi.URI(fmt.Sprintf("http://sandbox:%s", DefaultHttpListenerPort)),
150+
URI: logsapi.URI(fmt.Sprintf("http://sandbox.localdomain:%s", listenerPort())),
152151
HttpMethod: logsapi.HttpPost,
153152
Encoding: logsapi.JSON,
154153
}
@@ -166,3 +165,14 @@ func (a *HttpAgent) Shutdown() {
166165

167166
a.listener.Shutdown()
168167
}
168+
169+
func listenerPort() string{
170+
// Default listener port can be overridden by Lambda environment variable
171+
httpListenerPort := os.Getenv(HttpListenerPort)
172+
if httpListenerPort == "" {
173+
httpListenerPort = "1234"
174+
}
175+
176+
return httpListenerPort
177+
}
178+

0 commit comments

Comments
 (0)