Mion-sgrùdadh log Nginx a’ cleachdadh Amazon Athena agus Cube.js

Mar as trice, bidh toraidhean malairteach no roghainnean stòr fosgailte deiseil, leithid Prometheus + Grafana, air an cleachdadh gus sùil a chumail agus sgrùdadh a dhèanamh air gnìomhachd Nginx. Tha seo na dheagh roghainn airson sgrùdadh no mion-sgrùdadh fìor-ùine, ach chan eil e gu math goireasach airson mion-sgrùdadh eachdraidheil. Air goireas mòr-chòrdte sam bith, tha an àireamh de dhàta bho logaichean nginx a’ fàs gu luath, agus gus sgrùdadh a dhèanamh air mòran dàta, tha e loidsigeach rudeigin nas speisealta a chleachdadh.

San artaigil seo innsidh mi dhut mar as urrainn dhut a chleachdadh Athena gus logaichean a sgrùdadh, a’ toirt Nginx mar eisimpleir, agus seallaidh mi mar a chruinnicheas tu deas-bhòrd anailis bhon dàta seo a’ cleachdadh frèam stòr fosgailte cube.js. Seo an ailtireachd fuasglaidh iomlan:

Mion-sgrùdadh log Nginx a’ cleachdadh Amazon Athena agus Cube.js

TL: DR;
Ceangal ris an deas-bhòrd crìochnaichte.

Airson fiosrachadh a chruinneachadh bidh sinn a’ cleachdadh fileanta, airson giullachd - Firehose dàta AWS Kinesis и Glue AWS, airson stòradh - AWS S3. A’ cleachdadh a’ phasgan seo, faodaidh tu chan e a-mhàin logaichean nginx a stòradh, ach cuideachd tachartasan eile, a bharrachd air logaichean de sheirbheisean eile. Faodaidh tu cuid de phàirtean a chuir an àite an aon seòrsa airson do chruach, mar eisimpleir, faodaidh tu logaichean a sgrìobhadh gu kinesis gu dìreach bho nginx, a’ dol seachad air fileanta, no logstash a chleachdadh airson seo.

A 'cruinneachadh logaichean Nginx

Gu gnàthach, tha logaichean Nginx a’ coimhead rudeigin mar seo:

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" "-"

Faodar am parsadh, ach tha e fada nas fhasa an rèiteachadh Nginx a cheartachadh gus an cruthaich e logaichean ann an 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 airson stòradh

Airson logaichean a stòradh, cleachdaidh sinn S3. Leigidh seo leat logaichean a stòradh agus a sgrùdadh ann an aon àite, oir faodaidh Athena obrachadh le dàta ann an S3 gu dìreach. Nas fhaide air adhart san artaigil innsidh mi dhut mar a chuireas tu ris agus giullachd logaichean gu ceart, ach an toiseach feumaidh sinn bucaid glan ann an S3, anns nach tèid dad sam bith eile a stòradh. Is fhiach beachdachadh ro-làimh dè an roinn anns am bi thu a’ cruthachadh do bhucaid, oir chan eil Athena ri fhaighinn anns a h-uile sgìre.

A’ cruthachadh cuairt ann an consòil Athena

Cruthaichidh sinn clàr ann an Athena airson logaichean. Tha feum air airson an dà chuid sgrìobhadh agus leughadh ma tha thu an dùil Kinesis Firehose a chleachdadh. Fosgail consol Athena agus cruthaich clàr:

Cruthachadh clàr 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');

A 'cruthachadh Kinesis Firehose Stream

Sgrìobhaidh Kinesis Firehose an dàta a fhuaireadh bho Nginx gu S3 anns a’ chruth a chaidh a thaghadh, ga roinn ann an clàran ann an cruth YYYY/MM/DD/HH. Bidh seo feumail nuair a bhios tu a’ leughadh dàta. Faodaidh tu, gu dearbh, sgrìobhadh gu dìreach gu S3 bho fileanta, ach sa chùis seo feumaidh tu JSON a sgrìobhadh, agus tha seo neo-èifeachdach air sgàth cho mòr sa tha na faidhlichean. A bharrachd air an sin, nuair a bhios tu a’ cleachdadh PrestoDB no Athena, is e JSON an cruth dàta as slaodaiche. Mar sin fosgail consol Kinesis Firehose, cliog air “Cruthaich sruth lìbhrigidh”, tagh “PUT dìreach” anns an raon “lìbhrigeadh”:

