αž€αžΆαžšαžœαž·αž—αžΆαž‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αžŠαŸ„αž™αž”αŸ’αžšαžΎ Amazon Athena αž“αž·αž„ Cube.js

αž‡αžΆαž’αž˜αŸ’αž˜αžαžΆ αž•αž›αž·αžαž•αž›αž–αžΆαžŽαž·αž‡αŸ’αž‡αž€αž˜αŸ’αž˜ αž¬αž‡αž˜αŸ’αžšαžΎαžŸαž”αŸ’αžšαž—αž–αž”αžΎαž€αž…αŸ†αž αžŠαŸ‚αž›αžαŸ’αžšαŸ€αž˜αžšαž½αž…αž‡αžΆαžŸαŸ’αžšαŸαž… αžŠαžΌαž…αž‡αžΆ Prometheus + Grafana αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎαžŠαžΎαž˜αŸ’αž”αžΈαžαžΆαž˜αžŠαžΆαž“ αž“αž·αž„αžœαž·αž—αžΆαž‚αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžΆαžšαžšαž”αžŸαŸ‹ Nginx αŸ” αž“αŸαŸ‡αž‚αžΊαž‡αžΆαž‡αž˜αŸ’αžšαžΎαžŸαžŠαŸαž›αŸ’αž’αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαžαŸ’αžšαž½αžαž–αž·αž“αž·αžαŸ’αž™ αž¬αž€αžΆαžšαžœαž·αž—αžΆαž‚αžαžΆαž˜αž–αŸαž›αžœαŸαž›αžΆαž‡αžΆαž€αŸ‹αžŸαŸ’αžαŸ‚αž„ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž˜αž·αž“αž„αžΆαž™αžŸαŸ’αžšαž½αž›αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαžœαž·αž—αžΆαž‚αž”αŸ’αžšαžœαžαŸ’αžαž·αžŸαžΆαžŸαŸ’αžšαŸ’αžαž“αŸ„αŸ‡αž‘αŸαŸ” αž“αŸ…αž›αžΎαž’αž“αž’αžΆαž“αžŠαŸαž–αŸαž‰αž“αž·αž™αž˜αžŽαžΆαž˜αž½αž™ αž”αžšαž·αž˜αžΆαžŽαž“αŸƒαž‘αž·αž“αŸ’αž“αž“αŸαž™αž–αžΈαž€αŸ†αžŽαžαŸ‹αž αŸαžαž» nginx αž€αŸ†αž–αž»αž„αžαŸ‚αž€αžΎαž“αž‘αžΎαž„αž™αŸ‰αžΆαž„αž†αžΆαž”αŸ‹αžšαž αŸαžŸ αž αžΎαž™αžŠαžΎαž˜αŸ’αž”αžΈαžœαž·αž—αžΆαž‚αž‘αž·αž“αŸ’αž“αž“αŸαž™αž˜αž½αž™αž…αŸ†αž“αž½αž“αž’αŸ† αžœαžΆαžŸαž˜αž αŸαžαž»αž•αž›αž€αŸ’αž“αž»αž„αž€αžΆαžšαž”αŸ’αžšαžΎαž’αŸ’αžœαžΈαžŠαŸ‚αž›αž–αž·αžŸαŸαžŸαž‡αžΆαž„αž“αŸαŸ‡αŸ”

αž“αŸ…αž€αŸ’αž“αž»αž„αž’αžαŸ’αžαž”αž‘αž“αŸαŸ‡αžαŸ’αž‰αž»αŸ†αž“αžΉαž„αž”αŸ’αžšαžΆαž”αŸ‹αž’αŸ’αž“αž€αž–αžΈαžšαž”αŸ€αž”αžŠαŸ‚αž›αž’αŸ’αž“αž€αž’αžΆαž…αž”αŸ’αžšαžΎ Athena αžŠαžΎαž˜αŸ’αž”αžΈαžœαž·αž—αžΆαž‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» αžŠαŸ„αž™αž™αž€ Nginx αž‡αžΆαž§αž‘αžΆαž αžšαžŽαŸ αž αžΎαž™αžαŸ’αž‰αž»αŸ†αž“αžΉαž„αž”αž„αŸ’αž αžΆαž‰αž–αžΈαžšαž”αŸ€αž”αž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αžœαž·αž—αžΆαž‚αž–αžΈαž‘αž·αž“αŸ’αž“αž“αŸαž™αž“αŸαŸ‡αžŠαŸ„αž™αž”αŸ’αžšαžΎ open-source cube.js frameworkαŸ” αž“αŸαŸ‡αž‚αžΊαž‡αžΆαžŸαŸ’αžαžΆαž”αžαŸ’αž™αž€αž˜αŸ’αž˜αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž–αŸαž‰αž›αŸαž‰αŸ–

αž€αžΆαžšαžœαž·αž—αžΆαž‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αžŠαŸ„αž™αž”αŸ’αžšαžΎ Amazon Athena αž“αž·αž„ Cube.js

TL:DR;
αž—αŸ’αž‡αžΆαž”αŸ‹αž‘αŸ…αž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αžŠαŸ‚αž›αž”αžΆαž“αž”αž‰αŸ’αž…αž”αŸ‹.

αžŠαžΎαž˜αŸ’αž”αžΈαž”αŸ’αžšαž˜αžΌαž›αž–αŸαžαŸŒαž˜αžΆαž“αž™αžΎαž„αž”αŸ’αžšαžΎ αžŸαŸ’αž‘αžΆαžαŸ‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš - AWS Kinesis Data Firehose ΠΈ αž€αžΆαžœαž’αŸαžœαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž•αŸ’αž‘αž»αž€ - αž’αŸαžŸαŸ” ធេស ៣. αžŠαŸ„αž™αž”αŸ’αžšαžΎαž€αž‰αŸ’αž…αž”αŸ‹αž“αŸαŸ‡ αž’αŸ’αž“αž€αž’αžΆαž…αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž˜αž·αž“αžαŸ’αžšαžΉαž˜αžαŸ‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» nginx αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αž‘αŸ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž€αŸαž˜αžΆαž“αž–αŸ’αžšαžΉαžαŸ’αžαž·αž€αžΆαžšαžŽαŸαž•αŸ’αžŸαŸαž„αž‘αŸ€αž αž€αŸαžŠαžΌαž…αž‡αžΆαž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αž“αŸƒαžŸαŸαžœαžΆαž€αž˜αŸ’αž˜αž•αŸ’αžŸαŸαž„αž‘αŸ€αžαž•αž„αžŠαŸ‚αžšαŸ” αž’αŸ’αž“αž€αž’αžΆαž…αž‡αŸ†αž“αž½αžŸαž•αŸ’αž“αŸ‚αž€αžαŸ’αž›αŸ‡αžŠαŸ„αž™αž•αŸ’αž“αŸ‚αž€αžŸαŸ’αžšαžŠαŸ€αž„αž‚αŸ’αž“αžΆαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‡αž„αŸ‹αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αž§αž‘αžΆαž αžšαžŽαŸ αž’αŸ’αž“αž€αž’αžΆαž…αžŸαžšαžŸαŸαžšαž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αž‘αŸ…αž€αžΆαž“αŸ‹ kinesis αžŠαŸ„αž™αž•αŸ’αž‘αžΆαž›αŸ‹αž–αžΈ nginx αžšαŸ†αž›αž„αžŸαŸ’αž‘αžΆαžαŸ‹αž‡αŸ†αž“αžΆαž‰ αž¬αž”αŸ’αžšαžΎ logstash αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž“αŸαŸ‡αŸ”

αž€αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx

αžαžΆαž˜αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜ αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αž˜αžΎαž›αž‘αŸ…αžŠαžΌαž…αž“αŸαŸ‡αŸ–

4/9/2019 12:58:17 PM1.1.1.1 - - [09/Apr/2019:09:58:17 +0000] "GET /sign-up HTTP/2.0" 200 9168 "https://example.com/sign-in" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36" "-"
4/9/2019 12:58:17 PM1.1.1.1 - - [09/Apr/2019:09:58:17 +0000] "GET /sign-in HTTP/2.0" 200 9168 "https://example.com/sign-up" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36" "-"

