【发布时间】:2020-06-09 13:07:29
【问题描述】:
我正在尝试使用 Cloudwatch 订阅过滤器构建集中式日志记录解决方案,以将日志写入 Kinesis Firehose -> S3 -> AWS Glue -> Athena。我在数据格式方面遇到了很多问题。
最初,我使用 AWS::KinesisFirehose 的 S3DestinationConfiguration 写入 S3,然后尝试使用 AWS::Glue::Crawler 抓取数据或在 Cloudformation 模板中手动创建表。我发现 Crawler 在确定 S3 上的数据格式时遇到了很多麻烦(发现 ION 而不是 JSON - Athena 无法查询 ION)。我现在正在尝试ExtendedS3DestinationConfiguration,它允许显式配置输入和输出格式以强制其为镶木地板。
很遗憾,使用此设置 Kinesis Firehose 会返回错误日志,指出输入不是有效的 JSON。这让我想知道 Cloudwatch 订阅过滤器是否没有写入正确的 JSON - 但是此对象上没有配置选项来控制数据格式。
这不是一个特别不寻常的问题陈述,因此必须有人进行适当的配置。以下是我失败配置的一些 sn-ps:
ExtendedS3DestinationConfiguration:
BucketARN: !Sub arn:aws:s3:::${S3Bucket}
Prefix: !Sub ${S3LogsPath}year=!{timestamp:YYYY}/month=!{timestamp:MM}/day=!{timestamp:dd}/hour=!{timestamp:HH}/
ErrorOutputPrefix: !Sub ${FailedWritePath}
BufferingHints:
IntervalInSeconds: 300
SizeInMBs: 128
CloudWatchLoggingOptions:
Enabled: true
LogGroupName: !Sub ${AppId}-logstream-${Environment}
LogStreamName: logs
CompressionFormat: UNCOMPRESSED
RoleARN: !GetAtt FirehoseRole.Arn
DataFormatConversionConfiguration:
Enabled: true
InputFormatConfiguration:
Deserializer:
OpenXJsonSerDe: {}
OutputFormatConfiguration:
Serializer:
ParquetSerDe: {}
SchemaConfiguration:
CatalogId: !Ref AWS::AccountId
DatabaseName: !Ref CentralizedLoggingDatabase
Region: !Ref AWS::Region
RoleARN: !GetAtt FirehoseRole.Arn
TableName: !Ref LogsGlueTable
VersionId: LATEST
以前的配置:
S3DestinationConfiguration:
BucketARN: !Sub arn:aws:s3:::${S3Bucket}
Prefix: !Sub ${S3LogsPath}year=!{timestamp:YYYY}/month=!{timestamp:MM}/day=!{timestamp:dd}/hour=!{timestamp:HH}/
ErrorOutputPrefix: !Sub ${FailedWritePath}
BufferingHints:
IntervalInSeconds: 300
SizeInMBs: 128
CloudWatchLoggingOptions:
Enabled: true
LogGroupName: !Sub ${AppId}-logstream-${Environment}
LogStreamName: logs
CompressionFormat: GZIP
RoleARN: !GetAtt FirehoseRole.Arn
还有爬虫:
Type: AWS::Glue::Crawler
Properties:
Name: !Sub ${DNSEndPoint}_logging_s3_crawler_${Environment}
DatabaseName: !Ref CentralizedLoggingDatabase
Description: AWS Glue crawler to crawl logs on S3
Role: !GetAtt CentralizedLoggingGlueRole.Arn
# Schedule: ## run on demand
# ScheduleExpression: cron(40 * * * ? *)
Targets:
S3Targets:
- Path: !Sub s3://${S3Bucket}/${S3LogsPath}
SchemaChangePolicy:
UpdateBehavior: UPDATE_IN_DATABASE
DeleteBehavior: LOG
TablePrefix: !Sub ${AppId}_${Environment}_
错误,使用ExtendedS3DestinationConfiguration:
"attemptsMade":1,"arrivalTimestamp":1582650068665,"lastErrorCode":"DataFormatConversion.ParseError","lastErrorMessage":"遇到格式错误的 JSON。非法字符((CTRL-CHAR,代码 31)):在 [Source: com.fasterxml.jackson.databind.util.ByteBufferBackedInputStream@2ce955fc; line: 1, column: 2] 处的标记之间只允许使用常规空格(\r、\n、\t)
这里似乎有一些配置问题,但我找不到它。
【问题讨论】:
-
可能值得让日志进入 lambda 中的预处理步骤,您可以在其中验证格式,然后再将其发送到 firehose
-
嗨,你有没有设法解决这个问题?我从您的初始 FH 配置开始。显然,json 被发送 base64 编码,显然 Athena 可以默认读取它。尽管如此,让 Athena 表输出清晰的数据仍然是一项艰巨的工作!
标签: amazon-web-services aws-glue amazon-kinesis-firehose