Mion-sgrùdadh log Nginx a’ cleachdadh Amazon Athena agus Cube.js

Anns an ath tab, tagh "Clàr iompachadh cruth" - "Enabled" agus tagh "Apache ORC" mar an cruth clàraidh. A rèir cuid de rannsachadh Owen O'Malley, is e seo an cruth as fheàrr airson PrestoDB agus Athena. Cleachdaidh sinn an clàr a chruthaich sinn gu h-àrd mar sgeama. Thoir an aire gun urrainn dhut àite S3 sam bith a shònrachadh ann an kinesis; chan eil ach an sgeama air a chleachdadh bhon chlàr. Ach ma shònraicheas tu àite eile airson S3, cha bhith e comasach dhut na clàran seo bhon chlàr seo a leughadh.

Mion-sgrùdadh log Nginx a’ cleachdadh Amazon Athena agus Cube.js

Bidh sinn a 'taghadh S3 airson stòradh agus am bucaid a chruthaich sinn na bu tràithe. Chan urrainn dha Aws Glue Crawler, air am bi mi a’ bruidhinn beagan nas fhaide air adhart, obrachadh le ro-leasachain ann am bucaid S3, agus mar sin tha e cudromach a fàgail falamh.

Mion-sgrùdadh log Nginx a’ cleachdadh Amazon Athena agus Cube.js

Faodar na roghainnean a tha air fhàgail atharrachadh a rèir an luchd agad; mar as trice bidh mi a’ cleachdadh an fheadhainn àbhaisteach. Thoir an aire nach eil teannachadh S3 ri fhaighinn, ach bidh ORC a’ cleachdadh teannachadh dùthchasach gu bunaiteach.

fileanta

A-nis gu bheil sinn air logaichean a stòradh agus a thoirt a-steach, feumaidh sinn rèiteachadh a chuir air dòigh. Cleachdaidh sinn fileanta, oir tha gaol agam air Ruby, ach faodaidh tu Logstash a chleachdadh no logaichean a chuir gu kinesis gu dìreach. Faodar an frithealaiche fileanta a chuir air bhog ann an grunn dhòighean, innsidh mi dhut mu docker oir tha e sìmplidh agus goireasach.

An toiseach, feumaidh sinn am faidhle rèiteachaidh fluent.conf. Cruthaich e agus cuir ris an stòr:

seòrsa air adhart
port 24224
ceangail 0.0.0.0

A-nis faodaidh tu am frithealaiche Fileanta a thòiseachadh. Ma tha feum agad air rèiteachadh nas adhartaiche, rachaibh gu Hub Docker Tha stiùireadh mionaideach ann, a 'toirt a-steach mar a chruinnicheas tu an ìomhaigh agad.

$ 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

Bidh an rèiteachadh seo a’ cleachdadh na slighe /fluentd/log gus logaichean a thasgadh mus tèid an cur. Faodaidh tu a dhèanamh às aonais seo, ach an uairsin nuair a thòisicheas tu a-rithist, faodaidh tu a h-uile càil a chall a tha air a thasgadh le saothair briseadh-cùil. Faodaidh tu cuideachd port sam bith a chleachdadh; Is e 24224 am port bunaiteach Fluentd.

A-nis gu bheil Fluentd againn a’ ruith, is urrainn dhuinn logaichean Nginx a chuir an sin. Mar as trice bidh sinn a’ ruith Nginx ann an soitheach Docker, agus mar sin tha draibhear logaidh dùthchasach aig Docker airson 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

Ma ruitheas tu Nginx ann an dòigh eadar-dhealaichte, faodaidh tu faidhlichean log a chleachdadh, tha Fluentd air plugan earball faidhle.

Nach cuir sinn am parsadh log a chaidh a rèiteachadh gu h-àrd ris an rèiteachadh Fileanta:

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

Agus a 'cur logaichean gu Kinesis a' cleachdadh Luchdaich a-nuas am plugan 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

Ma tha thu air a h-uile càil a rèiteachadh gu ceart, an uairsin às deidh greis (gu gnàthach, fhuair clàran Kinesis dàta aon uair gach 10 mionaidean) bu chòir dhut faidhlichean log fhaicinn ann an S3. Anns a 'chlàr "cumail sùil" de Kinesis Firehose chì thu dè an dàta a tha air a chlàradh ann an S3, a bharrachd air mearachdan. Na dìochuimhnich cothrom sgrìobhte a thoirt don bhucaid S3 gu dreuchd Kinesis. Mura b’ urrainn dha Kinesis rudeigin a pharsadh, cuiridh e na mearachdan ris an aon bhucaid.