αž–αž½αž€αžœαžΆαž’αžΆαž…αž‰αŸ‚αž€αž”αžΆαž“ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžœαžΆαž€αžΆαž“αŸ‹αžαŸ‚αž„αžΆαž™αžŸαŸ’αžšαž½αž›αž€αŸ’αž“αž»αž„αž€αžΆαžšαž€αŸ‚αžαž˜αŸ’αžšαžΌαžœαž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ Nginx αžŠαžΌαž…αŸ’αž“αŸαŸ‡αžœαžΆαž”αž„αŸ’αž€αžΎαžαž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αž“αŸ…αž€αŸ’αž“αž»αž„ JSONαŸ–

log_format json_combined escape=json '{ "created_at": "$msec", '
            '"remote_addr": "$remote_addr", '
            '"remote_user": "$remote_user", '
            '"request": "$request", '
            '"status": $status, '
            '"bytes_sent": $bytes_sent, '
            '"request_length": $request_length, '
            '"request_time": $request_time, '
            '"http_referrer": "$http_referer", '
            '"http_x_forwarded_for": "$http_x_forwarded_for", '
            '"http_user_agent": "$http_user_agent" }';

access_log  /var/log/nginx/access.log  json_combined;

S3 αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž•αŸ’αž‘αž»αž€

αžŠαžΎαž˜αŸ’αž”αžΈαžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» αž™αžΎαž„αž“αžΉαž„αž”αŸ’αžšαžΎ S3 αŸ” αž“αŸαŸ‡αž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž’αŸ’αž“αž€αžšαž€αŸ’αžŸαžΆαž‘αž»αž€ αž“αž·αž„αžœαž·αž—αžΆαž‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αž“αŸ…αž€αž“αŸ’αž›αŸ‚αž„αžαŸ‚αž˜αž½αž™ αžŠαŸ„αž™αžŸαžΆαžš Athena αž’αžΆαž…αž’αŸ’αžœαžΎαž€αžΆαžšαž‡αžΆαž˜αž½αž™αž‘αž·αž“αŸ’αž“αž“αŸαž™αž“αŸ…αž€αŸ’αž“αž»αž„ S3 αžŠαŸ„αž™αž•αŸ’αž‘αžΆαž›αŸ‹αŸ” αž’αžαŸ’αžαž”αž‘αž”αž“αŸ’αž‘αžΆαž”αŸ‹αžαŸ’αž‰αž»αŸ†αž“αžΉαž„αž”αŸ’αžšαžΆαž”αŸ‹αž’αŸ’αž“αž€αž–αžΈαžšαž”αŸ€αž”αž”αž“αŸ’αžαŸ‚αž˜ αž“αž·αž„αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αž±αŸ’αž™αž”αžΆαž“αžαŸ’αžšαžΉαž˜αžαŸ’αžšαžΌαžœ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžŠαŸ†αž”αžΌαž„αž™αžΎαž„αžαŸ’αžšαžΌαžœαž€αžΆαžšαž’αž»αž„αžŸαŸ’αž’αžΆαžαž“αŸ…αž€αŸ’αž“αž»αž„ S3 αžŠαŸ‚αž›αž‚αŸ’αž˜αžΆαž“αž’αŸ’αžœαžΈαž•αŸ’αžŸαŸαž„αž‘αŸ€αžαž“αžΉαž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž‘αŸαŸ” αžœαžΆαž˜αžΆαž“αžαž˜αŸ’αž›αŸƒαž–αž·αž…αžΆαžšαžŽαžΆαž‡αžΆαž˜αž»αž“αžαžΆαžαžΎαžαŸ†αž”αž“αŸ‹αžŽαžΆαžŠαŸ‚αž›αž’αŸ’αž“αž€αž“αžΉαž„αž”αž„αŸ’αž€αžΎαžαž’αž»αž„αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αž–αžΈαž–αŸ’αžšαŸ„αŸ‡ Athena αž˜αž·αž“αž˜αžΆαž“αž“αŸ…αž‚αŸ’αžšαž”αŸ‹αžαŸ†αž”αž“αŸ‹αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αŸ”

αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαžŸαŸ€αž‚αŸ’αžœαžΈαž“αŸ…αž€αŸ’αž“αž»αž„αž€αž»αž„αžŸαžΌαž› Athena

αžαŸ„αŸ‡αž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„αž“αŸ… Athena αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αŸ” αžœαžΆαžαŸ’αžšαžΌαžœαž€αžΆαžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‘αžΆαŸ†αž„αž€αžΆαžšαžŸαžšαžŸαŸαžš αž“αž·αž„αž€αžΆαžšαž’αžΆαž“ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž˜αžΆαž“αž‚αž˜αŸ’αžšαŸ„αž„αž”αŸ’αžšαžΎ Kinesis Firehose αŸ” αž”αžΎαž€αž€αž»αž„αžŸαžΌαž› Athena αž αžΎαž™αž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„αŸ–

αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„ SQL

