How to send EKS logs to AWS OpenSearch by Fluent-Bit

Julien Chen
4 min readJul 31, 2024

--

We know Kubernetes usually does not persist data. We needs to find a place to store application logs. If you are using AWS EKS. CloudWatch is an official suggestion. But recently I got a system it have to store in AWS OpenSearch. Not much information I can find related to it. So, I want to document how I set up the whole app log flow for me or someone’s reference in the future.

Log Flow

The whole app log flow is pod stdout → Fluent-Bit → AWS Kinesis Data Stream → AWS Data Firehose → AWS OpenSearch

The app-log flow

As I know Fluent-Bit can send app-logs to OpenSearch directly. But if you have a lot of application and traffic. You should consider using Kinesis Data Streams & Dta Firehose in the middle to be the buffer.

Fluent-Bit

You can follow the AWS document to install Fluent-Bit into your EKS. https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-logs-FluentBit.html
Please modify the k8s resource template .yaml file according your requirement to deploy it.

ConfigMap fluent-bit-config

application-log.conf & parsers.conf. [OUTPUT] kinesis and [PARSER] regex are important.

For linux

apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/name: fluentbit
name: fluent-bit-config
namespace: mts-infra
data:
fluent-bit.conf: |
[SERVICE]
Flush 5
Grace 30
Log_Level error
Daemon off
Parsers_File parsers.conf
HTTP_Server ${HTTP_SERVER}
HTTP_Listen 0.0.0.0
HTTP_Port ${HTTP_PORT}
storage.path /var/fluent-bit/state/flb-storage/
storage.sync normal
storage.checksum off
storage.backlog.mem_limit 5M

@INCLUDE application-log.conf

application-log.conf: |
[INPUT]
Name tail
Tag application.*
Exclude_Path /var/log/containers/cloudwatch-agent*, /var/log/containers/fluent-bit*, /var/log/containers/aws-node*, /var/log/containers/kube-proxy*
Path /var/log/containers/*.log
multiline.parser docker, cri
DB /var/fluent-bit/state/flb_container.db
Mem_Buf_Limit 50MB
Skip_Long_Lines On
Refresh_Interval 10

[FILTER]
Name grep
Match *
Regex log loggly

[FILTER]
Name parser
Match **
Parser loggly
Key_Name log
Reserve_Data On

[FILTER]
Name record_modifier
Match *
Remove_key stream

[OUTPUT]
Name kinesis
Match **
region ${AWS_REGION}
stream ${MY_APP_LOG}
append_newline true

parsers.conf: |
[PARSER]
Name docker
Format json
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L
Time_Keep On

[PARSER]
Name loggly
Format regex
Regex ^(?<time>\d{4}-\d{2}-\d{2}\S\d{2}:\d{2}:\d{2}(\.\d*)?\S)([^\|])*(?<logtime>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}(\.\d*)?)\|(?<levelname>[^|].+)\|(?<name>[^|].+)\|(?<filename>[^|].+)\|(?<lineno>[^|].+)\|(?<module>[^|].+)\|(?<funcName>[^|].+)\|(?<processName>[^|].+)\|(?<threadName>[^|].+)\|(?<messageinfo>[^|].+)\|(?<hostname>.*)\|(?<uuid>.*)\|(?<elapsed>.*)
Time_Format %Y-%m-%d %H:%M:%S.%L
Time_Keep On
Time_Key logtime

For windows

apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-windows-config
namespace: mts-infra
labels:
k8s-app: fluent-bit
data:
fluent-bit.conf: |
[SERVICE]
Flush 5
Log_Level error
Daemon off
net.dns.resolver LEGACY
Parsers_File parsers.conf

@INCLUDE application-log.conf

application-log.conf: |
[INPUT]
Name tail
Tag application.*
Exclude_Path C:\\var\\log\\containers\\fluent-bit*, C:\\var\\log\\containers\\cloudwatch-agent*
Path C:\\var\\log\\containers\\*.log
Parser docker
DB C:\\var\\fluent-bit\\state\\flb_container.db
Mem_Buf_Limit 5MB
Skip_Long_Lines On
Rotate_Wait 30

[FILTER]
Name grep
Match *
Regex log loggly

[FILTER]
Name parser
Match **
Parser loggly
Key_Name log
Reserve_Data On

[FILTER]
Name record_modifier
Match *
Remove_key stream

[OUTPUT]
Name kinesis
Match application.*
region ${AWS_REGION}
stream ${MY_APP_LOG}
append_newline true

parsers.conf: |
[PARSER]
Name docker
Format json
Time_Key time
Time_Format %b %d %H:%M:%S

[PARSER]
Name loggly
Format regex
Regex ^(?<time>\d{4}-\d{2}-\d{2}\S\d{2}:\d{2}:\d{2}(\.\d*)?\S)([^\|])*(?<logtime>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}(\.\d*)?)\|(?<levelname>[^|].+)\|(?<name>[^|].+)\|(?<filename>[^|].+)\|(?<lineno>[^|].+)\|(?<module>[^|].+)\|(?<funcName>[^|].+)\|(?<processName>[^|].+)\|(?<threadName>[^|].+)\|(?<messageinfo>[^|].+)\|(?<hostname>.*)\|(?<uuid>.*)\|(?<elapsed>.*)
Time_Format %Y-%m-%d %H:%M:%S.%L
Time_Keep On
Time_Key logtime

time & logtime fields are important index patterns for OpenSearch.
The regex match result of logtime Time_Format needs to be matched with the [PARSER] loggly Time_Key of fluent-bit-config %Y-%m-%d %H:%M:%S.%L

Regex

You can test your regex here https://rubular.com/
Make sure your log can be matched your regex like below.

match groups

IAM

Make sure you have attached corresponding AWS resource policy. Otherwise you will see unauthorized error logs in fluent-bit pods.

kinesis:PutRecords unauthorized logs

AWS Kinesis Data Stream

Create a data stream ${MY_APP_LOG} there

create data stream

AWS Data Firehose

Create Firehose stream and set data source & destination.

create firehose stream

AWS OpenSearch

Security / Roles / all_access / Map user

Click Manage mapping to add the backend role in Security/Roles/all_access

manage mapping
map user

If you do not set it right, you will see this Destination error logs in AWS Data Firehose

Stack Management / Index patterns

Create Index patterns for your app log

Discover

If everything set up right, you should see your app log index in Discover

app-logs index in discover

Dev Tools

You can use GET /{your-index}/_search?q= to check your app-logs are stored in OpenSearch or not.

If everything is right, you can see the response like below

right regex

If your app-logs are stored in OpenSearch but the Regex set up wrong, the response will be like…

wrong regex

Please double check the Regex of fluent-bit-config configmap.
time & logtime fields are the important index patterns.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response