我有一个php工作程序,我可以在其中将事件记录到AWS。不幸的是,我在尝试提交时出现了以下错误。
InvalidSequenceTokenException在上执行"PutLogEvents"时出错"https://logs.eu-west-1.amazonaws.com";AWS HTTP错误:客户端错误:
POST https://logs.eu-west-1.amazonaws.com
导致400 Bad Request
响应:{"__type":"InvalidSequenceTokenException","expectedSequenceToken":"99999999999999 0356407851919528174(已截断…)InvalidSequenceTokenException(客户端):给定sequenceToken无效。下一个预期的sequenceToken是:495599999999988500356407851919528174642-{"__type":"InvalidSequenceTokenException","expectedSequenceToken":"495573099999999900356407851919528174642","message":"给定的sequenceToken无效。下一个预期的sequenceToken是:495579999999900356407851919528174642"}
这是我的代码
$date = new DateTime();
$instance= = new CloudWatchLogsClient([
'region' => 'eu-west-1',
'version' => 'latest',
'credentials' => [
'key' => 'XXX',
'secret' => 'XXXX'
]
]);
$instance->putLogEvents([
'logGroupName' => "WorkerLog",
'logStreamName' => "log",
'logEvents' => [
[
'timestamp' => $date->getTimestamp(),
'message' => "test log"
]
]
]);
http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html
您必须在请求中包含序列令牌。如果没有,则必须使用describeLogStreams(http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogStreams.html)以获得流序列。
当您调用putLogEvents时,您将在响应中获得nextToken。您还必须为其他人推送到流并使nextToken无效的情况做好准备。(在这种情况下,您需要再次描述流以获得更新的令牌)。
DescribeLogStreams
不支持与PutLogEvent
相同的卷调用。如果经常打电话,你可能会被抑制。
推荐的方法是直接调用PutLogEvents
并捕获InvalidSequenceTokenException
。然后重试InvalidSequenceTokenException
消息中的带有序列令牌的PutLogEvents
。
在InvalidSequenceTokenException
的expectedSequenceToken字段中可以找到正确的序列令牌
try {
$result = $client->describeLogStreams([
'logGroupName' => $logGroupName,
'logStreamNamePrefix' => $logStreamName,
]);
$uploadSequenceToken = $logStreams[0]['uploadSequenceToken'];
$client->putLogEvents([
'logGroupName' => $logGroupName,
'logStreamName' => $logStreamName,
'logEvents' => [
[
'timestamp' => $timestamp,
'message' => $message
],
],
'sequenceToken' => $uploadSequenceToken,
]);
} catch ('InvalidSequenceTokenException $e) {
$client->putLogEvents([
'logGroupName' => $logGroupName,
'logStreamName' => $logStreamName,
'logEvents' => [
[
'timestamp' => $timestamp,
'message' => $message
],
],
'sequenceToken' => $e->expectedSequenceToken,
]);
}
这是我的工作解决方案:在发送新的putLogEvents之前,您必须获取最后一个uploadSequenceToken。
try {
$client = 'Aws'CloudWatchLogs'CloudWatchLogsClient::factory($configCloudWatch);
$logStreamName = 'testLogStream';
$logGroupName = 'testGroupName';
$result = $client->describeLogStreams([
'logGroupName' => $logGroupName,
'logStreamNamePrefix' => $logStreamName,
]);
$logStreams=$result->get('logStreams');
if (!$logStreams)
throw new 'Exception('No log stream found');
if (count($logStreams)!=1)
throw new 'Exception('Multiple log stream found');
$uploadSequenceToken = $logStreams[0]['uploadSequenceToken'];
$client->putLogEvents([
'logGroupName' => $logGroupName,
'logStreamName' => $logStreamName,
'logEvents' => [
[
'timestamp' => round(microtime(true) * 1000),
// message is required
'message' => json_encode([ ... ]
),
],
],
'sequenceToken' => $uploadSequenceToken,
]);
} catch ('Exception $e) {
'Log::error(__METHOD__, ['exception' => $e]);
}