Last active
October 4, 2021 12:09
-
-
Save metachris/d713082d5269e8a30aa270eb5c148eb1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Example for using CloudWatch in Golang. | |
- https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html | |
- https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/working_with_metrics.html | |
Install dependencies: | |
go get github.com/aws/aws-sdk-go github.com/google/uuid github.com/zhexuany/wordGenerator | |
Run this code: | |
go run . | |
This code will generate some metrics, creates a logGroup and stream logs all few seconds. | |
*/ | |
package main | |
import ( | |
"fmt" | |
"log" | |
"sync" | |
"time" | |
"github.com/aws/aws-sdk-go/aws" | |
"github.com/aws/aws-sdk-go/aws/session" | |
"github.com/aws/aws-sdk-go/service/cloudwatch" | |
"github.com/aws/aws-sdk-go/service/cloudwatchlogs" | |
"github.com/google/uuid" | |
"github.com/zhexuany/wordGenerator" | |
) | |
var ( | |
cwl *cloudwatchlogs.CloudWatchLogs | |
cw *cloudwatch.CloudWatch | |
logGroupName = "fooBarABCD" | |
logStreamName = "" | |
sequenceToken = "" | |
) | |
func init() { | |
sess, err := session.NewSessionWithOptions(session.Options{ | |
Config: aws.Config{ | |
Region: aws.String("sa-east-1"), | |
}, | |
}) | |
if err != nil { | |
panic(err) | |
} | |
// Setup CW logs | |
cwl = cloudwatchlogs.New(sess) | |
err = ensureLogGroupExists(logGroupName) | |
if err != nil { | |
panic(err) | |
} | |
// Setup CW metrics | |
cw = cloudwatch.New(sess) | |
} | |
func main() { | |
// Example of add some metrics | |
go addCloudWatchMetrics() | |
// Continuously add logs (random words) | |
go runWithCloudWatchLogs() | |
// to stop the code from exiting | |
wg := sync.WaitGroup{} | |
wg.Add(1) | |
wg.Wait() | |
} | |
func addCloudWatchMetrics() { | |
_, err := cw.PutMetricData(&cloudwatch.PutMetricDataInput{ | |
Namespace: aws.String("Site/Traffic"), | |
MetricData: []*cloudwatch.MetricDatum{ | |
&cloudwatch.MetricDatum{ | |
MetricName: aws.String("UniqueVisitors"), | |
Unit: aws.String("Count"), | |
Value: aws.Float64(5885.0), | |
Dimensions: []*cloudwatch.Dimension{ | |
&cloudwatch.Dimension{ | |
Name: aws.String("SiteName"), | |
Value: aws.String("example.com"), | |
}, | |
}, | |
}, | |
&cloudwatch.MetricDatum{ | |
MetricName: aws.String("UniqueVisits"), | |
Unit: aws.String("Count"), | |
Value: aws.Float64(8628.0), | |
Dimensions: []*cloudwatch.Dimension{ | |
&cloudwatch.Dimension{ | |
Name: aws.String("SiteName"), | |
Value: aws.String("example.com"), | |
}, | |
}, | |
}, | |
&cloudwatch.MetricDatum{ | |
MetricName: aws.String("PageViews"), | |
Unit: aws.String("Count"), | |
Value: aws.Float64(18057.0), | |
Dimensions: []*cloudwatch.Dimension{ | |
&cloudwatch.Dimension{ | |
Name: aws.String("PageURL"), | |
Value: aws.String("my-page.html"), | |
}, | |
}, | |
}, | |
}, | |
}) | |
if err != nil { | |
fmt.Println("Error adding metrics:", err.Error()) | |
return | |
} | |
} | |
func runWithCloudWatchLogs() { | |
var logQueue []*cloudwatchlogs.InputLogEvent | |
for { | |
time.Sleep(time.Second * 3) | |
// Add a new word to the log queue | |
word := wordGenerator.GetWord(10) | |
fmt.Println(word) | |
logQueue = append(logQueue, &cloudwatchlogs.InputLogEvent{ | |
Message: &word, | |
Timestamp: aws.Int64(time.Now().UnixNano() / int64(time.Millisecond)), | |
}) | |
// Create a CW log event from the input queue | |
input := cloudwatchlogs.PutLogEventsInput{ | |
LogEvents: logQueue, | |
LogGroupName: &logGroupName, | |
} | |
// Send to CW | |
if sequenceToken == "" { | |
err := createLogStream() | |
if err != nil { | |
panic(err) | |
} | |
} else { | |
input = *input.SetSequenceToken(sequenceToken) | |
} | |
input = *input.SetLogStreamName(logStreamName) | |
resp, err := cwl.PutLogEvents(&input) | |
if err != nil { | |
log.Println(err) | |
} | |
if resp != nil { | |
sequenceToken = *resp.NextSequenceToken | |
} | |
// Reset queue | |
logQueue = []*cloudwatchlogs.InputLogEvent{} | |
} | |
} | |
// ensureLogGroupExists first checks if the log group exists, | |
// if it doesn't it will create one. | |
func ensureLogGroupExists(name string) error { | |
resp, err := cwl.DescribeLogGroups(&cloudwatchlogs.DescribeLogGroupsInput{}) | |
if err != nil { | |
return err | |
} | |
for _, logGroup := range resp.LogGroups { | |
if *logGroup.LogGroupName == name { | |
return nil | |
} | |
} | |
_, err = cwl.CreateLogGroup(&cloudwatchlogs.CreateLogGroupInput{ | |
LogGroupName: &name, | |
}) | |
if err != nil { | |
return err | |
} | |
_, err = cwl.PutRetentionPolicy(&cloudwatchlogs.PutRetentionPolicyInput{ | |
RetentionInDays: aws.Int64(14), | |
LogGroupName: &name, | |
}) | |
return err | |
} | |
// createLogStream will make a new logStream with a random uuid as its name. | |
func createLogStream() error { | |
name := uuid.New().String() | |
_, err := cwl.CreateLogStream(&cloudwatchlogs.CreateLogStreamInput{ | |
LogGroupName: &logGroupName, | |
LogStreamName: &name, | |
}) | |
logStreamName = name | |
return err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment