Spring Boot 为AWS Cloudwatch日志客户端指定凭据

zi8p0yeb  于 2024-01-06  发布在  Spring
关注(0)|答案(2)|浏览(215)

嗨,我试图在AWS cloudwatch中创建我的Java应用程序代码的异常日志,因为我已经使用CloudWatchLogsClient将我的事件放入其中,但我得到了下面的错误

  1. 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).
  2. 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).
  3. at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:97)
  4. at software.amazon.awssdk.auth.credentials.internal.SystemSettingsCredentialsProvider.resolveCredentials(SystemSettingsCredentialsProvider.java:58)
  5. at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:91)
  6. at software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider.resolveCredentials(LazyAwsCredentialsProvider.java:52)
  7. at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:100)
  8. at software.amazon.awssdk.awscore.client.handler.AwsClientHandlerUtils.createExecutionContext(AwsClientHandlerUtils.java:71)
  9. at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.createExecutionContext(AwsSyncClientHandler.java:68)
  10. at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:68)
  11. at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:44)
  12. at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:55)
  13. at software.amazon.awssdk.services.cloudwatchlogs.DefaultCloudWatchLogsClient.describeLogStreams(DefaultCloudWatchLogsClient.java:1168)
  14. at com.WorkingwithS3.WorkingwithS3.PutLogEvents.main(PutLogEvents.java:58)

字符串

这是我的代码示例

  1. package com.WorkingwithS3.WorkingwithS3;
  2. import com.amazonaws.auth.AWSStaticCredentialsProvider;
  3. import com.amazonaws.auth.BasicAWSCredentials;
  4. import com.amazonaws.regions.Regions;
  5. import com.amazonaws.services.s3.AmazonS3;
  6. import com.amazonaws.services.s3.AmazonS3ClientBuilder;
  7. import software.amazon.awssdk.regions.Region;
  8. import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClient;
  9. import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClientBuilder;
  10. import software.amazon.awssdk.services.cloudwatchlogs.model.DescribeLogStreamsRequest;
  11. import software.amazon.awssdk.services.cloudwatchlogs.model.DescribeLogStreamsResponse;
  12. import software.amazon.awssdk.services.cloudwatchlogs.model.InputLogEvent;
  13. import software.amazon.awssdk.services.cloudwatchlogs.model.PutLogEventsRequest;
  14. import java.util.Arrays;
  15. // snippet-end:[cloudwatch.java2.put_log_events.import]
  16. /**
  17. * Puts a sample CloudWatch log event
  18. */
  19. public class PutLogEvents {
  20. public static void main(String[] args) {
  21. BasicAWSCredentials creds = new BasicAWSCredentials("xxxx",
  22. "xxxxx");
  23. // BasicAWSCredentials creds = new BasicAWSCredentials("xxxxxxxx",
  24. // "xxxx");
  25. String regionId = "xxx";
  26. String logGroupName = "xxxx";
  27. String streamName = "xxxxx";
  28. // snippet-start:[cloudwatch.java2.put_log_events.main]
  29. CloudWatchLogsClient logsClient = CloudWatchLogsClient.builder().region(Region.of(regionId)).build();
  30. // A sequence token is required to put a log event in an existing stream.
  31. // Look up the stream to find its sequence token.
  32. // First describe all streams in the log group.
  33. DescribeLogStreamsRequest logStreamRequest = DescribeLogStreamsRequest.builder()
  34. .logGroupName(logGroupName)
  35. .logStreamNamePrefix(streamName)
  36. .build();
  37. DescribeLogStreamsResponse describeLogStreamsResponse = logsClient.describeLogStreams(logStreamRequest);
  38. // Assume that a single stream is returned since a specific stream name was specified in the previous request.
  39. String sequenceToken = describeLogStreamsResponse.logStreams().get(0).uploadSequenceToken();
  40. // Build an input log message to put to CloudWatch.
  41. InputLogEvent inputLogEvent = InputLogEvent.builder()
  42. .message("{ \"key1\": \"value1\", \"key2\": \"value2\" }")
  43. .timestamp(System.currentTimeMillis())
  44. .build();
  45. // Specify the request parameters.
  46. PutLogEventsRequest putLogEventsRequest = PutLogEventsRequest.builder()
  47. .logEvents(Arrays.asList(inputLogEvent))
  48. .logGroupName(logGroupName)
  49. .logStreamName(streamName)
  50. // Sequence token is required so that the log can be written to the
  51. // latest location in the stream.
  52. .sequenceToken(sequenceToken)
  53. .build();
  54. logsClient.putLogEvents(putLogEventsRequest);
  55. // snippet-end:[cloudwatch.java2.put_log_events.main]
  56. System.out.println("Successfully put CloudWatch log event");
  57. }
  58. }


有没有人可以指导如何指定CloudWatchLogsClient的凭据?提前感谢

sg3maiej

sg3maiej1#

