Tavaliselt kasutatakse Nginxi töö jälgimiseks ja analüüsimiseks kommertstooteid või valmis avatud lähtekoodiga alternatiive, nagu Prometheus + Grafana. See on hea valik jälgimiseks või reaalajas analüüsimiseks, kuid ajaloolise analüüsi jaoks mitte eriti mugav. Mis tahes populaarse ressursi puhul kasvab nginxi logide andmemaht kiiresti ja suure hulga andmete analüüsimiseks on loogiline kasutada midagi spetsiifilisemat.
Selles artiklis räägin teile, kuidas seda kasutada
TL:DR;
Kasutatava teabe kogumiseks
Nginxi logide kogumine
Vaikimisi näevad Nginxi logid välja umbes sellised:
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" "-"
Neid saab sõeluda, kuid Nginxi konfiguratsiooni on palju lihtsam parandada nii, et see looks logisid JSON-is:
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 ladustamiseks
Logide salvestamiseks kasutame S3. See võimaldab salvestada ja analüüsida logisid ühes kohas, kuna Athena saab S3-s otse andmetega töötada. Hiljem artiklis räägin teile, kuidas logisid õigesti lisada ja töödelda, kuid kõigepealt vajame S3-s puhast ämbrit, kuhu midagi muud ei salvestata. Tasub eelnevalt läbi mõelda, millises piirkonnas oma ämbri loote, sest Athena pole kõigis piirkondades saadaval.
Athena konsoolis vooluringi loomine
Loome Athenas logide jaoks tabeli. Seda on vaja nii kirjutamiseks kui lugemiseks, kui kavatsete kasutada Kinesis Firehose'i. Avage Athena konsool ja looge tabel:
SQL tabeli loomine
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 Streami loomine
Kinesis Firehose kirjutab Nginxist saadud andmed S3-le valitud vormingus, jagades need kataloogidesse vormingus AAAA/KK/PP/TT. See tuleb andmete lugemisel kasuks. Muidugi saate fluentd-st otse S3-le kirjutada, kuid sel juhul peate kirjutama JSON-i ja see on failide suure suuruse tõttu ebaefektiivne. Lisaks on PrestoDB või Athena kasutamisel JSON kõige aeglasem andmevorming. Nii et avage Kinesis Firehose'i konsool, klõpsake "Loo tarnevoog", valige väljal "tarne" "otsene PUT".
Järgmisel vahekaardil valige "Salvestamisvormingu teisendamine" - "Lubatud" ja valige salvestusvorminguks "Apache ORC". Mõnede uuringute kohaselt
Valime ladustamiseks S3 ja varem loodud ämbri. Aws Glue Crawler, millest räägin veidi hiljem, ei saa S3 ämbris eesliidetega töötada, seega on oluline see tühjaks jätta.
Ülejäänud valikuid saab muuta sõltuvalt teie koormusest; tavaliselt kasutan vaikevalikuid. Pange tähele, et S3 pakkimine pole saadaval, kuid ORC kasutab vaikimisi natiivset tihendamist.
ladusalt
Nüüd, kui oleme logide salvestamise ja vastuvõtmise konfigureerinud, peame konfigureerima saatmise. Me kasutame
Esiteks vajame konfiguratsioonifaili fluent.conf. Looge see ja lisage allikas:
port 24224
siduda 0.0.0.0
Nüüd saate käivitada Fluentd serveri. Kui vajate täpsemat konfiguratsiooni, minge aadressile
$ 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
See konfiguratsioon kasutab teed /fluentd/log
logide vahemällu salvestamiseks enne saatmist. Saate ka ilma selleta hakkama, kuid taaskäivitamisel võite kaotada kõik, mis on vahemällu salvestatud. Võite kasutada ka mis tahes porti; 24224 on vaikimisi Fluentd-port.
Nüüd, kui Fluentd töötab, saame sinna saata Nginxi logisid. Tavaliselt käitame Nginxit Dockeri konteineris, sel juhul on Dockeril Fluentdi jaoks natiivne logidraiver:
$ 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
Kui kasutate Nginxit teisiti, saate kasutada logifaile, Fluentd on seda teinud
Lisame Fluenti konfiguratsioonile ülal konfigureeritud logi sõelumise:
<filter YOUR-NGINX-TAG.*>
@type parser
key_name log
emit_invalid_record_to_error false
<parse>
@type json
</parse>
</filter>
Ja logide saatmine Kinesisele kasutades
<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
Kui oled kõik õigesti seadistanud, siis mõne aja pärast (vaikimisi Kinesis salvestab saadud andmed kord 10 minuti jooksul) peaks S3-s nägema logifaile. Kinesis Firehose'i jälgimise menüüs näete, kui palju andmeid S3-s salvestatakse, ja ka vigu. Ärge unustage anda Kinesise rollile S3 ämbrile kirjutamisõigust. Kui Kinesis ei saanud midagi sõeluda, lisab see vead samasse ämbrisse.
Nüüd saate andmeid Athenas vaadata. Otsime üles viimased päringud, mille puhul tagastasime vead:
SELECT * FROM "db_name"."table_name" WHERE status > 499 ORDER BY created_at DESC limit 10;
Kõigi kirjete skannimine iga päringu jaoks
Nüüd on meie logid töödeldud ja S3-s ORC-s salvestatud, tihendatud ja analüüsimiseks valmis. Kinesis Firehose korraldas need isegi iga tunni kohta kataloogidesse. Kuid seni, kuni tabel pole sektsioonideks jagatud, laadib Athena iga päringu korral kõigi aegade andmeid, välja arvatud harvad erandid. See on suur probleem kahel põhjusel:
- Andmemaht kasvab pidevalt, päringuid aeglustades;
- Athenale esitatakse arve skannitud andmete mahu alusel, vähemalt 10 MB päringu kohta.
Selle parandamiseks kasutame AWS Glue Crawleri, mis roomab S3 andmetes ja kirjutab partitsiooniteabe Glue Metastore'i. See võimaldab meil kasutada Athena päringu tegemisel sektsioone filtrina ja see skannib ainult päringus määratud katalooge.
Amazon Glue Crawleri seadistamine
Amazon Glue Crawler skannib kõik S3 ämbris olevad andmed ja loob vaheseintega tabeleid. Looge AWS Glue'i konsoolist liimiroomik ja lisage ämber, kuhu andmeid salvestate. Ühte roomajat saab kasutada mitme ämbri jaoks, sel juhul loob see määratud andmebaasi tabelid nimedega, mis vastavad ämbrite nimedele. Kui kavatsete neid andmeid regulaarselt kasutada, konfigureerige kindlasti roomaja käivitamise ajakava vastavalt oma vajadustele. Kõigi laudade jaoks kasutame ühte Crawlerit, mis töötab iga tund.
Jaotatud lauad
Pärast roomaja esmakordset käivitamist peaksid seadetes määratud andmebaasis ilmuma iga skannitud ämbri tabelid. Avage Athena konsool ja leidke Nginxi logidega tabel. Proovime midagi lugeda:
SELECT * FROM "default"."part_demo_kinesis_bucket"
WHERE(
partition_0 = '2019' AND
partition_1 = '04' AND
partition_2 = '08' AND
partition_3 = '06'
);
See päring valib kõik kirjed, mis on saabunud 6. aprillil 7 kella 8–2019. Kuid kui palju tõhusam see on kui lihtsalt lugemine jaotamata tabelist? Uurime välja ja valime samad kirjed, filtreerides need ajatempli järgi:
3.59 sekundit ja 244.34 megabaiti andmeid andmekogus, mis sisaldab vaid nädala logisid. Proovime filtrit partitsiooni järgi:
Natuke kiirem, aga mis kõige tähtsam – ainult 1.23 megabaiti andmemahtu! See oleks palju odavam, kui mitte hinnakujunduses olevad minimaalsed 10 megabaiti päringu kohta. Kuid see on siiski palju parem ja suurte andmekogumite puhul on erinevus palju muljetavaldavam.
Armatuurlaua loomine Cube.js-i abil
Armatuurlaua kokkupanemiseks kasutame Cube.js analüütilist raamistikku. Sellel on üsna palju funktsioone, kuid meid huvitavad kaks: partitsioonifiltrite automaatse kasutamise võimalus ja andmete eelliitmine. See kasutab andmeskeemi
Loome uue Cube.js rakenduse. Kuna me juba kasutame AWS-i pinu, on loogiline kasutada juurutamiseks Lambdat. Kui kavatsete Cube.js-i taustaprogrammi majutada Herokus või Dockeris, saate genereerimiseks kasutada ekspressmalli. Dokumentatsioon kirjeldab teisi
$ npm install -g cubejs-cli
$ cubejs create nginx-log-analytics -t serverless -d athena
Keskkonnamuutujaid kasutatakse faili cube.js andmebaasi juurdepääsu konfigureerimiseks. Generaator loob .env-faili, milles saate määrata oma võtmed
Nüüd vajame
Kataloogis schema
, looge fail Logs.js
. Siin on nginxi andmemudeli näide:
Mudeli kood
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`
}
}
});
Siin kasutame muutujat
Samuti määrame mõõdikud ja parameetrid, mida tahame armatuurlaual kuvada, ning määrame eelagregatsioonid. Cube.js loob täiendavaid tabeleid eelkoondandmetega ja värskendab neid saabumisel automaatselt. See mitte ainult ei kiirenda päringuid, vaid vähendab ka Athena kasutamise kulusid.
Lisame selle teabe andmeskeemi faili:
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`
)
}
}
}
Täpsustame selles mudelis, et kõigi kasutatud mõõdikute andmed tuleb eelnevalt koondada ja kasutada kuude kaupa jaotamist.
Nüüd saame armatuurlaua kokku panna!
Cube.js taustaprogramm pakub
Cube.js server võtab päringu vastu
{
"measures": ["Logs.errorCount"],
"timeDimensions": [
{
"dimension": "Logs.createdAt",
"dateRange": ["2019-01-01", "2019-01-07"],
"granularity": "day"
}
]
}
Installime NPM-i kaudu Cube.js-kliendi ja Reacti komponenditeegi:
$ npm i --save @cubejs-client/core @cubejs-client/react
Toome sisse komponente cubejs
и QueryRenderer
andmete allalaadimiseks ja armatuurlaua kogumiseks tehke järgmist.
Armatuurlaua kood
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>
);
}}
/>
)
}
Armatuurlaua allikad on saadaval aadressil
Allikas: www.habr.com