A-nis chì thu an dàta ann an Athena. Lorg sinn na h-iarrtasan as ùire air an do thill sinn mearachdan:

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

A’ sganadh a h-uile clàr airson gach iarrtas

A-nis tha na logaichean againn air an giullachd agus air an stòradh ann an S3 ann an ORC, air an teannachadh agus deiseil airson mion-sgrùdadh. Chuir Kinesis Firehose eadhon iad ann an clàran airson gach uair a thìde. Ach, fhad ‘s nach eil am bòrd air a sgaradh, luchdaichidh Athena dàta làn-ùine air a h-uile iarrtas, ach a-mhàin glè ainneamh. Tha seo na dhuilgheadas mòr airson dà adhbhar:

  • Tha meud an dàta a 'sìor fhàs, a' slaodadh sìos cheistean;
  • Tha Athena air a chunntas a rèir na tha de dhàta air a sganadh, le co-dhiù 10 MB gach iarrtas.

Gus seo a chàradh, bidh sinn a’ cleachdadh AWS Glue Crawler, a bhios a’ snàgail an dàta ann an S3 agus a’ sgrìobhadh am fiosrachadh dealachaidh chun Glue Metastore. Leigidh seo leinn sgaraidhean a chleachdadh mar chriathrag nuair a bhios sinn a’ faighneachd Athena, agus cha dèan e sganadh ach air na clàran a chaidh a shònrachadh sa cheist.

A’ stèidheachadh Amazon Glue Crawler

Bidh Amazon Glue Crawler a’ sganadh an dàta gu lèir anns a’ bhucaid S3 agus a’ cruthachadh chlàran le sgaraidhean. Cruthaich Glue Crawler bho chonsail AWS Glue agus cuir bucaid ris far am bi thu a’ stòradh an dàta. Faodaidh tu aon crawler a chleachdadh airson grunn bhucaid, agus mar sin cruthaichidh e clàran anns an stòr-dàta ainmichte le ainmean a tha a rèir ainmean nam bucaidean. Ma tha thu an dùil an dàta seo a chleachdadh gu cunbhalach, bi cinnteach gun cuir thu air dòigh clàr cur air bhog Crawler a fhreagras air na feumalachdan agad. Bidh sinn a 'cleachdadh aon Crawler airson a h-uile clàr, a bhios a' ruith gach uair a thìde.

Bùird air an sgaradh

Às deidh an crawler a chuir air bhog, bu chòir clàran airson gach bucaid a chaidh a sganadh nochdadh anns an stòr-dàta a tha air a shònrachadh anns na roghainnean. Fosgail consol Athena agus lorg am bòrd le logaichean Nginx. Feuchaidh sinn ri rudeigin a leughadh:

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

Taghaidh a’ cheist seo a h-uile clàr a gheibhear eadar 6m agus 7m air 8 Giblean, 2019. Ach dè an ìre nas èifeachdaiche a tha seo na dìreach leughadh bho bhòrd neo-phàirteach? Feuch an lorg sinn agus tagh sinn na h-aon chlàran, gan sìoladh a rèir stampa-ama:

Mion-sgrùdadh log Nginx a’ cleachdadh Amazon Athena agus Cube.js

3.59 diogan agus 244.34 megabytes de dhàta air stòr-dàta le dìreach seachdain de logaichean. Feuchaidh sinn criathrag le sgaradh:

Mion-sgrùdadh log Nginx a’ cleachdadh Amazon Athena agus Cube.js

Beagan nas luaithe, ach nas cudromaiche - dìreach 1.23 megabytes de dhàta! Bhiodh e tòrr na bu shaoire mura biodh e airson na 10 megabytes as ìsle gach iarrtas anns a’ phrìs. Ach tha e tòrr nas fheàrr fhathast, agus air stòran-dàta mòra bidh an eadar-dhealachadh tòrr nas drùidhtiche.

A’ togail deas-bhòrd a’ cleachdadh Cube.js

