diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index d2eaa45..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Go - -on: - pull_request: - branches: [ master ] - -jobs: - - build: - name: Build - runs-on: ubuntu-latest - steps: - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Dockerfile build & test - run: docker build -t lambda . - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-west-1 - - - name: Validate cloudformtion template - run: aws cloudformation validate-template --template-body file://cloudformation.yaml diff --git a/.github/workflows/production-release.yml b/.github/workflows/production-release.yml deleted file mode 100644 index 679ce45..0000000 --- a/.github/workflows/production-release.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Go - -on: - release: - types: - - created - -jobs: - - prod-deploy: - name: Production-Deploy - runs-on: ubuntu-latest - steps: - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Dockerfile build & test - run: docker build -t lambda . - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-west-1 - - - name: Validate cloudformtion template - run: aws cloudformation validate-template --template-body file://cloudformation.yaml - - - name: Deploying cloudformation.yaml to production - run: aws s3 cp cloudformation.yaml s3://lm-logs-forwarder/latest.yaml - - - name: Creating lambda zip - run: id=$(docker create lambda) && docker cp $id:/code/lambda.zip lambda.zip && docker rm -f $id - - - name: Deploying lambda to production - run: aws s3 cp lambda.zip s3://lm-logs-forwarder/source/1.0.0/ && rm lambda.zip \ No newline at end of file diff --git a/.github/workflows/staging-master.yml b/.github/workflows/staging-master.yml deleted file mode 100644 index 578c53e..0000000 --- a/.github/workflows/staging-master.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Go - -on: - push: - branches: [ master ] - -jobs: - - staging-deploy: - name: Staging-Deploy - runs-on: ubuntu-latest - steps: - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Dockerfile build & test - run: docker build -t lambda . - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-west-1 - - - name: Validate cloudformtion template - run: aws cloudformation validate-template --template-body file://cloudformation.yaml - - - name: Deploying cloudformation.yaml to staging - run: aws s3 cp cloudformation.yaml s3://lm-logs-forwarder/staging/latest.yaml - - - name: Creating lambda zip - run: id=$(docker create lambda) && docker cp $id:/code/lambda.zip lambda.zip && docker rm -f $id - - - name: Deploying lambda to staging - run: aws s3 cp lambda.zip s3://lm-logs-forwarder/staging/code/1.0.0/ && rm lambda.zip - - - name: Update lambda on QAUAT - run: aws lambda update-function-code --function-name LMLogsForwarderQAUAT --s3-bucket lm-logs-forwarder --s3-key staging/code/1.0.0/lambda.zip \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 10a8270..4911c36 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.19-alpine as base +FROM golang:1.24-alpine as base ENV GOOS linux ENV GOARCH amd64 ENV CGO_ENABLED 0 @@ -9,16 +9,16 @@ RUN go mod download COPY code/* /code/ FROM base as build -RUN go build -o main *.go \ - && zip lambda.zip main +RUN go build -o bootstrap *.go \ + && zip lambda.zip bootstrap FROM base as test RUN go test RUN wget -O- -nv 'https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh' \ - | sh -s -- -b "$(go env GOPATH)/bin" 'v1.49.0' + | sh -s -- -b "$(go env GOPATH)/bin" 'v1.62.2' RUN golangci-lint run . FROM alpine as release WORKDIR /code COPY --from=build /code/lambda.zip /code/ -VOLUME /code \ No newline at end of file +VOLUME /code diff --git a/README.md b/README.md index b6f8b99..e0655dd 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,12 @@ You will need to supply the following LogicMonitor credentials when configuring * LM Access ID * LM Access Key * LM Account Name +* LM Account Domain + +**NOTE**: If the LM Account Domain is not specified, it defaults to "logicmonitor.com". ### Deploying lambda using CloudFormation -[![Launch Stack](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?stackName=lm-forwarder&templateURL=https://logicmonitor-logs-forwarder.s3.amazonaws.com/source/latest.yaml) +[![Launch Stack](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?stackName=lm-forwarder&templateURL=https://logicmonitor-logs-forwarder.s3.us-west-1.amazonaws.com/source/latest.yaml) ### Deploying lambda using Terraform **Sample configuration** @@ -27,6 +30,10 @@ variable "lm_company_name" { description = "LogicMonitor Account Name" } +variable "lm_company_domain" { + description = "LogicMonitor Account Domain" +} + # LogicMonitor Logs forwarder resource "aws_cloudformation_stack" "lm_forwarder" { name = "lm-forwarder" @@ -36,13 +43,14 @@ resource "aws_cloudformation_stack" "lm_forwarder" { LMAccessId = var.lm_access_id LMAccessKey = var.lm_access_key LMCompanyName = var.lm_company_name + LMCompanyDomain = var.lm_company_domain LMRegexScrub = "" PermissionsBoundaryArn = "" } - template_url = "https://lm-logs-forwarder-v2.s3.amazonaws.com/latest.yaml" + template_url = "https://logicmonitor-logs-forwarder.s3.us-west-1.amazonaws.com/source/latest.yaml" } ``` -`terraform apply --var 'lm_access_id=' --var 'lm_access_key=' --var 'lm_company_name='` +`terraform apply --var 'lm_access_id=' --var 'lm_access_key=' --var 'lm_company_name=' --var 'lm_company_domain='` ### Forwarding EC2 Instances logs Forward EC2 logs to CloudWatch, using the [CloudWatch Logs Agent](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/QuickStartEC2Instance.html). @@ -77,6 +85,21 @@ To send Lambda logs to LogicMonitor, go to cloudwatch and find lambda's log grou 1. Go to Cloudwatch, select the lambda's log group of which you want to forward logs , under Actions > Create Lambda subscription filter 2. In Create Lambda subscription filter , select "Lambda Function" and choose "LMLogsForwarder" (or, whatever you named the Lambda function during stack creation) and click Start streaming. +### Forwarding EKS logs +Add an "Amazon CloudWatch Observability" plugin to existing or new cluster, OR +Forward EKS logs to cloudwatch using [application metrics to cloudwatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-metrics.html) and [application logs to cloudwatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-EKS-logs.html) using [Fluenbit](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-logs-FluentBit.html) + +These steps create 5 different log groups into cloudwatch as below: +1. /aws/containerInsights//application +2. /aws/containerInsights//host +3. /aws/containerInsights//performance +4. /aws/containerInsights//dataplane +5. /aws/eks//cluster + +To forward EKS logs to LogicMonitor, follow these steps for the specific log group you want to send: +1. Go to Cloudwatch, select the EKS's log group of which you want to forward logs , under Actions > Create Lambda subscription filter +2. In Create Lambda subscription filter , select "Lambda Function" and choose "LMLogsForwarder" (or, whatever you named the Lambda function during stack creation) and click Start streaming. + ### Send flow logs from EC2 1. Add below lines in permissions of lambda's role policy: "logs:CreateLogGroup", @@ -143,117 +166,104 @@ As these logs are filtered from Cloudtrail, all the Cloudtrail steps needs to be ### Send ELB flow logs ELB flow logs to ECS: -1. Add below lines in permissions of lambda's role policy: - "logs:CreateLogGroup", - "logs:CreateLogStream", - "logs:PutLogEvents" - -2. Add below line in the Trust Relationship part of the role in the Service tag: - "vpc-flow-logs.amazonaws.com" - -3. A Log group in cloud watch should be created with name /aws/elb/networkInterface - -4. Use your ELB name to search in Network interfaces page. Select that Network interface row and create a flow log. In create flow log Destination log group should be /aws/elb/networkInterface and IAM role should be the role created in 1st and 2nd step. - -5. Go to /aws/elb/networkInterface log group. In Actions > Subscription filters > Create lambda subscription filter. In lambda function select “LMLogsForwarder” (or whatever you named the Lambda function during stack creation) and provide Subscription filter name. Hit Start Streaming. - -6. Logs will start to propagate through lambda to LogIngest. - ### Send RDS logs -RDS logs to ECS: - -1. Add below lines in permissions of lambda's role policy: +1.Add below lines in permissions of lambda's role policy: "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" 2. Add below line in the Trust Relationship part of the role in the Service tag: "vpc-flow-logs.amazonaws.com" - 3. A Log group in cloud watch should be created with name /aws/rds/networkInterface - 4. Use your RDS instance private IP address to search in Network interfaces page. Select that Network interface row and create a flow log. In create flow log Destination log group should be /aws/rds/networkInterface and IAM role should be the role created in 1st and 2nd step. - 5. Go to /aws/rds/networkInterface log group. In Actions > Subscription filters > Create lambda subscription filter. In lambda function select “LMLogsForwarder” (or whatever you named the Lambda function during stack creation) and provide Subscription filter name. Hit Start Streaming. - 6. Logs will start to propagate through lambda to LogIngest. -### Send Fargate logs -Fargate logs of ECS: - -1. Go to Task defination that you are using with your service in ECS cluster - -2. It should have "awslogs-group" as key and "/aws/fargate" as value in Container definition section of Task definition. If you are adding to already existing task definition than create new revision of Task definition and update Service in ECS cluster. Else if creating a new Task defination then make sure to attach it to Service in ECS cluster. - -3. Go to /aws/fargate log group. In Actions > Subscription filters > Create lambda subscription filter. In lambda function select “LMLogsForwarder” (or whatever you named the Lambda function during stack creation) and provide Subscription filter name. Hit Start Streaming. - -4. Logs will start to propagate through lambda to LogIngest. - -Fargate logs from EKS: - -1. Create a dedicated Kubernetes namespace named aws-observability. - -2. Save the following contents to a file named aws-observability-namespace.yaml on your computer. The value for name must be aws-observability and the aws-observability: enabled label is required. - -kind: Namespace -apiVersion: v1 -metadata: - name: aws-observability - labels: - aws-observability: enabled - - -3. Create the namespace. - -Save the following contents to a file named aws-logging-cloudwatch-configmap.yaml. Replace region-code with the AWS Region. The parameters under [OUTPUT] are required. - -kind: ConfigMap -apiVersion: v1 -metadata: - name: aws-logging - namespace: aws-observability -data: - output.conf: | - [OUTPUT] - Name cloudwatch_logs - Match * - region region-code - log_group_name fluent-bit-cloudwatch - log_stream_prefix from-fluent-bit- - auto_create_group true - log_key log - - parsers.conf: | - [PARSER] - Name crio - Format Regex - Regex ^(?