Nginx log analytica utens Athena Amazon et Cube.js

De more commerciali producti vel optiones aperturae fontium paratae, sicut Prometheus + Grafana, ad monitorem et operationem Nginx analysim adhibentur. Haec optio magna est ad analytica vigilantia vel real-time, sed non valde commoda ad analysim historicam. Quovis populari auxilio, volumen notitiarum e ngingis lignis celeriter crescit, et magnam notarum copiam resolvere, logicum est aliquid specialius uti.

In hoc articulo tibi dicam quomodo uti potes Athens ad acta resolvere, exemplum Nginx sumens, et monstrabo quomodo colligo analyticam ashboardday ex hac notitia utens aperti-fontis cube.js compage. Haec est integra solutio architecturae:

Nginx log analytica utens Athena Amazon et Cube.js

TL:DR;
Ad perfectum ashboardday ".

Ad notitias utimur fluentedad processus - AWS Kinesis Data Firehose ΠΈ AWS Glue, pro repono - S 3 AWS. Hoc fasciculo utens, non solum nginx tigna, sed etiam alia eventa ac alia officia condere potes. Potes partes aliquas cum similibus pro acervo tuo reponere, exempli gratia, ligna ad kinesim directe ab nginx scribere potes, fluente praetereunte, vel ad hoc utere.

Nginx colligendis omnia

Defalta, Nginx taleae aliquid simile hoc spectant:

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

Parsed possunt, sed multo facilius Nginx configurationem corrigere ut trabes in JSON producat;

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;

S 3 pro repono

Ad acta condunt, utemur S3. Hoc tibi concedit in uno loco condere ac resolvere acta, quoniam Athena cum notitia in S3 directe laborare potest. Postea in articulo narrabo tibi quomodo ligna et processus recte adiciant, sed primum in S3 situla pura indigemus, in qua nihil aliud condietur. Operae pretium est ante considerare quam regionem in situlam tuam creabis, quod Athena omnibus in locis praesto non est.

Circuitus in Athena console

Tabulam Athenis de lignis faciamus. Utrumque opus est scribendo et legendo si Kinesis Firehose uti velis. Aperi Athenam consolare et mensam crea;

SQL mensam creationis

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');

Creando Kinesis Firehose Stream

Kinesis Firehose notitias ab Nginx ad S3 receptas in forma delectae scribet, eam dividens in directoria in forma YYYY/MM/DD/HH. Haec in promptu veniet, cum lectio data est. Potes sane scribere directe ad S3 ex fluented, sed in hoc casu debebis scribere JSON, et hoc inhabilis est propter magnitudinem imaginum. Accedit, cum PrestoDB vel Athena utens, JSON notitia forma tardissima est. Aperire Kinesis Firehose consolatorium, preme "Create rivum partus", elige "directum PUT" in "partus" campum:

Nginx log analytica utens Athena Amazon et Cube.js

In altera tab, "Record format conversionem" - "Administrare" et "Apache ORC" eligere ut in forma recordationis. Secundum quosdam investigationes Owen O'MalleyHaec forma optima est pro PrestoDB et Athena. Mensa utimur ut schema supra conditum. Nota quaeso quod aliquem locum S3 in kinesis notare potes, schema tantum e mensa adhibetur. Sed si alium locum S3 denotas, istas tabulas ex hac tabula legere non poteris.

Nginx log analytica utens Athena Amazon et Cube.js

S3 eligimus pro repositione et situla quam antea creavimus. Aws Glue Crawler, de quo paulo post loquar, cum praefixis in situla S3 laborare non potest, ideo interest ut inanem relinqueret.

Nginx log analytica utens Athena Amazon et Cube.js

Reliquae optiones in onere tuo pendentes mutari possunt, defaltis uti soleo. Nota compressionem S3 non in promptu esse, sed ORC pressionem indigenam per defaltam adhibet.

fluented

Nunc quod figuram habemus accommodare et accepto tigna, mittens configurare necesse est. Nos utemur fluentedRuby, quod amo, sed Logstash uti potes vel ligna ad kinesim directe mittere. Fluentd server pluribus modis deduci potest, de docina dicam tibi quia simplex et commodum est.

Primum, lima configuratione fluent.conf opus est. Crea eum et fontem adde:

genus ante
portus 24224
ligare 0.0.0.0

Nunc a Fluentd servo incipere potes. Si configuratione provectiore opus est, vade ad Docker hub Singula dux est, etiam quomodo imaginem tuam convenias.

$ 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

Hoc configuratione utitur semita /fluentd/log ut acta ante mittens. Hoc facere potes, sed tunc cum sileo, omnia conditivo labore fracto posteriori amittere potes. Portu quolibet uti potes, 24224 Portus est default Fluentd.

Nunc quod Fluentd cursus habemus, ligna ibi Nginx mittere possumus. Solent currere Nginx in Docker continente, quo casu Docker logging coegi pro Fluentd indigena habet:

$ 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

Si Nginx aliter curris, lima stipes uti potes, Fluentd has file cauda plugin.

Addamus truncum parsing figuratum supra fluenti configuratione:

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

Et mittens ligna ad Kinesis utens kinesis firehose plugin:

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

Athens

