Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python/Boto - Writing to AWS CloudWatch Logs without sequence token

I am trying to send logs to AWS CloudWatch Logs using Python and Boto framework. I am doing this:

res=logs.put_log_events("FOO", "BAR",
     [{'timestamp':int(round(time.time() * 1000)),
       'message':time.strftime("%m/%d/%Y %H:%M:%S")+' Scheduled  monitoring check' }], 
     sequence_token=None)

I get an error each time I run:

boto.logs.exceptions.InvalidSequenceTokenException: InvalidSequenceTokenException: 400 Bad Request
{u'message': u'The given sequenceToken is invalid. The next expected sequenceToken is: 49540113336360065754596906019042392283494234157161146226', u'expectedSequenceToken': u'49540113336360065754596906019042392283494234157161146226', u'__type': u'InvalidSequenceTokenException'}

It is somewhat impractical for me to store that token. It makes no sense, why can't I just append to the log stream ?

How can I get around this ?

like image 328
Oleg Dulin Avatar asked Jun 17 '15 17:06

Oleg Dulin


People also ask

How do I automate CloudWatch logs?

To send action output to CloudWatch Logs (console)Open the AWS Systems Manager console at https://console.aws.amazon.com/systems-manager/ . In the navigation pane, choose Automation. Choose the Preferences tab, and then choose Edit. Select the check box next to Send output to CloudWatch Logs.


2 Answers

AWS Cloud Watch Putlogevent code

import boto3
import time


client = boto3.client('logs')

LOG_GROUP='cloudwatch_customlog'
LOG_STREAM='{}-{}'.format(time.strftime('%Y-%m-%d'),'logstream')

try:
   client.create_log_group(logGroupName=LOG_GROUP)
except client.exceptions.ResourceAlreadyExistsException:
   pass

try:
   client.create_log_stream(logGroupName=LOG_GROUP, logStreamName=LOG_STREAM)
except client.exceptions.ResourceAlreadyExistsException:
   pass

response = client.describe_log_streams(
   logGroupName=LOG_GROUP,
   logStreamNamePrefix=LOG_STREAM
)

event_log = {
   'logGroupName': LOG_GROUP,
   'logStreamName': LOG_STREAM,
   'logEvents': [
       {
           'timestamp': int(round(time.time() * 1000)),
           'message': time.strftime('%Y-%m-%d %H:%M:%S')+'\t Your custom log messages'
       }
   ],
}

if 'uploadSequenceToken' in response['logStreams'][0]:
   event_log.update({'sequenceToken': response['logStreams'][0] ['uploadSequenceToken']})

response = client.put_log_events(**event_log)
print(response)
like image 135
sarath kumar Avatar answered Sep 21 '22 23:09

sarath kumar


Though most answers here work, BUT.. If you have multiple processes that write to the same stream really fast, they'll get the exception all the time, and if you put it in a loop, the same race condition applies. Everyone should be aware of that!

like image 45
marcellsimon Avatar answered Sep 23 '22 23:09

marcellsimon