Amazon Cloud Watch Log - PutLogEventsRequest - 给定的sequenceToken无效

afy*_*fym 6 java amazon-web-services amazon-cloudwatch aws-java-sdk

我正在使用Amazon Cloud Watch服务为我的应用程序构建一个小型日志跟踪器.这个想法不是跟踪文件的日志输出,而是使用aws控制台的搜索引擎来查找日志信息.

我在用:

  • Eclipse作为IDE
  • Java 8
  • 依赖关系:aws-java-sdk-core/aws-java-sdk-cloudwatch V 1.10.49

另一方面,我有以下AWS配置:

  • 访问和私钥
  • 地区:加州
  • 日志组:demo1
  • 日志流:stream1

我正在编写以下代码来进行简单的功能测试:

package com.test.pe.cloudwatch;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.logs.AWSLogsClient;
import com.amazonaws.services.logs.model.InputLogEvent;
import com.amazonaws.services.logs.model.PutLogEventsRequest;
import com.amazonaws.services.logs.model.PutLogEventsResult;
import com.test.pe.base.CredentialBuilder; 

public class RegisterLog {
    private static String LOG_GROUP = "demo1";
    private static String LOG_STREAM = "stream1";

    public static void main(String[] args) throws ParseException {
        // building my credential and calendar instances
        AWSCredentials credential = CredentialBuilder.getCredential();
        Calendar calendar = Calendar.getInstance();
        // building a cloud watch log client
        AWSLogsClient cloudWatchlog = new AWSLogsClient(credential);
        cloudWatchlog.setRegion(Region.getRegion(Regions.US_WEST_1));
        // building a put request log
        PutLogEventsRequest request = new PutLogEventsRequest();
        request.setLogGroupName(LOG_GROUP);
        request.setLogStreamName(LOG_STREAM);
        // building my log event
        InputLogEvent log = new InputLogEvent();
        log.setMessage("Some message for a test");
        log.setTimestamp(calendar.getTimeInMillis());
        // building the array list log event
        ArrayList<InputLogEvent> logEvents = new ArrayList<InputLogEvent>();
        logEvents.add(log);
        // setting the error array list
        request.setLogEvents(logEvents);
        // make the request
        cloudWatchlog.putLogEvents(request);

        System.out.println("done!");
    }
}
Run Code Online (Sandbox Code Playgroud)

当我第一次运行代码时,所有都是okey,消息被成功保存.

在此输入图像描述

但是,当我第二次执行代码时,我得到以下异常:

Exception in thread "main" com.amazonaws.services.logs.model.InvalidSequenceTokenException: The given sequenceToken is invalid. The next expected sequenceToken is: xxxxxxxxxxxxxxxxxxxxxxxxxxx (Service: AWSLogs; Status Code: 400; Error Code: InvalidSequenceTokenException; Request ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1389)
Run Code Online (Sandbox Code Playgroud)

XXXXXXXXXXX:是亚马逊生成的令牌代码.

阅读亚马逊文档,我发现了以下信息:

请求语法:

{
    "LogEvents": [
        {
            "Message": "string",
            "Timestamp": number
        }
    ],
    "LogGroupName": "string",
    "LogStreamName": "string",
    "SequenceToken": "string"
}
Run Code Online (Sandbox Code Playgroud)

SequenceToken

A string token that must be obtained from the response of the previous PutLogEvents request.

Type: String

Length constraints: Minimum length of 1.

Required: No
Run Code Online (Sandbox Code Playgroud)

有关云监视日志REST API的amazon文档

我决定在我的代码上硬编码序列标记,如下所示:

request.setSequenceToken("58523.......");
Run Code Online (Sandbox Code Playgroud)

它工作正常.我只是为了测试而做的.

最后,我发现获取序列令牌的唯一方法是.

PutLogEventsResult response = cloudWatchlog.putLogEvents(request);
String token = response.getNextSequenceToken();
Run Code Online (Sandbox Code Playgroud)

如何提出请求之前验证并获取序列代码?我在文档上找不到.

Mir*_*cea 5

通常,在调用putLogEvents(getNextSequenceToken)时会得到nextToken。如果有一个以上的生产者推送到该流中,则它们正在竞争并且一次只能推送其中一个(即:如果您获得令牌,而其他人推送它会使您的令牌无效)。

如果发生这种情况,则需要描述流并获取新令牌:http : //docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogStreams.html

因此,模式是:1)如果您没有有效的令牌或根本没有令牌(您只是在开始),请描述流以找出令牌。2)使用已获得的令牌进行推送。如果推送成功,则更新令牌3)如果推送失败,则转到1),获取新令牌,然后重试。如果有多个生产者,则可能需要尝试多次(即循环)。