Si omnia recte configurasti, dein post tempus (per default, Kinesis monumenta data semel singulis 10 momentis recepta) tabellas stipes in S3 videre debes. In tabula "magna" Kinesis Firehose videre potes quantum notitia in S3 scripta est, necnon errores. Noli oblivisci dare aditum scribere in S3 situla ad munus Kinesis. Si Kinesis aliquid parse non potuit, errores eidem situla addet.

Iam Athenas datas videre potes. Novissimas petitiones inveniamus quibus errores reddidimus:

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

Scaning all records for each request

Nunc omnia nostra processit et condita sunt in S3 in ORC, compressa et parata ad analysim. Kinesis Firehose eos etiam in directoria uniuscuiusque horae ordinavit. Attamen dum mensa non est partita, Athena omni tempore data omni rogatu, raris exceptionibus, oneret. Haec quaestio magna est duabus de causis;

  • Voluminis notitia constanter crescit, retardatio queries;
  • Athena billed innixa e codice notitiarum lustratarum, cum minimum 10 MB per petitionem.

Ad hoc figendum, AWS Glue Crawler utimur, quae notitias in S3 repetet et informationes partitio ad Glue Metastore scribes. Hoc nobis permittet ut quasi filamentum partitionibus cum Athena interrogatione utatur et tantum directoria quae in interrogatione specificata erunt.

Gluten Amazon profecta est Crawler

Amazon gluten Crawler omnes notitias in S3 situla lustrat et mensas cum partitionibus gignit. Facere gluten Crawler ex AWS Gluten console et adde situlam ubi datam condes. Uno crawler pluribus situlis uti potes, quo casu tabulas in datorum determinatis creabit cum nominibus quae nominibus sitularum aequant. Si hac notitia regulariter uti cogitas, scito configurare scedulam launch Crawler ad usus tuos necessarios. Uno Crawler pro omnibus tabulis utimur, quae omni hora currit.

Partita tabulae

Post primam activitates reptans, tabulae pro singulis situlae inspectis apparere debent in uncinis datorum determinatis. Aperi consolare Athenam et inveniunt mensam cum Nginx tigna. Quid legere scriptor experiri:

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

Quaestio haec omnia monumenta quae inter 6 a.m. et 7 a.m. die 8 Aprilis MMXIX recepta sunt, eliget. Sed quanto efficacius hoc, quam ex non partita tabula lectio? Investigemus et lego eadem monumenta, ea per indicatione percolando:

Nginx log analytica utens Athena Amazon et Cube.js

3.59 secundae et 244.34 megabytae notitiarum in schedula cum hebdomada tantum lignorum. Colamentum per partitionem scriptor experiri:

Nginx log analytica utens Athena Amazon et Cube.js

Paulo velocius, sed praesertim - modo 1.23 megabytarum notitiarum! Multo vilius esset nisi pro minimis 10 megabytis per petitionem in cursus sapien. Sed multo melius est, et in magnis datasetis differentia multo gravior erit.

Building ashboardday using Cube.js

Ad ashboardday convenire, compage analytica Cube.js utimur. Multa munera habet, sed duo quaerimus: facultas automatice utendi partitionis filtra et notitia praegregationis. Notitia utitur schema data schema, scripta in Javascript ad SQL generandum et interrogationem datorum exsequendam. Tantum opus est indicare quomodo partitione colum in schemate utatur.

Novam Cube.js applicationem faciamus. Cum iam per AWS ACERVUM utamur, consentaneum est Lambda uti ad instruere. Formula expressa generationis uti potes si vis ut exercitum Cube.js regredi in Heroku vel Docker. Documenta describitur aliis hosting modi.

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

Variabiles ambitus adhibentur ad accessum datorum configurandum in cube.js. Generator fasciculum .env creabit in quo claves tuas pro .icere potes Athens.

Nunc opus est data schemain quo quomodo acta nostra reponantur exacte indicabimus. Ibi etiam specificare potes quomodo metrice pro dashboards calculare.

In indicem schema, lima creare Logs.js. Exem- plum hic est pro nginx notitia;

Exemplar codice

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

Hic utendo variabili FILTER_PARAMSad generate SQL query cum partitione filter.

Etiam metricos et parametros constituimus quos in ashboardday proponere ac prae-gregationes specificare volumus. Cube.js alias tabulas cum notitia pre-congregatis creabit et statim datas cum advenerit renovabit. Hoc non solum quaerit queries, sed etiam pretium utendi Athena minuit.

Addamus haec informationes ad schema lima notitia:

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

In hoc exemplari definimus quod necesse est praeiacere notitias omnium metricorum usuum, et per mensem partitionibus utere. Pre-congregatio partitionibus potest signanter accelerare notitia collectio et adaequationis.

Nunc ashboardday convenire possumus!

Cube.js backend praebet API CETEROQUIN and a set of client libraries for popular front-fin frameworks. versione React utemur clientis ad ashboardday aedificare. Cube.js tantum notitias praebet, sic bibliotheca visualisationi opus est - id mihi placet recharsAliquam sed aliquam quam.

Cube.js servo petitionem accipit in JSON formatqui metri speciem requiri. Exempli gratia, computare quot errores Nginx per diem dederunt, necesse est ut sequentem petitionem mittat;

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

Instruamus Cube.js clientem et React componentis bibliothecam per NPM:

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

Partes sumus importare cubejs ΠΈ QueryRenderernotitias extrahere, et ashboardday colligere;

Dashboard codice

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 fontes sunt praesto ad code sandbox.

Source: www.habr.com