in util/awsservice/cloudwatchlogs.go [79:134]
func GetLogsSince(logGroup, logStream string, since, until *time.Time) ([]types.OutputLogEvent, error) {
var events []types.OutputLogEvent
// https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_GetLogEvents.html
// GetLogEvents can return an empty result while still having more log events on a subsequent page,
// so rather than expecting all the events to show up in one GetLogEvents API call, we need to paginate.
params := &cloudwatchlogs.GetLogEventsInput{
LogGroupName: aws.String(logGroup),
LogStreamName: aws.String(logStream),
StartFromHead: aws.Bool(true), // read from the beginning
}
if since != nil {
params.StartTime = aws.Int64(since.UnixMilli())
}
if until != nil {
params.EndTime = aws.Int64(until.UnixMilli())
}
var nextToken *string
attempts := 0
for {
if nextToken != nil {
params.NextToken = nextToken
}
output, err := CwlClient.GetLogEvents(ctx, params)
attempts += 1
if err != nil {
if errors.As(err, &rnf) && attempts <= StandardRetries {
// The log group/stream hasn't been created yet, so wait and retry
time.Sleep(30 * time.Second)
continue
}
// if the error is not a ResourceNotFoundException, we should fail here.
return events, err
}
for _, e := range output.Events {
events = append(events, e)
}
if nextToken != nil && output.NextForwardToken != nil && *output.NextForwardToken == *nextToken {
// From the docs: If you have reached the end of the stream, it returns the same token you passed in.
log.Printf("Done paginating log events for %s/%s and found %d logs", logGroup, logStream, len(events))
break
}
nextToken = output.NextForwardToken
}
return events, nil
}