boto3 icon indicating copy to clipboard operation
boto3 copied to clipboard

Missing expectedSequenceToken property in InvalidSequenceTokenException when calling CloudWatch put_log_events

Open dnlprplt opened this issue 7 years ago • 4 comments

Hi,

The following is an excerpt from our code where we are putting log events in CloudWatch. Whenever the sequence token is invalid the InvalidSequenceTokenException is raised.

I am expecting this exception to hold the next valid sequence token. But as far as I can tell, it doesn't contain the expectedSequenceToken property.

` try:

        client = log_client()

        if sequence_token:
            response = client.put_log_events(logStreamName=log_stream,
                                             logGroupName=log_group_name,
                                             sequenceToken=sequence_token,
                                             logEvents=log_events)
        else:
            response = client.put_log_events(logStreamName=log_stream,
                                             logGroupName=log_group_name,
                                             logEvents=log_events)

    except (client.exceptions.InvalidSequenceTokenException,
            client.exceptions.DataAlreadyAcceptedException) as exception:

        LOGGER.info('%s', json.dumps(exception.response))

        sequence_token = exception.response['expectedSequenceToken']

        LOGGER.info('Put log events failed. Trying with returned sequence token: %s',
                    sequence_token)

        response = client.put_log_events(logStreamName=log_stream,
                                         logGroupName=log_group_name,
                                         sequenceToken=sequence_token,
                                         logEvents=log_events)

`

The response output is as follows. It does contain the next valid sequence token as part of the message. But I'd appreciate if there was a dedicated property to hold the value.

{ "Error": { "Message": "The given sequenceToken is invalid. The next expected sequenceToken is: 49586360281911722480461522616484155674142469117630813186", "Code": "InvalidSequenceTokenException" }, "ResponseMetadata": { "RequestId": "ef8bbbef-b81b-11e8-96ea-ed047286006c", "HTTPStatusCode": 400, "HTTPHeaders": { "x-amzn-requestid": "ef8bbbef-b81b-11e8-96ea-ed047286006c", "content-type": "application/x-amz-json-1.1", "content-length": "266", "date": "Fri, 14 Sep 2018 12:44:35 GMT", "connection": "close" }, "RetryAttempts": 0 } }

The HTTP API returns the expectedSequenceToken as shown in the debug logs of the CLI here:

2018-08-28 10:15:28,315 - MainThread - botocore.parsers - DEBUG - Response body: b'{"__type":"InvalidSequenceTokenException","expectedSequenceToken":"49587586260383644776994940668591089983175064596957435266","message":"The given sequenceToken is invalid. The next expected sequenceToken is: 49587586260383644776994940668591089983175064596957435266"}'

Is there a way to retrieve the expectedSequenceToken from the exception or a workaround? Currently, I plan to parse the message property and hope its format never changes.

Note that using describe_log_stream is not an option due to the low rate limit applied on that API.

Your help would be much appreciated.

dnlprplt avatar Sep 14 '18 13:09 dnlprplt

Boto3 doesn't support parsing additional parameters from exceptions, it only adds a Code and a Message. Labeling as a feature request, I think this is something we should add, but for now your best workaround would be to parse the error message.

jamesls avatar Sep 17 '18 19:09 jamesls

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/logs.html#CloudWatchLogs.Client.put_log_events says

You can also get the sequence token in the expectedSequenceToken field from InvalidSequenceTokenException .

Is this fixed?

zjiekai avatar Sep 16 '20 09:09 zjiekai

I can see that now we have 'expectedSequenceToken' in 'response' field:

ipdb> print(json.dumps(exc.response, indent=2))
{
  "Error": {
    "Message": "The given sequenceToken is invalid. The next expected sequenceToken is: 49610127944015239820552827234191336649719443806369856978",
    "Code": "InvalidSequenceTokenException"
  },
  "ResponseMetadata": {
    "RequestId": "1482884d-6b6b-40b1-a1b3-c77cf3a8bb1a",
    "HTTPStatusCode": 400,
    "HTTPHeaders": {
      "x-amzn-requestid": "1482884d-6b6b-40b1-a1b3-c77cf3a8bb1a",
      "content-type": "application/x-amz-json-1.1",
      "content-length": "266",
      "date": "Fri, 20 Nov 2020 16:51:30 GMT",
      "connection": "close"
    },
    "RetryAttempts": 0
  },
  "expectedSequenceToken": "49610127944015239820552827234191336649719443806369856978"
}

The question is can we rely on it? @jamesls do you think using this field would be an acceptable solution?

demosito avatar Nov 20 '20 16:11 demosito

Following up on @demosito's question on is this defined behaviour now?

NathanRoseCE avatar Jul 25 '22 16:07 NathanRoseCE

As previously mentioned this now appears to be addressed per the PutLogEvents API documentation so I will close this issue. Please let us know if there's any other feedback regarding this.

tim-finnigan avatar Nov 18 '22 19:11 tim-finnigan