Gus an deas-bhòrd a chruinneachadh, bidh sinn a’ cleachdadh frèam anailis Cube.js. Tha tòrr ghnìomhan aige, ach tha ùidh againn ann an dhà: an comas sìoltachain sgaradh agus ro-chruinneachadh dàta a chleachdadh gu fèin-ghluasadach. Bidh e a’ cleachdadh sgeama dàta sgeama dàta, sgrìobhte ann an Javascript gus SQL a ghineadh agus ceist stòr-dàta a chuir an gnìomh. Chan fheum sinn ach innse mar a chleachdas sinn an criathrag sgaradh anns an sgeama dàta.

Nach cruthaich sinn tagradh Cube.js ùr. Leis gu bheil sinn mu thràth a’ cleachdadh stac AWS, tha e reusanta Lambda a chleachdadh airson a chleachdadh. Faodaidh tu an teamplaid luath a chleachdadh airson ginealach ma tha thu an dùil aoigheachd a thoirt don backend Cube.js ann an Heroku no Docker. Tha na sgrìobhainnean a’ toirt cunntas air feadhainn eile dòighean aoigheachd.

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

Bithear a’ cleachdadh caochladairean àrainneachd gus ruigsinneachd stòr-dàta a rèiteachadh ann an cube.js. Cruthaichidh an gineadair faidhle .env anns an urrainn dhut na h-iuchraichean agad a shònrachadh airson Athena.

A-nis feumaidh sinn sgeama dàta, anns am bi sinn ag innse gu mionaideach mar a tha na logaichean againn air an stòradh. An sin faodaidh tu cuideachd sònrachadh mar a nì thu àireamhachadh metrics airson deas-bhòrd.

Anns an eòlaire schema, cruthaich faidhle Logs.js. Seo eisimpleir de mhodail dàta airson nginx:

Còd modail

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`
    }
  }
});

An seo tha sinn a 'cleachdadh an caochlaideach FILTER_PARAMSgus ceist SQL a ghineadh le criathrag sgaradh.

Bidh sinn cuideachd a’ suidheachadh na meatrach agus na crìochan a tha sinn airson a thaisbeanadh air an deas-bhòrd agus a’ sònrachadh ro-chruinneachaidhean. Cruthaichidh Cube.js clàran a bharrachd le dàta ro-chruinnichte agus bheir e ùrachadh gu fèin-ghluasadach air an dàta mar a thig e. Chan e a-mhàin gu bheil seo a’ luathachadh cheistean, ach cuideachd a’ lughdachadh cosgais cleachdadh Athena.

Nach cuir sinn am fiosrachadh seo ris an fhaidhle sgeama dàta:

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`
      )
    }
  }
}

Bidh sinn a’ sònrachadh sa mhodail seo gu bheil e riatanach dàta a ro-chruinneachadh airson a h-uile meatrach a thathar a’ cleachdadh, agus sgaradh a chleachdadh gach mìos. Roinneadh ro-chruinneachadh comasach air cruinneachadh agus ùrachadh dàta a luathachadh gu mòr.

A-nis is urrainn dhuinn an deas-bhòrd a chruinneachadh!

Tha backend Cube.js a’ toirt seachad CÒRR API agus seata de leabharlannan teachdaiche airson frèaman aghaidh mòr-chòrdte. Cleachdaidh sinn an dreach React den neach-dèiligidh gus an deas-bhòrd a thogail. Chan eil Cube.js a’ toirt seachad ach dàta, agus mar sin bidh feum againn air leabharlann fradharc - is toil leam e ath-chlàran, ach faodaidh tu gin a chleachdadh.

Gabhaidh am frithealaiche Cube.js ris an iarrtas a-steach cruth JSON, a tha a’ sònrachadh nan slatan-tomhais a tha a dhìth. Mar eisimpleir, gus obrachadh a-mach cia mheud mearachd a thug Nginx seachad tron ​​​​latha, feumaidh tu an t-iarrtas a leanas a chuir:

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

Nach stàlaich sinn an neach-dèiligidh Cube.js agus an leabharlann co-phàirt React tro NPM:

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

Bidh sinn a 'toirt a-steach co-phàirtean cubejs и QueryRenderergus an dàta a luchdachadh sìos, agus an deas-bhòrd a chruinneachadh:

Còd deas-bhòrd

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>
        );
      }}
    />
  )
}

Tha stòran deas-bhòrd rim faighinn aig bogsa gainmhich còd.

Source: www.habr.com

Cuir beachd ann