嗨,我正在尝试在AWS cloudwatch中创建我的Java应用程序代码的异常日志,因为我已经使用CloudWatchLogsClient来放置事件了,但是却出现了以下错误
DEBUG software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain - Unable to load credentials from SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId).
software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId).
at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:97)
at software.amazon.awssdk.auth.credentials.internal.SystemSettingsCredentialsProvider.resolveCredentials(SystemSettingsCredentialsProvider.java:58)
at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:91)
at software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider.resolveCredentials(LazyAwsCredentialsProvider.java:52)
at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:100)
at software.amazon.awssdk.awscore.client.handler.AwsClientHandlerUtils.createExecutionContext(AwsClientHandlerUtils.java:71)
at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.createExecutionContext(AwsSyncClientHandler.java:68)
at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:68)
at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:44)
at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:55)
at software.amazon.awssdk.services.cloudwatchlogs.DefaultCloudWatchLogsClient.describeLogStreams(DefaultCloudWatchLogsClient.java:1168)
at com.WorkingwithS3.WorkingwithS3.PutLogEvents.main(PutLogEvents.java:58)
这是我的代码示例
package com.WorkingwithS3.WorkingwithS3;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClient;
import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClientBuilder;
import software.amazon.awssdk.services.cloudwatchlogs.model.DescribeLogStreamsRequest;
import software.amazon.awssdk.services.cloudwatchlogs.model.DescribeLogStreamsResponse;
import software.amazon.awssdk.services.cloudwatchlogs.model.InputLogEvent;
import software.amazon.awssdk.services.cloudwatchlogs.model.PutLogEventsRequest;
import java.util.Arrays;
// snippet-end:[cloudwatch.java2.put_log_events.import]
/**
* Puts a sample CloudWatch log event
*/
public class PutLogEvents {
public static void main(String[] args) {
BasicAWSCredentials creds = new BasicAWSCredentials("xxxx",
"xxxxx");
// BasicAWSCredentials creds = new BasicAWSCredentials("xxxxxxxx",
// "xxxx");
String regionId = "xxx";
String logGroupName = "xxxx";
String streamName = "xxxxx";
// snippet-start:[cloudwatch.java2.put_log_events.main]
CloudWatchLogsClient logsClient = CloudWatchLogsClient.builder().region(Region.of(regionId)).build();
// A sequence token is required to put a log event in an existing stream.
// Look up the stream to find its sequence token.
// First describe all streams in the log group.
DescribeLogStreamsRequest logStreamRequest = DescribeLogStreamsRequest.builder()
.logGroupName(logGroupName)
.logStreamNamePrefix(streamName)
.build();
DescribeLogStreamsResponse describeLogStreamsResponse = logsClient.describeLogStreams(logStreamRequest);
// Assume that a single stream is returned since a specific stream name was specified in the previous request.
String sequenceToken = describeLogStreamsResponse.logStreams().get(0).uploadSequenceToken();
// Build an input log message to put to CloudWatch.
InputLogEvent inputLogEvent = InputLogEvent.builder()
.message("{ \"key1\": \"value1\", \"key2\": \"value2\" }")
.timestamp(System.currentTimeMillis())
.build();
// Specify the request parameters.
PutLogEventsRequest putLogEventsRequest = PutLogEventsRequest.builder()
.logEvents(Arrays.asList(inputLogEvent))
.logGroupName(logGroupName)
.logStreamName(streamName)
// Sequence token is required so that the log can be written to the
// latest location in the stream.
.sequenceToken(sequenceToken)
.build();
logsClient.putLogEvents(putLogEventsRequest);
// snippet-end:[cloudwatch.java2.put_log_events.main]
System.out.println("Successfully put CloudWatch log event");
}
}
任何人都可以指导如何为CloudWatchLogsClient指定凭据吗?
提前致谢
最佳答案
从跟踪中我们可以看到在此实例CloudWatchLogsClient.builder()
中的sdk客户端无法找到凭据,因此无法构建。
客户端将在以下defaults locations中查找凭据
出于很多原因,设置代码以从环境变量读取凭据非常有好处。
这有很多原因。
AWS鼓励使用environment variables for credentials。
例如,越来越需要在诸如Kubernetes之类的容器集群中运行您的应用程序。
通常在容器化环境中访问文件系统可能会出现问题。
在像docker这样的许多容器工具中,将其琐碎化为pass environment variables to the container。
在链接defaults locations中,它精确地指定了为CloudWatchLogsClient.builder()
操作提供凭据的选项,并且由于上述原因,建议您采用环境变量解决方案,并可以使用`测试它们的设置是否正确。
Map<String, String> mapOfEnvironmentVariables = System.getenv();
检索它们。