从跟踪中我们可以看到这个示例CloudWatchLogsClient.builder()中的sdk客户端无法找到凭据,因此无法构建。
客户端将在以下defaults locations中查找凭据
出于多种原因,最好将代码设置为从环境变量读取凭据。
这有很多原因。
AWS鼓励使用environment variables for credentials
越来越需要在某种容器集群中运行应用程序,例如Kubernetes。
在容器化的环境中,访问文件系统通常是有问题的。
在许多容器工具中,比如docker-compose,它的作用很小,就像pass environment variables to the container一样。
在链接defaults locations中,它精确地指定了如何为CloudWatchLogsClient.builder()操作提供凭据的选项,并且由于上述原因,建议您采用环境变量解决方案,并且您可以使用`

  1. Map<String, String> mapOfEnvironmentVariables = System.getenv();

字符串
去取回它们

更新20-12-2023

更改了“默认位置”的AWS文档链接,查找副标题“凭据设置检索顺序”下的第2节

展开查看全部
rjee0c15

rjee0c152#

下面的代码工作正常,我能够使用CloudWatchLogsClient在cloudwatch中编写异常,仅供参考,我附上了代码

  1. package com.example.DynamoDB;
  2. import org.springframework.http.HttpStatus;
  3. import org.springframework.http.ResponseEntity;
  4. import org.springframework.web.bind.annotation.ControllerAdvice;
  5. import org.springframework.web.bind.annotation.ExceptionHandler;
  6. import software.amazon.awssdk.regions.Region;
  7. import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClient;
  8. import software.amazon.awssdk.services.cloudwatchlogs.model.DescribeLogStreamsRequest;
  9. import software.amazon.awssdk.services.cloudwatchlogs.model.DescribeLogStreamsResponse;
  10. import software.amazon.awssdk.services.cloudwatchlogs.model.InputLogEvent;
  11. import software.amazon.awssdk.services.cloudwatchlogs.model.PutLogEventsRequest;
  12. import java.util.Arrays;
  13. @ControllerAdvice
  14. public class ExceptionControllerAdvice {
  15. @ExceptionHandler(Exception.class)
  16. public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) {
  17. ErrorResponse error = new ErrorResponse();
  18. error.setErrorCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
  19. error.setMessage(ex.getMessage());
  20. error.setController(ex.getStackTrace()[0].getClassName());
  21. error.setService(ex.getStackTrace()[0].getClassName());
  22. error.setTimestamp(System.currentTimeMillis());
  23. PutLogEvents(error);
  24. return new ResponseEntity<ErrorResponse>(error, HttpStatus.OK);
  25. }
  26. public static void PutLogEvents(ErrorResponse Er)
  27. {
  28. String regionId = "us-east-1";
  29. String logGroupName = "xxxxxxxxx";
  30. String logStreamName = "xxxxxxxxx";
  31. CloudWatchLogsClient logsClient = CloudWatchLogsClient.builder().region(Region.of(regionId)).build();
  32. // A sequence token is required to put a log event in an existing stream.
  33. // Look up the stream to find its sequence token.
  34. String sequenceToken = getNextSequenceToken(logsClient, logGroupName, logStreamName);
  35. // Build a JSON log using the EmbeddedMetricFormat.
  36. String message = "[{" +
  37. " \"Timestamp\": " + Er.getTimestamp() + "," +
  38. " \"ErrorCode\": " + Er.getErrorCode() + "," +
  39. " \"ControllerName\": " + Er.getErrorCode() + "," +
  40. " \"ServiceName\": " + Er.getErrorCode() + "," +
  41. " \"ErrorMsg\": " + Er.getErrorCode() + "" +
  42. "}]";
  43. InputLogEvent inputLogEvent = InputLogEvent.builder()
  44. .message(message)
  45. .timestamp(Er.getTimestamp())
  46. .build();
  47. // Specify the request parameters.
  48. PutLogEventsRequest putLogEventsRequest = PutLogEventsRequest.builder()
  49. .logEvents(Arrays.asList(inputLogEvent))
  50. .logGroupName(logGroupName)
  51. .logStreamName(logStreamName)
  52. // Sequence token is required so that the log can be written to the
  53. // latest location in the stream.
  54. .sequenceToken(sequenceToken)
  55. .build();
  56. logsClient.putLogEvents(putLogEventsRequest);
  57. }
  58. private static String getNextSequenceToken(CloudWatchLogsClient logsClient, String logGroupName, String logStreamName) {
  59. DescribeLogStreamsRequest logStreamRequest = DescribeLogStreamsRequest.builder()
  60. .logGroupName(logGroupName)
  61. .logStreamNamePrefix(logStreamName)
  62. .build();
  63. DescribeLogStreamsResponse describeLogStreamsResponse = logsClient.describeLogStreams(logStreamRequest);
  64. // Assume that a single stream is returned since a specific stream name was
  65. // specified in the previous request.
  66. return describeLogStreamsResponse.logStreams().get(0).uploadSequenceToken();
  67. }
  68. }

字符串

展开查看全部

相关问题