แ แแแแ แช แฌแแกแ, แแแแแ แชแแฃแแ แแ แแแฃแฅแขแแแ แแ แแแ แฆแแ แฌแงแแ แแก แแแขแแ แแแขแแแแแ, แ แแแแ แแชแแ Prometheus + Grafana, แแแแแแงแแแแแ Nginx-แแก แแฃแจแแแแแก แแแแแขแแ แแแแแกแ แแ แแแแแแแแกแแแแก. แแก แแแ แแ แแแ แแแแขแแ แแแแแขแแ แแแแแกแแแแก แแ แ แแแแฃแ แแ แแจแ แแแแแแขแแแแกแแแแก, แแแแ แแ แแ แช แแกแ แแแกแแฎแแ แฎแแแแแ แแกแขแแ แแฃแแ แแแแแแแแกแแแแก. แแแแแกแแแแ แแแแฃแแแ แฃแ แ แแกแฃแ แกแแ, nginx logs-แแก แแแแแชแแแแแแก แแแชแฃแแแแ แกแฌแ แแคแแ แแแ แแแแ แแ แแแแ แ แแแแแแแแแ แแแแแชแแแแแแก แแแกแแแแแแแแแแแแ, แแแแแแฃแ แแ แแแแแแงแแแแ แ แแแแ แฃแคแ แ แกแแแชแแแแแแแแฃแแ.
แแ แกแขแแขแแแจแ แแ แแแขแงแแแ, แแฃ แ แแแแ แจแแแแซแแแแ แแแแแแงแแแแ
TL:DR;
แแแคแแ แแแชแแแก แจแแกแแแ แแแแแแแ แฉแแแ แแแงแแแแแ
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-แก แแแแกแแแจแ
แแแแแ แจแแแฅแแแแ แชแฎแ แแแ แแแแแแจแ แแฃแ แแแแแแแกแแแแก. แแก แกแแญแแ แแ แ แแแแ แช แฌแแ แแกแแแแก, แแกแแแ แแแแฎแแแกแแแแก, แแฃ แแแแแแแ 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 Stream-แแก แจแแฅแแแ
Kinesis Firehose แแแฌแแ แก Nginx-แแแ S3-แจแ แแแฆแแแฃแ แแแแแชแแแแแก แจแแ แฉแแฃแ แคแแ แแแขแจแ, แแแงแแคแก แแแ แแแ แแฅแขแแ แแแแแแ YYYY/MM/DD/HH แคแแ แแแขแจแ. แแก แแแแแแแแแแแแ แแแแแชแแแแแแก แฌแแแแแฎแแแกแแก. แแฅแแแ, แ แ แแฅแแ แฃแแแ, แจแแแแซแแแแ แแแฌแแ แแ แแแ แแแแแ S3-แแ fluentd-แแแ, แแแแ แแ แแ แจแแแแฎแแแแแจแ แแแแแฌแแแ แแแฌแแ แแ JSON แแ แแก แแ แแแคแแฅแขแฃแ แแ แคแแแแแแแก แแแแ แแแแแก แแแแ. แแแ แแ แแแแกแ, PrestoDB แแ Athena-แก แแแแแงแแแแแแกแแก, JSON แแ แแก แงแแแแแแ แแแแ แแแแแชแแแแ แคแแ แแแขแ. แแกแ แ แแ, แแแฎแกแแแแ Kinesis Firehose แแแแกแแแ, แแแแฌแแแแฃแแแ "แแแฌแแแแแแก แแแแแแแก แจแแฅแแแ", "แแแฌแแแแแแก" แแแแจแ แแแ แฉแแแ "แแแ แแแแแ แ PUT":
แจแแแแแ แฉแแแแ แแจแ แแแ แฉแแแ โแฉแแฌแแ แแก แคแแ แแแขแแก แแแแแแ แขแแชแแโ - โแฉแแ แแฃแแแโ แแ แฉแแฌแแ แแก แคแแ แแแขแแ แแแ แฉแแแ โApache ORCโ. แแแแแแ แแ แแแแแแแก แแแฎแแแแแ
แฉแแแ แแแ แฉแแแ S3 แจแแกแแแแฎแแ แแ แแแแแฃแแก, แ แแแแแแช แแแ แ แจแแแฅแแแแแ. Aws Glue Crawler, แ แแแแแแแช แชแแขแ แแแแแแแแแแแ แแแกแแฃแแ แแ, แแแ แแฃแจแแแแก แแ แแคแแฅแกแแแแ S3 แแแแแฃแแจแ, แแแแขแแ แแแแจแแแแแแแแแแ แแแกแ แชแแ แแแแ แแแขแแแแแ.
แแแ แฉแแแแแ แแแ แแแแขแแแ แจแแแซแแแแ แจแแแชแแแแแก แแฅแแแแ แแแขแแแ แแแแก แแแฎแแแแแ; แแ แฉแแแฃแแแแ แแ แแแงแแแแ แแแแฃแแแกแฎแแแแก. แแแแแแแแแกแฌแแแแ, แ แแ S3 แจแแแฃแแจแแ แแ แแ แแก แฎแแแแแกแแฌแแแแแ, แแแแ แแ ORC แแแแฃแแแกแฎแแแแแ แแงแแแแแก แแจแแแแแฃแ แจแแแฃแแจแแแก.
แแแแแ แแฃแแ
แแฎแแ, แ แแแแกแแช แฉแแแ แแแแแแแแคแแแฃแ แแ แแ แแฃแ แแแแแแแก แจแแแแฎแแ แแ แแแฆแแแ, แฉแแแ แแแญแแ แแแแ แแแแแแแแแก แแแแคแแแฃแ แแชแแ. แฉแแแ แแแแแแแงแแแแแ
แแแ แแแ แ แแแจแ, แฉแแแ แแแญแแ แแแแ fluent.conf แแแแคแแแฃแ แแชแแแก แคแแแแ. แจแแฅแแแแแ แแ แแแแแแขแแ แฌแงแแ แ:
แแแ แขแ 24224
แจแแแแ แ 0.0.0.0
แแฎแแ แแฅแแแ แจแแแแซแแแแ แแแฃแจแแแ 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-แแก แแแแขแแแแแ แจแ, แแ แจแแแแฎแแแแแจแ Docker-แก แแฅแแก แคแแฃแแแขแ-แแก แแแแแแแแก แแ แแแแแ แ:
$ 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-แก แแฅแแก
แแแแแ แแแแแแแขแแ แแแแแ แแแแคแแแฃแ แแ แแแฃแแ แแฃแ แแแแแก แแแแแแแ Fluent-แแก แแแแคแแแฃแ แแชแแแก:
<filter YOUR-NGINX-TAG.*>
@type parser
key_name log
emit_invalid_record_to_error false
<parse>
@type json
</parse>
</filter>
แแ แแฃแ แแแแแแแก แแแแแแแแ Kinesis-แจแ แแแแแงแแแแแแ
<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 แแ แแแแ แแแแฎแแแแแแ.
แแแแก แแแแแกแฌแแ แแแแก แแแแแแ, แฉแแแ แแแงแแแแแ AWS Glue Crawler-แก, แ แแแแแแช แแแแแแแแแแ แแแก แแแแแชแแแแแก S3-แจแ แแ แฉแแฌแแ แก แแแแแงแแคแแก แแแคแแ แแแชแแแก Glue Metastore-แจแ. แแก แกแแจแฃแแแแแแก แแแแแชแแแก แแแแแแแงแแแแ แขแแฎแ แแแ, แ แแแแ แช แคแแแขแ แ Athena-แก แจแแแแแฎแแแกแแก แแ แแก แแฎแแแแ แแแแกแแแแแ แแแก แแแแฎแแแแแจแ แแแแแแแแฃแ แแแ แแฅแขแแ แแแแแก.
Amazon Glue Crawler-แแก แแแงแแแแแ
Amazon Glue Crawler แกแแแแแ แแแก แงแแแแ แแแแแชแแแก S3 แแแแแฃแแจแ แแ แฅแแแแก แชแฎแ แแแแแก แแแแแงแแคแแแแ. แจแแฅแแแแแ Glue Crawler AWS Glue แแแแกแแแแแแ แแ แแแแแแขแแ แแแแแฃแแ, แกแแแแช แแแแฎแแแ แแแแแชแแแแแก. แแฅแแแ แจแแแแซแแแแ แแแแแแงแแแแ แแ แแ แแชแแชแแแ แ แแแแแแแแ แแแแแฃแแแกแแแแก, แแ แจแแแแฎแแแแแจแ แแก แจแแฅแแแแก แชแฎแ แแแแแก แแแแแแแแฃแ แแแแแชแแแแ แแแแแจแ แกแแฎแแแแแแ, แ แแแแแแแช แแแแฎแแแแ แแแแแฃแแแแแก แกแแฎแแแแแก. แแฃ แแ แแแแแชแแแแแแก แ แแแฃแแแ แฃแแแ แแแแแงแแแแแแก แแแแแแแ, แแแ แฌแแฃแแแแ, แ แแ แแแแแแแคแแแฃแ แแ แแ 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 แกแแแแแแแ. แแแแ แแ แ แแแแแแแ แฃแคแ แ แแคแแฅแขแฃแ แแ แแก, แแแแ แ แฃแแ แแแแ แแ แแแแแแฌแแแแแฃแแ แชแฎแ แแแแแแ แแแแฎแแ? แแแแแ แแแแแ แแแแแ แแ แแแแ แฉแแแ แแแแแ แฉแแแแฌแแ แแแ, แแแแคแแแขแ แแ แแกแแแ แแ แแแก แแแจแแฃแแแ:
3.59 แฌแแแ แแ 244.34 แแแแแแแแขแ แแแแแชแแแแแ แแแแแชแแแแ แแแแแแ แแฎแแแแ แแ แแ แแแแ แแก แแฃแ แแแแแแแ. แแชแแแแ แคแแแขแ แ แแแแแงแแคแแก แแแฎแแแแแ:
แชแแขแ แฃแคแ แ แกแฌแ แแคแ, แแแแ แแ แ แแช แแแแแแ แแ - แแฎแแแแ 1.23 แแแแแแแแขแ แแแแแชแแแแแ! แแก แแแแ แแ แแแคแ แแฅแแแแแแ, แ แแ แแ แ แแแแแแฃแ 10 แแแแแแแแขแ แแแแ แแแแฎแแแแแแ แคแแกแจแ. แแแแ แแ แแก แแแแแช แแแแ แแ แฃแแแแแกแแ แแ แแแ แแแแแชแแแแ แแแแ แแแแแจแ แแแแกแฎแแแแแแ แแแแ แแ แฃแคแ แ แจแแแแแแญแแแแ แแฅแแแแ.
แแแคแแก แจแแฅแแแ Cube.js-แแก แแแแแงแแแแแแ
แแแคแแก แแกแแฌแงแแแแ แแแงแแแแแ Cube.js แแแแแแขแแแฃแ แฉแแ แฉแแก. แแแก แแฅแแก แกแแแแแแ แแแแ แ แคแฃแแฅแชแแ, แแแแ แแ แฉแแแ แแแแแแขแแ แแกแแแก แแ แ: แแแแแงแแคแแก แคแแแขแ แแแแก แแแขแแแแขแฃแ แแ แแแแแงแแแแแแก แจแแกแแซแแแแแแแ แแ แแแแแชแแแแ แฌแแแแกแฌแแ แ แแแ แแแแชแแ. แแก แแงแแแแแก แแแแแชแแแแ แกแฅแแแแก
แแแแแ แจแแแฅแแแแ แแฎแแแ 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 แคแแแแก, แ แแแแแจแแช แจแแแแซแแแแ แแแฃแแแแแ แแฅแแแแ แแแกแแฆแแแแแ
แแฎแแ แฉแแแ แแแญแแ แแแแ
แแแ แแฅแขแแ แแแจแ 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`
}
}
});
แแฅ แฉแแแ แแแงแแแแแ แชแแแแแก
แฉแแแ แแกแแแ แแแงแแแแแ แแแขแ แแแแกแ แแ แแแ แแแแขแ แแแก, แ แแแแแแแช แแแแแแ แแแแแแแฉแแแแ แแแคแแแ แแ แแแแฃแแแแแ แฌแแแแกแฌแแ แ แแแ แแแแชแแแแ. 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 backend แฃแแ แฃแแแแแงแแคแก
Cube.js แกแแ แแแ แ แแฆแแแก แแแแฎแแแแแก
{
"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>
);
}}
/>
)
}
แแแคแแก แฌแงแแ แแแแ แฎแแแแแกแแฌแแแแแแ แแฅ
แฌแงแแ แ: www.habr.com