Импорт журналов из S3 в Athena с помощью регулярных выражений

#amazon-s3 #amazon-cloudwatch #amazon-athena

Вопрос:

Я экспортировал журналы CloudWatch в S3 и теперь хочу импортировать эти журналы в Athena. Формат журналов следующий (вставлен только один журнал для справки):

 2021-07-30T14:30:22.937Z    RequestId   INFO    {"_logLevel":"debug","msg":"Start: Calling All the Data Associates Function","timestamp":1627655422937,"EventSubCategory":"AppSyncService","API":"AppSyncService","function":"XXXXXXXXXXXXXXXXX","Correlation_Id":"XXXXXXXXXXXXXXXXX"}
 

Я использую регулярное выражение для импорта журнала и использую следующий запрос для создания таблицы.

 CREATE EXTERNAL TABLE IF NOT EXISTS test1 (
  `time` string
  `requestid` string
  `loglevel` string
  `message` string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1',
  'input.regex' = '^(.*?)t(.*?)t(.*?)t([sS]*?)n'
)
LOCATION 's3://logs/test/'
TBLPROPERTIES ('has_encrypted_data'='false');
 

обычное выражение:

 ^(.*?)t(.*?)t(.*?)t([sS]*?)n
 

В таблице четыре столбца, и регулярное выражение также создает четыре группы и работает в соответствии с моими ожиданиями. Однако в результате мы все равно получаем пустую таблицу.

Кто-нибудь может, пожалуйста, помочь решить эту проблему?

Комментарии:

1. Я удалил дублирующуюся метку времени в начале строки журнала, потому что она выглядела как опечатка (в таблице есть только один столбец времени).

2. Это была не опечатка. Когда мы экспортируем журналы из CloudWatch в S3, в выходном файле мы получаем две временные метки, разделенные пробелом.

3. В таком случае я не понимаю, почему в вашем регулярном выражении четыре группы захвата. С начальными и конечными якорями, как они будут соответствовать пяти столбцам?

Ответ №1:

Я думаю, ваша проблема в том, что вам нужно дважды экранировать вещи в регулярном выражении, и вы также не должны совпадать с новой строкой в конце, но $ . Попробуйте этот шаблон:

 'input.regex' = '^(.*?)\t(.*?)\t(.*?)\t([\s\S]*?)

Вы можете увидеть пример в официальных документах.

Кроме того, шаблон  [sS]  может быть заменен на  .  ( S   означает все , что не соответствует s  , поэтому вместе они соответствуют чему угодно).

Альтернативой регулярному выражению serde является Grok, который менее подвержен ошибкам при записи. Используя Grok serde, я думаю, что эта таблица подойдет вам:

 CREATE EXTERNAL TABLE IF NOT EXISTS test1 (
  `time` string
  `requestid` string
  `loglevel` string
  `message` string
)
ROW FORMAT SERDE 'com.amazonaws.glue.serde.GrokSerDe'
WITH SERDEPROPERTIES (
  input.format' = '%{TIMESTAMP_ISO8601:time} %{NOTSPACE:requestid} %{NOTSPACE:loglevel} %{NOTSPACE:message}'
)
LOCATION 's3://logs/test/'
 

Шаблоны Grok гораздо легче читать. Ознакомьтесь с документацией и встроенными шаблонами для получения дополнительной информации.

Вы можете увидеть пример в официальных документах.

Кроме того, шаблон [sS] может быть заменен на . ( S означает все , что не соответствует s , поэтому вместе они соответствуют чему угодно).

Альтернативой регулярному выражению serde является Grok, который менее подвержен ошибкам при записи. Используя Grok serde, я думаю, что эта таблица подойдет вам:


Шаблоны Grok гораздо легче читать. Ознакомьтесь с документацией и встроенными шаблонами для получения дополнительной информации.