CREATE EXTERNAL TABLE `kinesis_logs_nginx`(
  `created_at` double, 
  `remote_addr` string, 
  `remote_user` string, 
  `request` string, 
  `status` int, 
  `bytes_sent` int, 
  `request_length` int, 
  `request_time` double, 
  `http_referrer` string, 
  `http_x_forwarded_for` string, 
  `http_user_agent` string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.orc.OrcSerde' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'
LOCATION
  's3://<YOUR-S3-BUCKET>'
TBLPROPERTIES ('has_encrypted_data'='false');

αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαžŸαŸ’αž‘αŸ’αžšαžΈαž˜ Kinesis Firehose

Kinesis Firehose αž“αžΉαž„αžŸαžšαžŸαŸαžšαž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ‚αž›αž‘αž‘αž½αž›αž”αžΆαž“αž–αžΈ Nginx αž‘αŸ… S3 αž€αŸ’αž“αž»αž„αž‘αž˜αŸ’αžšαž„αŸ‹αžŠαŸ‚αž›αž”αžΆαž“αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ αžŠαŸ„αž™αž”αŸ‚αž„αž…αŸ‚αž€αžœαžΆαž‘αŸ…αž‡αžΆαžαžαž€αŸ’αž“αž»αž„αž‘αž˜αŸ’αžšαž„αŸ‹ YYYY/MM/DD/HHαŸ” αžœαžΆαž“αžΉαž„αž˜αžΆαž“αž”αŸ’αžšαž™αŸ„αž‡αž“αŸαž“αŸ…αž–αŸαž›αž’αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αŸ” αž‡αžΆαž€αžΆαžšαž–αž·αžαžŽαžΆαžŸαŸ‹αž’αŸ’αž“αž€αž’αžΆαž…αžŸαžšαžŸαŸαžšαžŠαŸ„αž™αž•αŸ’αž‘αžΆαž›αŸ‹αž‘αŸ… S3 αž–αžΈαžŸαŸ’αž‘αžΆαžαŸ‹αž‡αŸ†αž“αžΆαž‰ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαž“αŸαŸ‡αž’αŸ’αž“αž€αž“αžΉαž„αžαŸ’αžšαžΌαžœαžŸαžšαžŸαŸαžš JSON αž αžΎαž™αžœαžΆαž˜αž·αž“αž˜αžΆαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŠαŸ„αž™αžŸαžΆαžšαžαŸ‚αž‘αŸ†αž αŸ†αž’αŸ†αž“αŸƒαž―αž€αžŸαžΆαžšαŸ” αž›αžΎαžŸαž–αžΈαž“αŸαŸ‡αž‘αŸ€αž αž“αŸ…αž–αŸαž›αž”αŸ’αžšαžΎ PrestoDB ឬ Athena JSON αž‚αžΊαž‡αžΆαž‘αž˜αŸ’αžšαž„αŸ‹αž‘αž·αž“αŸ’αž“αž“αŸαž™αž™αžΊαžαž”αŸ†αž•αž»αžαŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž”αžΎαž€αž€αž»αž„αžŸαžΌαž› Kinesis Firehose αž…αž»αž… "αž”αž„αŸ’αž€αžΎαžαž€αžΆαžšαž…αŸ‚αž€αž…αžΆαž™" αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ "αžŠαŸ„αž™αž•αŸ’αž‘αžΆαž›αŸ‹ PUT" αž“αŸ…αž€αŸ’αž“αž»αž„αžœαžΆαž› "αž€αžΆαžšαžŠαžΉαž€αž‡αž‰αŸ’αž‡αžΌαž“"αŸ–

αž€αžΆαžšαžœαž·αž—αžΆαž‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αžŠαŸ„αž™αž”αŸ’αžšαžΎ Amazon Athena αž“αž·αž„ Cube.js

αž“αŸ…αž€αŸ’αž“αž»αž„αž•αŸ’αž‘αžΆαŸ†αž„αž”αž“αŸ’αž‘αžΆαž”αŸ‹ αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ "αž€αžΆαžšαž”αž˜αŸ’αž›αŸ‚αž„αž‘αŸ’αžšαž„αŸ‹αž‘αŸ’αžšαžΆαž™αžαž" - "αž”αžΆαž“αž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš" αž αžΎαž™αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ "Apache ORC" αž‡αžΆαž‘αž˜αŸ’αžšαž„αŸ‹αžαžαŸ” αž“αŸαŸ‡β€‹αž”αžΎβ€‹αžαžΆαž˜β€‹αž€αžΆαžšβ€‹αžŸαŸ’αžšαžΆαžœαž‡αŸ’αžšαžΆαžœβ€‹αž˜αž½αž™β€‹αž…αŸ†αž“αž½αž“ Owen O'Malleyαž“αŸαŸ‡αž‚αžΊαž‡αžΆαž‘αž˜αŸ’αžšαž„αŸ‹αžŠαŸαž›αŸ’αž’αž”αŸ’αžšαžŸαžΎαžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹ PrestoDB αž“αž·αž„ Athena αŸ” αž™αžΎαž„αž”αŸ’αžšαžΎαžαžΆαžšαžΆαž„αžŠαŸ‚αž›αž™αžΎαž„αž”αžΆαž“αž”αž„αŸ’αž€αžΎαžαžαžΆαž„αž›αžΎαž‡αžΆαž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαŸ” αžŸαžΌαž˜αž…αŸ†αžŽαžΆαŸ†αžαžΆαž’αŸ’αž“αž€αž’αžΆαž…αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž‘αžΈαžαžΆαŸ†αž„ S3 αžŽαžΆαž˜αž½αž™αž“αŸ…αž€αŸ’αž“αž»αž„ kinesis αž˜αžΆαž“αžαŸ‚αž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎαž–αžΈαžαžΆαžšαžΆαž„αŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž‘αžΈαžαžΆαŸ†αž„ S3 αž•αŸ’αžŸαŸαž„ αž“αŸ„αŸ‡αž’αŸ’αž“αž€αž“αžΉαž„αž˜αž·αž“αž’αžΆαž…αž’αžΆαž“αž€αŸ†αžŽαžαŸ‹αžαŸ’αžšαžΆαž‘αžΆαŸ†αž„αž“αŸαŸ‡αž–αžΈαžαžΆαžšαžΆαž„αž“αŸαŸ‡αž”αžΆαž“αž‘αŸαŸ”

αž€αžΆαžšαžœαž·αž—αžΆαž‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αžŠαŸ„αž™αž”αŸ’αžšαžΎ Amazon Athena αž“αž·αž„ Cube.js

αž™αžΎαž„αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ S3 αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž•αŸ’αž‘αž»αž€ αž“αž·αž„αž’αž»αž„αžŠαŸ‚αž›αž™αžΎαž„αž”αžΆαž“αž”αž„αŸ’αž€αžΎαžαž˜αž»αž“αŸ” Aws Glue Crawler αžŠαŸ‚αž›αžαŸ’αž‰αž»αŸ†αž“αžΉαž„αž“αž·αž™αžΆαž™αž’αŸ†αž–αžΈαž”αž“αŸ’αžαž·αž…αž€αŸ’αžšαŸ„αž™αž˜αž€ αž˜αž·αž“αž’αžΆαž…αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž‡αžΆαž˜αž½αž™αž”αž»αž–αŸ’αžœαž”αž‘αž“αŸ…αž€αŸ’αž“αž»αž„αž’αž»αž„ S3 αž”αžΆαž“αž‘αŸ αžŠαžΌαž…αŸ’αž“αŸαŸ‡αžœαžΆαž‡αžΆαž€αžΆαžšαžŸαŸ†αžαžΆαž“αŸ‹αž€αŸ’αž“αž»αž„αž€αžΆαžšαž‘αž»αž€αžœαžΆαž±αŸ’αž™αž“αŸ…αž‘αž‘αŸαŸ”

αž€αžΆαžšαžœαž·αž—αžΆαž‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αžŠαŸ„αž™αž”αŸ’αžšαžΎ Amazon Athena αž“αž·αž„ Cube.js

αž‡αž˜αŸ’αžšαžΎαžŸαžŠαŸ‚αž›αž“αŸ…αžŸαž›αŸ‹αž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαž’αžΆαžŸαŸ’αžšαŸαž™αž›αžΎαž”αž“αŸ’αž‘αž»αž€αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αž‡αžΆαž’αž˜αŸ’αž˜αžαžΆαžαŸ’αž‰αž»αŸ†αž”αŸ’αžšαžΎαž‡αž˜αŸ’αžšαžΎαžŸαž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜αŸ” αž…αŸ†αžŽαžΆαŸ†αžαžΆαž€αžΆαžšαž”αž„αŸ’αž αžΆαž”αŸ‹ S3 αž˜αž·αž“αž˜αžΆαž“αž‘αŸ αž”αŸ‰αž»αž“αŸ’αžαŸ‚ ORC αž”αŸ’αžšαžΎαž€αžΆαžšαž”αž„αŸ’αž αžΆαž”αŸ‹αžŠαžΎαž˜αžαžΆαž˜αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜αŸ”

αžŸαŸ’αž‘αžΆαžαŸ‹

αž₯αž‘αžΌαžœβ€‹αž“αŸαŸ‡β€‹αž™αžΎαž„β€‹αž”αžΆαž“β€‹αž€αŸ†αžŽαžαŸ‹β€‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’β€‹αž€αžΆαžšβ€‹αžšαž€αŸ’αžŸαžΆβ€‹αž‘αž»αž€ αž“αž·αž„β€‹αž‘αž‘αž½αž›β€‹αž”αžΆαž“β€‹αž αžΎαž™ αž™αžΎαž„β€‹αžαŸ’αžšαžΌαžœβ€‹αž€αŸ†αžŽαžαŸ‹β€‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’β€‹αž€αžΆαžšβ€‹αž•αŸ’αž‰αžΎαŸ” αž™αžΎαž„αž“αžΉαž„αž”αŸ’αžšαžΎ αžŸαŸ’αž‘αžΆαžαŸ‹αžŠαŸ„αž™αžŸαžΆαžšαžαŸ‚αžαŸ’αž‰αž»αŸ†αžŸαŸ’αžšαž›αžΆαž‰αŸ‹ Ruby αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž’αŸ’αž“αž€αž’αžΆαž…αž”αŸ’αžšαžΎ Logstash αž¬αž•αŸ’αž‰αžΎαž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αž‘αŸ…αž€αžΆαž“αŸ‹ kinesis αžŠαŸ„αž™αž•αŸ’αž‘αžΆαž›αŸ‹αŸ” αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸ Fluentd αž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžαžΆαž˜αžœαž·αž’αžΈαž‡αžΆαž…αŸ’αžšαžΎαž“ αžαŸ’αž‰αž»αŸ†αž“αžΉαž„αž”αŸ’αžšαžΆαž”αŸ‹αž’αŸ’αž“αž€αž’αŸ†αž–αžΈ docker αž–αŸ’αžšαŸ„αŸ‡αžœαžΆαžŸαžΆαž˜αž‰αŸ’αž‰ αž“αž·αž„αž„αžΆαž™αžŸαŸ’αžšαž½αž›αŸ”

αžŠαŸ†αž”αžΌαž„αž™αžΎαž„αžαŸ’αžšαžΌαžœαž€αžΆαžšαž―αž€αžŸαžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ fluent.conf αŸ” αž”αž„αŸ’αž€αžΎαžαžœαžΆ αž αžΎαž™αž”αž“αŸ’αžαŸ‚αž˜αž”αŸ’αžšαž—αž–αŸ–

αž”αŸ’αžšαž—αŸαž‘ αž‘αŸ…αž˜αž»αž
αž€αŸ†αž–αž„αŸ‹αž•αŸ‚ 24224
αž…αž„ ៩

αž₯αž‘αžΌαžœαž“αŸαŸ‡αž’αŸ’αž“αž€αž’αžΆαž…αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸ Fluentd αŸ” αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαž€αžΆαžšαž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž€αž˜αŸ’αžšαž·αžαžαŸ’αž–αžŸαŸ‹αž”αž“αŸ’αžαŸ‚αž˜αž‘αŸ€αž αžŸαžΌαž˜αž…αžΌαž›αž‘αŸ…αž€αžΆαž“αŸ‹ αžŠαž»αž€αž‘αŸαžšαž αžΆαž”αŸ‹ αž˜αžΆαž“αž€αžΆαžšαžŽαŸ‚αž“αžΆαŸ†αž›αž˜αŸ’αž’αž·αž αžšαž½αž˜αž‘αžΆαŸ†αž„αžšαž”αŸ€αž”αž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αžšαžΌαž”αž—αžΆαž–αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ”

$ docker run 
  -d 
  -p 24224:24224 
  -p 24224:24224/udp 
  -v /data:/fluentd/log 
  -v <PATH-TO-FLUENT-CONF>:/fluentd/etc fluentd 
  -c /fluentd/etc/fluent.conf
  fluent/fluentd:stable

αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αž“αŸαŸ‡αž”αŸ’αžšαžΎαž•αŸ’αž›αžΌαžœ /fluentd/log αžŠαžΎαž˜αŸ’αž”αžΈαžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αž˜αž»αž“αž–αŸαž›αž•αŸ’αž‰αžΎαŸ” αž’αŸ’αž“αž€β€‹αž’αžΆαž…β€‹αž’αŸ’αžœαžΎβ€‹αžŠαŸ„αž™β€‹αž‚αŸ’αž˜αžΆαž“β€‹αžœαžΆ αž”αŸ‰αž»αž“αŸ’αžαŸ‚β€‹αž”αž“αŸ’αž‘αžΆαž”αŸ‹β€‹αž˜αž€β€‹αž“αŸ…β€‹αž–αŸαž›β€‹αžŠαŸ‚αž›β€‹αž’αŸ’αž“αž€β€‹αž…αžΆαž”αŸ‹αž•αŸ’αžŠαžΎαž˜β€‹αž‘αžΎαž„β€‹αžœαž·αž‰ αž’αŸ’αž“αž€β€‹αž’αžΆαž…β€‹αž”αžΆαžαŸ‹αž”αž„αŸ‹β€‹αž’αŸ’αžœαžΈβ€‹αž‚αŸ’αžšαž”αŸ‹β€‹αž™αŸ‰αžΆαž„β€‹αžŠαŸ‚αž›β€‹αž”αžΆαž“β€‹αž‘αž»αž€β€‹αž€αŸ’αž“αž»αž„β€‹αžƒαŸ’αž›αžΆαŸ†αž„β€‹αžŸαž˜αŸ’αž„αžΆαžαŸ‹β€‹αž‡αžΆαž˜αž½αž™β€‹αž“αžΉαž„β€‹αž€αž˜αŸ’αž›αžΆαŸ†αž„β€‹αž–αž›αž€αž˜αŸ’αž˜αŸ” αž’αŸ’αž“αž€αž€αŸαž’αžΆαž…αž”αŸ’αžšαžΎαž…αŸ’αžšαž€αžŽαžΆαž˜αž½αž™αž€αŸαž”αžΆαž“αžŠαŸ‚αžš 24224 αž‚αžΊαž‡αžΆαž…αŸ’αžšαž€ Fluentd αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜αŸ”

αž₯αž‘αžΌαžœαž“αŸαŸ‡ αž™αžΎαž„αž˜αžΆαž“ Fluentd αž€αŸ†αž–αž»αž„αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš αž™αžΎαž„αž’αžΆαž…αž•αŸ’αž‰αžΎαž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αž“αŸ…αž‘αžΈαž“αŸ„αŸ‡αŸ” αž‡αžΆαž’αž˜αŸ’αž˜αžαžΆαž™αžΎαž„αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš Nginx αž“αŸ…αž€αŸ’αž“αž»αž„ Docker container αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαž“αŸαŸ‡ Docker αž˜αžΆαž“αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž”αž‰αŸ’αž‡αžΆαž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αžŠαžΎαž˜αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ FluentdαŸ–

$ docker run 
--log-driver=fluentd 
--log-opt fluentd-address=<FLUENTD-SERVER-ADDRESS>
--log-opt tag="{{.Name}}" 
-v /some/content:/usr/share/nginx/html:ro 
-d 
nginx

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš Nginx αžαž»αžŸαž‚αŸ’αž“αžΆαž’αŸ’αž“αž€αž’αžΆαž…αž”αŸ’αžšαžΎαž―αž€αžŸαžΆαžšαž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Fluentd αž˜αžΆαž“ αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž‡αŸ†αž“αž½αž™αž€αž“αŸ’αž‘αž»αž™αž―αž€αžŸαžΆαžš.

αžαŸ„αŸ‡αž”αž“αŸ’αžαŸ‚αž˜αž€αžΆαžšαž‰αŸ‚αž€αž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αžŠαŸ‚αž›αž”αžΆαž“αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžαžΆαž„αž›αžΎαž‘αŸ…αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžŸαŸ’αž‘αžΆαžαŸ‹αž‡αŸ†αž“αžΆαž‰αŸ–

<filter YOUR-NGINX-TAG.*>
  @type parser
  key_name log
  emit_invalid_record_to_error false
  <parse>
    @type json
  </parse>
</filter>

αž“αž·αž„αž€αžΆαžšαž•αŸ’αž‰αžΎαž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αž‘αŸ… Kinesis αžŠαŸ„αž™αž”αŸ’αžšαžΎ αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž‡αŸ†αž“αž½αž™ kinesis firehose:

<match YOUR-NGINX-TAG.*>
    @type kinesis_firehose
    region region
    delivery_stream_name <YOUR-KINESIS-STREAM-NAME>
    aws_key_id <YOUR-AWS-KEY-ID>
    aws_sec_key <YOUR_AWS-SEC_KEY>
</match>

Athena

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž”αžΆαž“αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‚αŸ’αžšαž”αŸ‹αž™αŸ‰αžΆαž„αž”αžΆαž“αžαŸ’αžšαžΉαž˜αžαŸ’αžšαžΌαžœ αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž˜αž½αž™αžŸαž“αŸ’αž‘αž»αŸ‡ (αžαžΆαž˜αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜ αž€αŸ†αžŽαžαŸ‹αžαŸ’αžšαžΆ Kinesis αž”αžΆαž“αž‘αž‘αž½αž›αž‘αž·αž“αŸ’αž“αž“αŸαž™αž˜αŸ’αžαž„αžšαŸ€αž„αžšαžΆαž›αŸ‹ 10 αž“αžΆαž‘αžΈαž˜αŸ’αžαž„) αž’αŸ’αž“αž€αž‚αž½αžšαžαŸ‚αžƒαžΎαž‰αž―αž€αžŸαžΆαžšαž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αž“αŸ…αž€αŸ’αž“αž»αž„ S3 αŸ” αž“αŸ…αž€αŸ’αž“αž»αž„αž˜αŸ‰αžΊαž“αž»αž™ "αž€αžΆαžšαžαŸ’αžšαž½αžαž–αž·αž“αž·αžαŸ’αž™" αž“αŸƒ Kinesis Firehose αž’αŸ’αž“αž€αž’αžΆαž…αž˜αžΎαž›αžƒαžΎαž‰αž…αŸ†αž“αž½αž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž”αžΆαž“αž€αžαŸ‹αžαŸ’αžšαžΆαž“αŸ…αž€αŸ’αž“αž»αž„ S3 αž€αŸαžŠαžΌαž…αž‡αžΆαž€αŸ†αž αž»αžŸαž•αž„αžŠαŸ‚αžšαŸ” αž€αž»αŸ†αž—αŸ’αž›αŸαž…αž•αŸ’αžαž›αŸ‹αžŸαž·αž‘αŸ’αž’αž·αžŸαžšαžŸαŸαžšαž‘αŸ…αž€αžΆαž“αŸ‹αž’αž»αž„ S3 αž‘αŸ…αž€αžΆαž“αŸ‹αžαž½αž“αžΆαž‘αžΈ KinesisαŸ” αž”αŸ’αžšαžŸαž·αž“αž”αžΎ Kinesis αž˜αž·αž“αž’αžΆαž…αž‰αŸ‚αž€αž’αŸ’αžœαžΈαž˜αž½αž™αž”αžΆαž“αž‘αŸ αžœαžΆαž“αžΉαž„αž”αž“αŸ’αžαŸ‚αž˜αž€αŸ†αž αž»αžŸαž‘αŸ…αž€αŸ’αž“αž»αž„αž’αž»αž„αžαŸ‚αž˜αž½αž™αŸ”

αž₯αž‘αžΌαžœαž“αŸαŸ‡αž’αŸ’αž“αž€αž’αžΆαž…αž˜αžΎαž›αž‘αž·αž“αŸ’αž“αž“αŸαž™αž“αŸ…αž€αŸ’αž“αž»αž„ Athena αŸ” αž…αžΌαžšαž™αžΎαž„αžŸαŸ’αžœαŸ‚αž„αžšαž€αžŸαŸ†αžŽαžΎαž…αž»αž„αž€αŸ’αžšαŸ„αž™αž”αŸ†αž•αž»αžαžŠαŸ‚αž›αž™αžΎαž„αž”αžΆαž“αžαŸ’αžšαž‘αž”αŸ‹αž€αŸ†αž αž»αžŸαŸ–

SELECT * FROM "db_name"."table_name" WHERE status > 499 ORDER BY created_at DESC limit 10;

αž€αŸ†αž–αž»αž„αžŸαŸ’αž€αŸαž“αžšαžΆαž›αŸ‹αž€αžΆαžšαžŸαŸ’αž“αžΎαžŸαž»αŸ†αž“αžΈαž˜αž½αž™αŸ—

αž₯αž‘αžΌαžœαž“αŸαŸ‡ αž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αžšαž”αžŸαŸ‹αž™αžΎαž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš αž“αž·αž„αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž“αŸ…αž€αŸ’αž“αž»αž„ S3 αž“αŸ…αž€αŸ’αž“αž»αž„ ORC αžŠαŸ„αž™αž”αžΆαž“αž”αž„αŸ’αž αžΆαž”αŸ‹ αž“αž·αž„αžšαž½αž…αžšαžΆαž›αŸ‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαžœαž·αž—αžΆαž‚αŸ” Kinesis Firehose αžαŸ‚αž˜αž‘αžΆαŸ†αž„αžšαŸ€αž”αž…αŸ†αž–αž½αž€αžœαžΆαž‘αŸ…αž€αŸ’αž“αž»αž„αž”αž‰αŸ’αž‡αžΈαžˆαŸ’αž˜αŸ„αŸ‡αžšαŸ€αž„αžšαžΆαž›αŸ‹αž˜αŸ‰αŸ„αž„αŸ” αž‘αŸ„αŸ‡αž™αŸ‰αžΆαž„αžŽαžΆαž€αŸαžŠαŸ„αž™ αžŠαžšαžΆαž”αžŽαžΆαžαžΆαžšαžΆαž„αž˜αž·αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ‚αž„αž…αŸ‚αž€ Athena αž“αžΉαž„αž•αŸ’αž‘αž»αž€αž‘αž·αž“αŸ’αž“αž“αŸαž™αž‚αŸ’αžšαž”αŸ‹αž–αŸαž›αž“αŸ…αž›αžΎαžšαžΆαž›αŸ‹αžŸαŸ†αžŽαžΎ αžŠαŸ„αž™αž˜αžΆαž“αž€αžšαžŽαžΈαž›αžΎαž€αž›αŸ‚αž„αžŠαŸαž€αž˜αŸ’αžšαŸ” αž“αŸαŸ‡αž‚αžΊαž‡αžΆαž”αž‰αŸ’αž αžΆαž’αŸ†αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž αŸαžαž»αž•αž›αž–αžΈαžšαŸ–

  • αž”αžšαž·αž˜αžΆαžŽαž‘αž·αž“αŸ’αž“αž“αŸαž™αž€αŸ†αž–αž»αž„αž€αžΎαž“αž‘αžΎαž„αž₯αžαžˆαž”αŸ‹αžˆαžš αž”αž“αŸ’αžαž™αž›αŸ’αž”αžΏαž“αžŸαŸ†αžŽαž½αžšαŸ”
  • Athena αžαŸ’αžšαžΌαžœβ€‹αž”αžΆαž“β€‹αž…αŸαž‰β€‹αžœαž·αž€αŸ’αž€αž™αž”αžαŸ’αžšβ€‹αžŠαŸ„αž™β€‹αž•αŸ’αž’αŸ‚αž€β€‹αž›αžΎβ€‹αž”αžšαž·αž˜αžΆαžŽβ€‹αž“αŸƒβ€‹αž‘αž·αž“αŸ’αž“αž“αŸαž™β€‹αžŠαŸ‚αž›β€‹αž”αžΆαž“β€‹αžŸαŸ’αž€αŸαž“ αžŠαŸ„αž™β€‹αž˜αžΆαž“β€‹αž’αž”αŸ’αž”αž”αžšαž˜αžΆ 10 MB αž€αŸ’αž“αž»αž„β€‹αž˜αž½αž™β€‹αžŸαŸ†αžŽαžΎαŸ”

αžŠαžΎαž˜αŸ’αž”αžΈαž‡αž½αžŸαž‡αž»αž›αžœαžΆ αž™αžΎαž„αž”αŸ’αžšαžΎ AWS Glue Crawler αžŠαŸ‚αž›αž“αžΉαž„αžšαž»αž€αžšαž€αž‘αž·αž“αŸ’αž“αž“αŸαž™αž“αŸ…αž€αŸ’αž“αž»αž„ S3 αž αžΎαž™αžŸαžšαžŸαŸαžšαž–αŸαžαŸŒαž˜αžΆαž“αž—αžΆαž‚αžαžΆαžŸαž‘αŸ…αž€αžΆαž“αŸ‹ Glue Metastore αŸ” αžœαžΆαž“αžΉαž„αž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž™αžΎαž„αž”αŸ’αžšαžΎαž—αžΆαž‚αžαžΆαžŸαž‡αžΆαžαž˜αŸ’αžšαž„αž“αŸ…αž–αŸαž›αžŸαž½αžš Athena αž αžΎαž™αžœαžΆαž“αžΉαž„αžŸαŸ’αž€αŸαž“αžαŸ‚αžαžαžŠαŸ‚αž›αž”αžΆαž“αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αžŸαŸ†αžŽαž½αžšαž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αŸ”

αž€αžΆαžšαžŠαŸ†αž‘αžΎαž„ Amazon Glue Crawler

Amazon Glue Crawler αžŸαŸ’αž€αŸαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αž’αž»αž„ S3 αž“αž·αž„αž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„αžŠαŸ‚αž›αž˜αžΆαž“αž—αžΆαž‚αžαžΆαžŸαŸ” αž”αž„αŸ’αž€αžΎαž Glue Crawler αž–αžΈαž€αž»αž„αžŸαžΌαž› AWS Glue αž αžΎαž™αž”αž“αŸ’αžαŸ‚αž˜αž’αž»αž„αžŠαŸ‚αž›αž’αŸ’αž“αž€αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αž‘αž·αž“αŸ’αž“αž“αŸαž™αŸ” αž’αŸ’αž“αž€β€‹αž’αžΆαž…β€‹αž”αŸ’αžšαžΎ crawler αž˜αž½αž™β€‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹β€‹αžŠαžΆαž€αŸ‹β€‹αž’αž»αž„β€‹αž‡αžΆβ€‹αž…αŸ’αžšαžΎαž“ αžŠαŸ‚αž›β€‹αž€αŸ’αž“αž»αž„β€‹αž€αžšαžŽαžΈβ€‹αž“αŸαŸ‡β€‹αžœαžΆβ€‹αž“αžΉαž„β€‹αž”αž„αŸ’αž€αžΎαžβ€‹αžαžΆαžšαžΆαž„β€‹αž€αŸ’αž“αž»αž„β€‹αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“β€‹αž‘αž·αž“αŸ’αž“αž“αŸαž™β€‹αžŠαŸ‚αž›β€‹αž”αžΆαž“β€‹αž”αž‰αŸ’αž‡αžΆαž€αŸ‹β€‹αž‡αžΆαž˜αž½αž™β€‹αž“αžΉαž„β€‹αžˆαŸ’αž˜αŸ„αŸ‡β€‹αžŠαŸ‚αž›β€‹αžαŸ’αžšαžΌαžœβ€‹αž‚αŸ’αž“αžΆβ€‹αž“αžΉαž„β€‹αžˆαŸ’αž˜αŸ„αŸ‡β€‹αžšαž”αžŸαŸ‹β€‹αž’αž»αž„αŸ” αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž˜αžΆαž“αž‚αž˜αŸ’αžšαŸ„αž„αž”αŸ’αžšαžΎαž‘αž·αž“αŸ’αž“αž“αŸαž™αž“αŸαŸ‡αž‡αžΆαž”αŸ’αžšαž…αžΆαŸ† αžαŸ’αžšαžΌαžœαž”αŸ’αžšαžΆαž€αžŠαžαžΆαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž€αžΆαž›αžœαž·αž—αžΆαž‚αž“αŸƒαž€αžΆαžšαž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžšαž”αžŸαŸ‹ Crawler αž±αŸ’αž™αžŸαž˜αž“αžΉαž„αžαž˜αŸ’αžšαžΌαžœαž€αžΆαžšαžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ” αž™αžΎαž„αž”αŸ’αžšαžΎ Crawler αž˜αž½αž™αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžαžΆαžšαžΆαž„αž‘αžΆαŸ†αž„αž’αžŸαŸ‹ αžŠαŸ‚αž›αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžšαŸ€αž„αžšαžΆαž›αŸ‹αž˜αŸ‰αŸ„αž„αŸ”

αžαžΆαžšαžΆαž„αž”αŸ‚αž„αž…αŸ‚αž€

αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž–αžΈαž€αžΆαžšαž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŠαŸ†αž”αžΌαž„αžšαž”αžŸαŸ‹ crawler αžαžΆαžšαžΆαž„αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αž»αž„αžŸαŸ’αž€αŸαž“αž“αžΈαž˜αž½αž™αŸ—αž‚αž½αžšαžαŸ‚αž”αž„αŸ’αž αžΆαž‰αž“αŸ…αž€αŸ’αž“αž»αž„αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ‚αž›αž”αžΆαž“αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αŸ” αž”αžΎαž€αž€αž»αž„αžŸαžΌαž› Athena αž αžΎαž™αžŸαŸ’αžœαŸ‚αž„αžšαž€αžαžΆαžšαžΆαž„αžŠαŸ‚αž›αž˜αžΆαž“αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αŸ” αžαŸ„αŸ‡β€‹αžŸαžΆαž€β€‹αž’αžΆαž“β€‹αž”αž“αŸ’αžαž·αž…β€‹αž˜αžΎαž›αŸ–

SELECT * FROM "default"."part_demo_kinesis_bucket"
WHERE(
  partition_0 = '2019' AND
  partition_1 = '04' AND
  partition_2 = '08' AND
  partition_3 = '06'
  );

αžŸαŸ†αžŽαž½αžšαž“αŸαŸ‡αž“αžΉαž„αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸαž€αŸ†αžŽαžαŸ‹αžαŸ’αžšαžΆαž‘αžΆαŸ†αž„αž’αžŸαŸ‹αžŠαŸ‚αž›αž‘αž‘αž½αž›αž”αžΆαž“αž“αŸ…αž…αž“αŸ’αž›αŸ„αŸ‡αž˜αŸ‰αŸ„αž„ 6 αž–αŸ’αžšαžΉαž€ αžŠαž›αŸ‹ 7 αž–αŸ’αžšαžΉαž€ αž“αŸ…αžαŸ’αž„αŸƒαž‘αžΈ 8 αžαŸ‚αž˜αŸαžŸαžΆ αž†αŸ’αž“αžΆαŸ† 2019αŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚ αžαžΎβ€‹αžœαžΆβ€‹αž˜αžΆαž“β€‹αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–β€‹αž‡αžΆαž„β€‹αž€αžΆαžšβ€‹αž’αžΆαž“β€‹αž–αžΈβ€‹αžαžΆαžšαžΆαž„β€‹αžŠαŸ‚αž›β€‹αž˜αž·αž“β€‹αž˜αžΆαž“β€‹αž—αžΆαž‚β€‹αž…αŸ’αžšαžΎαž“β€‹αž‘αŸ…β€‹αž‘αŸ€αžβ€‹? αžαŸ„αŸ‡αžŸαŸ’αžœαŸ‚αž„αž™αž›αŸ‹ αž“αž·αž„αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸαž€αŸ†αžŽαžαŸ‹αžαŸ’αžšαžΆαžŠαžΌαž…αž‚αŸ’αž“αžΆ αžŠαŸ„αž™αžαŸ’αžšαž„αž–αž½αž€αžœαžΆαžαžΆαž˜αž–αŸαž›αžœαŸαž›αžΆαŸ–

αž€αžΆαžšαžœαž·αž—αžΆαž‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αžŠαŸ„αž™αž”αŸ’αžšαžΎ Amazon Athena αž“αž·αž„ Cube.js

3.59 αžœαž·αž“αžΆαž‘αžΈ αž“αž·αž„ 244.34 αž˜αŸαž€αžΆαž”αŸƒαž“αŸƒαž‘αž·αž“αŸ’αž“αž“αŸαž™αž“αŸ…αž›αžΎαžŸαŸ†αžŽαž»αŸ†αž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ‚αž›αž˜αžΆαž“αž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αžαŸ’αžšαžΉαž˜αžαŸ‚αž˜αž½αž™αžŸαž”αŸ’αžαžΆαž αŸαž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αŸ” αžαŸ„αŸ‡αžŸαžΆαž€αž›αŸ’αž”αž„αžαž˜αŸ’αžšαž„αžαžΆαž˜αž—αžΆαž‚αŸ–

αž€αžΆαžšαžœαž·αž—αžΆαž‚αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» Nginx αžŠαŸ„αž™αž”αŸ’αžšαžΎ Amazon Athena αž“αž·αž„ Cube.js

αž›αžΏαž“αž‡αžΆαž„αž”αž“αŸ’αžαž·αž… αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžŸαŸ†αžαžΆαž“αŸ‹αž”αŸ†αž•αž»αž - αž‘αž·αž“αŸ’αž“αž“αŸαž™αžαŸ’αžšαžΉαž˜αžαŸ‚ 1.23 αž˜αŸαž€αžΆαž”αŸƒ! αžœαžΆαž“αžΉαž„αž˜αžΆαž“αžαž˜αŸ’αž›αŸƒαžαŸ„αž€αž‡αžΆαž„αž“αŸαŸ‡ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž˜αž·αž“αž˜αŸ‚αž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αž”αŸ’αž”αž”αžšαž˜αžΆ 10 αž˜αŸαž αŸ’αž‚αžΆαž”αŸƒαž€αŸ’αž“αž»αž„αž˜αž½αž™αžŸαŸ†αžŽαžΎαž€αŸ’αž“αž»αž„αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžαž˜αŸ’αž›αŸƒαŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžœαžΆαž“αŸ…αžαŸ‚αž”αŸ’αžšαžŸαžΎαžšαž‡αžΆαž„αž˜αž»αž“ αž αžΎαž™αž“αŸ…αž›αžΎαžŸαŸ†αžŽαž»αŸ†αž‘αž·αž“αŸ’αž“αž“αŸαž™αž’αŸ† αž—αžΆαž–αžαž»αžŸαž‚αŸ’αž“αžΆαž“αžΉαž„αž€αžΆαž“αŸ‹αžαŸ‚αž‚αž½αžšαž’αŸ„αž™αž…αžΆαž”αŸ‹αž’αžΆαžšαž˜αŸ’αž˜αžŽαŸαŸ”

αž”αž„αŸ’αž€αžΎαžαž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αžŠαŸ„αž™αž”αŸ’αžšαžΎ Cube.js

αžŠαžΎαž˜αŸ’αž”αžΈαž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„ αž™αžΎαž„αž”αŸ’αžšαžΎαž€αŸ’αžšαž”αžαŸαžŽαŸ’αžŒαžœαž·αž—αžΆαž‚ Cube.js αŸ” αžœαžΆβ€‹αž˜αžΆαž“β€‹αž˜αž»αžαž„αžΆαžšβ€‹αž…αŸ’αžšαžΎαž“β€‹αžŽαžΆαžŸαŸ‹ αž”αŸ‰αž»αž“αŸ’αžαŸ‚β€‹αž™αžΎαž„β€‹αž…αžΆαž”αŸ‹β€‹αž’αžΆαžšαž˜αŸ’αž˜αžŽαŸβ€‹αž›αžΎβ€‹αž–αžΈαžšαŸ– αžŸαž˜αžαŸ’αžαž—αžΆαž–β€‹αž€αŸ’αž“αž»αž„β€‹αž€αžΆαžšβ€‹αž”αŸ’αžšαžΎβ€‹αž—αžΆαž‚β€‹αžαžΆαžŸβ€‹αžŠαŸ„αž™β€‹αžŸαŸ’αžœαŸαž™β€‹αž”αŸ’αžšαžœαžαŸ’αžαž· αž“αž·αž„β€‹αž€αžΆαžšβ€‹αž”αŸ’αžšαž˜αžΌαž›β€‹αž‘αž·αž“αŸ’αž“αž“αŸαž™β€‹αž‡αžΆαž˜αž»αž“αŸ” αžœαžΆαž”αŸ’αžšαžΎαž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž‘αž·αž“αŸ’αž“αž“αŸαž™ αž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž‘αž·αž“αŸ’αž“αž“αŸαž™αžŸαžšαžŸαŸαžšαž€αŸ’αž“αž»αž„ Javascript αžŠαžΎαž˜αŸ’αž”αžΈαž”αž„αŸ’αž€αžΎαž SQL αž“αž·αž„αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αžŸαŸ†αžŽαž½αžšαž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αŸ” αž™αžΎαž„αž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αžαŸ’αžšαžΌαžœαž…αž„αŸ’αž’αž»αž›αž”αž„αŸ’αž αžΆαž‰αž–αžΈαžšαž”αŸ€αž”αž”αŸ’αžšαžΎαžαž˜αŸ’αžšαž„αž—αžΆαž‚αžαžΆαžŸαž“αŸ…αž€αŸ’αž“αž»αž„αž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž‘αž·αž“αŸ’αž“αž“αŸαž™αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αŸ”

αžαŸ„αŸ‡αž”αž„αŸ’αž€αžΎαžαž€αž˜αŸ’αž˜αžœαž·αž’αžΈ Cube.js αžαŸ’αž˜αžΈαŸ” αžŠαŸ„αž™αžŸαžΆαžšαž™αžΎαž„αž€αŸ†αž–αž»αž„αž”αŸ’αžšαžΎαž‡αž„αŸ‹ AWS αžšαž½αž…αž αžΎαž™ αžœαžΆαž‡αžΆαž‘αžΌαž‡αžΈαžαž›αž€αŸ’αž“αž»αž„αž€αžΆαžšαž”αŸ’αžšαžΎ Lambda αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™αŸ” αž’αŸ’αž“αž€αž’αžΆαž…αž”αŸ’αžšαžΎαž‚αŸ†αžšαžΌαžšαž αŸαžŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‡αŸ†αž“αžΆαž“αŸ‹ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž˜αžΆαž“αž‚αž˜αŸ’αžšαŸ„αž„αžšαŸ€αž”αž…αŸ†αž€αž˜αŸ’αž˜αžœαž·αž’αžΈ Cube.js backend αž“αŸ…αž€αŸ’αž“αž»αž„ Heroku ឬ DockerαŸ” αž―αž€αžŸαžΆαžšαž–αž·αž–αžŽαŸŒαž“αžΆαž’αŸ†αž–αžΈαž’αŸ’αž“αž€αžŠαž‘αŸƒ αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžšαŸ’αžαž”αž„αŸ’αž αŸ„αŸ‡.

$ npm install -g cubejs-cli
$ cubejs create nginx-log-analytics -t serverless -d athena

αž’αžαŸαžšαž”αžšαž·αžŸαŸ’αžαžΆαž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎαžŠαžΎαž˜αŸ’αž”αžΈαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž€αžΆαžšαž…αžΌαž›αž”αŸ’αžšαžΎαž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αž“αŸ…αž€αŸ’αž“αž»αž„ cube.js αŸ” αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž—αŸ’αž›αžΎαž„αž“αžΉαž„αž”αž„αŸ’αž€αžΎαžαž―αž€αžŸαžΆαžš .env αžŠαŸ‚αž›αž’αŸ’αž“αž€αž’αžΆαž…αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αžŸαŸ„αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ Athena.

αž₯αž‘αžΌαžœαž“αŸαŸ‡αž™αžΎαž„αžαŸ’αžšαžΌαžœαž€αžΆαžš αž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ‚αž›αž€αŸ’αž“αž»αž„αž“αŸ„αŸ‡αž™αžΎαž„αž“αžΉαž„αž”αž„αŸ’αž αžΆαž‰αž™αŸ‰αžΆαž„αž…αŸ’αž”αžΆαžŸαŸ‹αž–αžΈαžšαž”αŸ€αž”αžŠαŸ‚αž›αž€αŸ†αžŽαžαŸ‹αž αŸαžαž»αžšαž”αžŸαŸ‹αž™αžΎαž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αžšαž€αŸ’αžŸαžΆαž‘αž»αž€αŸ” αž“αŸ…αž‘αžΈαž“αŸ„αŸ‡ αž’αŸ’αž“αž€αž€αŸαž’αžΆαž…αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž–αžΈαžšαž”αŸ€αž”αž‚αžŽαž“αžΆαž˜αŸ‰αŸ‚αžαŸ’αžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž•αž„αžŠαŸ‚αžšαŸ”

αž“αŸ…αž€αŸ’αž“αž»αž„αžαž schemaαž”αž„αŸ’αž€αžΎαžαž―αž€αžŸαžΆαžš Logs.js. αž“αŸαŸ‡αž‚αžΊαž‡αžΆαž‚αŸ†αžšαžΌαž‘αž·αž“αŸ’αž“αž“αŸαž™αž§αž‘αžΆαž αžšαžŽαŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹ nginxαŸ–

αž›αŸαžαž€αžΌαžŠαž‚αŸ†αžšαžΌ

const partitionFilter = (from, to) => `
    date(from_iso8601_timestamp(${from})) <= date_parse(partition_0 || partition_1 || partition_2, '%Y%m%d') AND
    date(from_iso8601_timestamp(${to})) >= date_parse(partition_0 || partition_1 || partition_2, '%Y%m%d')
    `

cube(`Logs`, {
  sql: `
  select * from part_demo_kinesis_bucket
  WHERE ${FILTER_PARAMS.Logs.createdAt.filter(partitionFilter)}
  `,

  measures: {
    count: {
      type: `count`,
    },

    errorCount: {
      type: `count`,
      filters: [
        { sql: `${CUBE.isError} = 'Yes'` }
      ]
    },

    errorRate: {
      type: `number`,
      sql: `100.0 * ${errorCount} / ${count}`,
      format: `percent`
    }
  },

  dimensions: {
    status: {
      sql: `status`,
      type: `number`
    },

    isError: {
      type: `string`,
      case: {
        when: [{
          sql: `${CUBE}.status >= 400`, label: `Yes`
        }],
        else: { label: `No` }
      }
    },

    createdAt: {
      sql: `from_unixtime(created_at)`,
      type: `time`
    }
  }
});

αž“αŸ…αž‘αžΈαž“αŸαŸ‡αž™αžΎαž„αž€αŸ†αž–αž»αž„αž”αŸ’αžšαžΎαž’αžαŸαžš FILTER_PARAMSαžŠαžΎαž˜αŸ’αž”αžΈαž”αž„αŸ’αž€αžΎαžαžŸαŸ†αžŽαž½αžš SQL αž‡αžΆαž˜αž½αž™αžαž˜αŸ’αžšαž„αž—αžΆαž‚αžαžΆαžŸαŸ”

αž™αžΎαž„αž€αŸαž”αžΆαž“αž€αŸ†αžŽαžαŸ‹αž˜αŸ‰αŸ‚αžαŸ’αžš αž“αž·αž„αž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžšαžŠαŸ‚αž›αž™αžΎαž„αž…αž„αŸ‹αž”αž„αŸ’αž αžΆαž‰αž“αŸ…αž›αžΎαž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„ αž“αž·αž„αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž€αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αž‡αžΆαž˜αž»αž“αŸ” Cube.js αž“αžΉαž„αž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„αž”αž“αŸ’αžαŸ‚αž˜αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ‚αž›αž”αžΆαž“αž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αž‡αžΆαž˜αž»αž“ αž αžΎαž™αž“αžΉαž„αž’αŸ’αžœαžΎαž”αž…αŸ’αž…αž»αž”αŸ’αž”αž“αŸ’αž“αž—αžΆαž–αž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αž“αŸ…αž–αŸαž›αžœαžΆαž˜αž€αžŠαž›αŸ‹αŸ” αž“αŸαŸ‡αž˜αž·αž“αžαŸ’αžšαžΉαž˜αžαŸ‚αž”αž„αŸ’αž€αžΎαž“αž›αŸ’αž”αžΏαž“αžŸαŸ†αžŽαž½αžšαž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αž‘αŸ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžαŸ‚αž˜αž‘αžΆαŸ†αž„αž€αžΆαžαŸ‹αž”αž“αŸ’αžαž™αž€αžΆαžšαž…αŸ†αžŽαžΆαž™αž›αžΎαž€αžΆαžšαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹ Athena αž•αž„αžŠαŸ‚αžšαŸ”

αžαŸ„αŸ‡αž”αž“αŸ’αžαŸ‚αž˜αž–αŸαžαŸŒαž˜αžΆαž“αž“αŸαŸ‡αž‘αŸ…αž€αŸ’αž“αž»αž„αž―αž€αžŸαžΆαžšαž‚αŸ’αžšαŸ„αž„αž€αžΆαžšαžŽαŸαž‘αž·αž“αŸ’αž“αž“αŸαž™αŸ–

preAggregations: {
  main: {
    type: `rollup`,
    measureReferences: [count, errorCount],
    dimensionReferences: [isError, status],
    timeDimensionReference: createdAt,
    granularity: `day`,
    partitionGranularity: `month`,
    refreshKey: {
      sql: FILTER_PARAMS.Logs.createdAt.filter((from, to) => 
        `select
           CASE WHEN from_iso8601_timestamp(${to}) + interval '3' day > now()
           THEN date_trunc('hour', now()) END`
      )
    }
  }
}

αž™αžΎαž„αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αž‚αŸ†αžšαžΌαž“αŸαŸ‡αžαžΆ αžœαžΆαž…αžΆαŸ†αž”αžΆαž…αŸ‹αž€αŸ’αž“αž»αž„αž€αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž‘αž·αž“αŸ’αž“αž“αŸαž™αž‡αžΆαž˜αž»αž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž˜αŸ‰αŸ‚αžαŸ’αžšαž‘αžΆαŸ†αž„αž’αžŸαŸ‹αžŠαŸ‚αž›αž”αžΆαž“αž”αŸ’αžšαžΎ αž αžΎαž™αž”αŸ’αžšαžΎαž€αžΆαžšαž”αŸ‚αž„αž…αŸ‚αž€αžαžΆαž˜αžαŸ‚αŸ” αž€αžΆαžšαž”αŸ‚αž„αž…αŸ‚αž€αž‡αžΆαž˜αž»αž“αž“αŸƒαž€αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ† αž’αžΆαž…αž”αž„αŸ’αž€αžΎαž“αž›αŸ’αž”αžΏαž“αž”αŸ’αžšαž˜αžΌαž›αž‘αž·αž“αŸ’αž“αž“αŸαž™ αž“αž·αž„αž€αžΆαžšαž’αŸ’αžœαžΎαž”αž…αŸ’αž…αž»αž”αŸ’αž”αž“αŸ’αž“αž—αžΆαž–αž™αŸ‰αžΆαž„αžŸαŸ†αžαžΆαž“αŸ‹αŸ”

αž₯αž‘αžΌαžœαž“αŸαŸ‡αž™αžΎαž„αž’αžΆαž…αž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž”αžΆαž“!

αž•αŸ’αž“αŸ‚αž€αžαžΆαž„αž€αŸ’αžšαŸ„αž™ Cube.js αž•αŸ’αžαž›αŸ‹ REST API αž“αž·αž„αžŸαŸ†αžŽαž»αŸ†αž“αŸƒαž”αžŽαŸ’αžŽαžΆαž›αŸαž™αž’αžαž·αžαž·αž‡αž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αŸ’αžšαž”αžαŸαžŽαŸ’αžŒαž•αŸ’αž“αŸ‚αž€αžαžΆαž„αž˜αž»αžαžŠαŸαž–αŸαž‰αž“αž·αž™αž˜αŸ” αž™αžΎαž„αž“αžΉαž„αž”αŸ’αžšαžΎαž€αŸ†αžŽαŸ‚ React αžšαž”αžŸαŸ‹αž’αžαž·αžαž·αž‡αž“αžŠαžΎαž˜αŸ’αž”αžΈαž”αž„αŸ’αž€αžΎαžαž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αŸ” Cube.js αž•αŸ’αžαž›αŸ‹αžαŸ‚αž‘αž·αž“αŸ’αž“αž“αŸαž™ αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž™αžΎαž„αž“αžΉαž„αžαŸ’αžšαžΌαžœαž€αžΆαžšαž”αžŽαŸ’αžŽαžΆαž›αŸαž™αžŠαŸ‚αž›αž˜αžΎαž›αžƒαžΎαž‰ - αžαŸ’αž‰αž»αŸ†αž…αžΌαž›αž…αž·αžαŸ’αžαžœαžΆαŸ” αžαžΆαžšαžΆαž„αž‘αžΎαž„αžœαž·αž‰αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž’αŸ’αž“αž€αž’αžΆαž…αž”αŸ’αžšαžΎαžŽαžΆαž˜αž½αž™αŸ”

αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸ Cube.js αž‘αž‘αž½αž›αž™αž€αžŸαŸ†αžŽαžΎαž“αŸ…αž€αŸ’αž“αž»αž„ αž‘αž˜αŸ’αžšαž„αŸ‹ JSONαžŠαŸ‚αž›αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αž–αžΈαž€αžΆαžšαžœαžΆαžŸαŸ‹αžœαŸ‚αž„αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž€αžΆαžšαŸ” αž§αž‘αžΆαž αžšαžŽαŸ αžŠαžΎαž˜αŸ’αž”αžΈαž‚αžŽαž“αžΆαž…αŸ†αž“αž½αž“αž€αŸ†αž αž»αžŸαžŠαŸ‚αž› Nginx αž•αŸ’αžαž›αŸ‹αž±αŸ’αž™αž€αŸ’αž“αž»αž„αž˜αž½αž™αžαŸ’αž„αŸƒ αž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαž•αŸ’αž‰αžΎαžŸαŸ†αžŽαžΎαžαžΆαž„αž€αŸ’αžšαŸ„αž˜αŸ–

{
  "measures": ["Logs.errorCount"],
  "timeDimensions": [
    {
      "dimension": "Logs.createdAt",
      "dateRange": ["2019-01-01", "2019-01-07"],
      "granularity": "day"
    }
  ]
}

αžαŸ„αŸ‡αžŠαŸ†αž‘αžΎαž„αž€αž˜αŸ’αž˜αžœαž·αž’αžΈ Cube.js αž“αž·αž„αž”αžŽαŸ’αžŽαžΆαž›αŸαž™αžŸαž˜αžΆαžŸαž’αžΆαžαž» React αžαžΆαž˜αžšαž™αŸˆ NPMαŸ–

$ npm i --save @cubejs-client/core @cubejs-client/react

αž™αžΎαž„αž“αžΆαŸ†αž…αžΌαž›αžŸαž˜αžΆαžŸαž’αžΆαžαž» cubejs ΠΈ QueryRendererαžŠαžΎαž˜αŸ’αž”αžΈαž‘αžΆαž‰αž™αž€αž‘αž·αž“αŸ’αž“αž“αŸαž™ αž“αž·αž„αž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αŸ–

αž›αŸαžαž€αžΌαžŠαž•αŸ’αž‘αžΆαŸ†αž„αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„

import React from 'react';
import { LineChart, Line, XAxis, YAxis } from 'recharts';
import cubejs from '@cubejs-client/core';
import { QueryRenderer } from '@cubejs-client/react';

const cubejsApi = cubejs(
  'YOUR-CUBEJS-API-TOKEN',
  { apiUrl: 'http://localhost:4000/cubejs-api/v1' },
);

export default () => {
  return (
    <QueryRenderer
      query={{
        measures: ['Logs.errorCount'],
        timeDimensions: [{
            dimension: 'Logs.createdAt',
            dateRange: ['2019-01-01', '2019-01-07'],
            granularity: 'day'
        }]
      }}
      cubejsApi={cubejsApi}
      render={({ resultSet }) => {
        if (!resultSet) {
          return 'Loading...';
        }

        return (
          <LineChart data={resultSet.rawData()}>
            <XAxis dataKey="Logs.createdAt"/>
            <YAxis/>
            <Line type="monotone" dataKey="Logs.errorCount" stroke="#8884d8"/>
          </LineChart>
        );
      }}
    />
  )
}

αž”αŸ’αžšαž—αž– Dashboard αž˜αžΆαž“αž“αŸ… αž”αŸ’αžšαž’αž”αŸ‹αžαŸ’αžŸαžΆαž…αŸ‹αž€αžΌαžŠ.

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