Skip to content

Instantly share code, notes, and snippets.

@metachris
Last active October 4, 2021 12:09
Show Gist options
  • Save metachris/d713082d5269e8a30aa270eb5c148eb1 to your computer and use it in GitHub Desktop.
Save metachris/d713082d5269e8a30aa270eb5c148eb1 to your computer and use it in GitHub Desktop.
/*
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