github.com/mweagle/Sparta@v1.15.0/aws/cloudwatch/logs/util.go (about) 1 package cloudwatchlogs 2 3 import ( 4 "time" 5 6 "github.com/aws/aws-sdk-go/aws" 7 "github.com/aws/aws-sdk-go/aws/session" 8 "github.com/aws/aws-sdk-go/service/cloudwatchlogs" 9 "github.com/sirupsen/logrus" 10 ) 11 12 func tailParams(logGroupName string, filter string, lastEvent int64) *cloudwatchlogs.FilterLogEventsInput { 13 params := &cloudwatchlogs.FilterLogEventsInput{ 14 LogGroupName: aws.String(logGroupName), 15 } 16 if filter != "" { 17 params.FilterPattern = aws.String(filter) 18 } 19 if lastEvent != 0 { 20 params.StartTime = aws.Int64(lastEvent) 21 } 22 return params 23 } 24 25 // TailWithContext is a utility function that support tailing the given log stream 26 // name using the optional filter. It returns a channel for log messages 27 func TailWithContext(reqContext aws.Context, 28 closeChan chan bool, 29 awsSession *session.Session, 30 logGroupName string, 31 filter string, 32 logger *logrus.Logger) <-chan *cloudwatchlogs.FilteredLogEvent { 33 34 // Milliseconds... 35 lastSeenTimestamp := time.Now().Add(0).Unix() * 1000 36 logger.WithField("TS", lastSeenTimestamp).Debug("Started polling") 37 outputChannel := make(chan *cloudwatchlogs.FilteredLogEvent) 38 tailHandler := func(res *cloudwatchlogs.FilterLogEventsOutput, lastPage bool) bool { 39 maxTime := int64(0) 40 for _, eachEvent := range res.Events { 41 if maxTime < *eachEvent.Timestamp { 42 maxTime = *eachEvent.Timestamp 43 } 44 logger.WithField("ID", *eachEvent.EventId).Debug("Event") 45 outputChannel <- eachEvent 46 } 47 if maxTime != 0 { 48 lastSeenTimestamp = maxTime + 1 49 } 50 return !lastPage 51 } 52 53 cwlogsSvc := cloudwatchlogs.New(awsSession) 54 tickerChan := time.NewTicker(time.Millisecond * 333).C //AWS cloudwatch logs limit is 5tx/sec 55 go func() { 56 for { 57 select { 58 case <-closeChan: 59 logger.Debug("Exiting polling loop") 60 return 61 case <-tickerChan: 62 logParam := tailParams(logGroupName, filter, lastSeenTimestamp) 63 error := cwlogsSvc.FilterLogEventsPagesWithContext(reqContext, logParam, tailHandler) 64 if error != nil { 65 // Just pump the thing back through the channel... 66 errorEvent := &cloudwatchlogs.FilteredLogEvent{ 67 EventId: aws.String("N/A"), 68 Message: aws.String(error.Error()), 69 Timestamp: aws.Int64(time.Now().Unix() * 1000), 70 } 71 outputChannel <- errorEvent 72 } 73 } 74 } 75 }() 76 return outputChannel 77 }