Venjulega eru auglýsingavörur eða tilbúnir opinn uppspretta valkostir, eins og Prometheus + Grafana, notaðar til að fylgjast með og greina rekstur Nginx. Þetta er góður kostur fyrir eftirlit eða rauntíma greiningu, en ekki mjög þægilegt fyrir sögulega greiningu. Á hvaða vinsælu auðlind sem er, eykst magn gagna úr nginx logs hratt og til að greina mikið magn af gögnum er rökrétt að nota eitthvað sérhæfðara.
Í þessari grein mun ég segja þér hvernig þú getur notað
TL:DR;
Til að safna upplýsingum sem við notum
Að safna Nginx annálum
Sjálfgefið er að Nginx logs líta eitthvað svona út:
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" "-"
Hægt er að flokka þær, en það er miklu auðveldara að leiðrétta Nginx stillinguna þannig að hún framleiði logs í 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 fyrir geymslu
Til að geyma logs munum við nota S3. Þetta gerir þér kleift að geyma og greina annála á einum stað, þar sem Athena getur unnið með gögn í S3 beint. Síðar í greininni mun ég segja þér hvernig á að bæta við og vinna úr annálum rétt, en fyrst þurfum við hreina fötu í S3, þar sem ekkert annað verður geymt. Það er þess virði að íhuga fyrirfram á hvaða svæði þú ætlar að búa til fötuna þína, því Athena er ekki í boði á öllum svæðum.
Að búa til hringrás í Athena stjórnborðinu
Búum til töflu í Aþenu fyrir annála. Það er nauðsynlegt bæði til að skrifa og lesa ef þú ætlar að nota Kinesis Firehose. Opnaðu Athena stjórnborðið og búðu til töflu:
SQL töflugerð
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ð búa til Kinesis Firehose Stream
Kinesis Firehose mun skrifa gögnin sem berast frá Nginx til S3 á völdu sniði og skipta þeim í möppur á YYYY/MM/DD/HH sniðinu. Þetta mun koma sér vel þegar gögn eru lesin. Þú getur auðvitað skrifað beint á S3 frá fluentd, en í þessu tilfelli þarftu að skrifa JSON og það er óhagkvæmt vegna þess hve skrárnar eru stórar. Að auki, þegar þú notar PrestoDB eða Athena, er JSON hægasta gagnasniðið. Svo opnaðu Kinesis Firehose stjórnborðið, smelltu á „Create delivery stream“, veldu „direct PUT“ í „afhending“ reitnum:
Í næsta flipa, veldu „Record format conversion“ - „Enabled“ og veldu „Apache ORC“ sem upptökusnið. Samkvæmt sumum rannsóknum
Við veljum S3 fyrir geymslu og fötuna sem við bjuggum til áðan. Aws Glue Crawler, sem ég mun tala um aðeins síðar, getur ekki virkað með forskeytum í S3 fötu, svo það er mikilvægt að hafa það tómt.
Hægt er að breyta þeim valmöguleikum sem eftir eru eftir álagi þínu; ég nota venjulega sjálfgefna. Athugaðu að S3 þjöppun er ekki tiltæk, en ORC notar sjálfgefið innbyggða þjöppun.
reiprennandi
Nú þegar við höfum stillt geymslu og móttöku annála þurfum við að stilla sendingu. Við munum nota
Fyrst þurfum við fluent.conf stillingarskrána. Búðu til það og bættu við uppruna:
höfn 24224
binda 0.0.0.0
Nú geturðu ræst Fluent netþjóninn. Ef þú þarft ítarlegri uppsetningu skaltu fara á
$ 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
Þessi uppsetning notar slóðina /fluentd/log
til að vista annála fyrir sendingu. Þú getur verið án þessa, en svo þegar þú endurræsir geturðu tapað öllu sem er í skyndiminni með erfiðri vinnu. Þú getur líka notað hvaða höfn sem er; 24224 er sjálfgefið Fluentd tengi.
Nú þegar Fluent er í gangi getum við sent Nginx logs þangað. Við keyrum venjulega Nginx í Docker gámi, en í því tilviki er Docker með innfæddan skógarhöggsrekla fyrir 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
Ef þú keyrir Nginx öðruvísi geturðu notað log skrár, Fluentd hefur
Bætum loggreiningunni sem stillt er hér að ofan við Fluent stillinguna:
<filter YOUR-NGINX-TAG.*>
@type parser
key_name log
emit_invalid_record_to_error false
<parse>
@type json
</parse>
</filter>
Og senda logs til Kinesis með því að nota
<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
Ef þú hefur stillt allt rétt, þá eftir smá stund (sjálfgefið, Kinesis skráir móttekin gögn einu sinni á 10 mínútna fresti) ættir þú að sjá annálsskrár í S3. Í „eftirlit“ valmyndinni á Kinesis Firehose geturðu séð hversu mikið af gögnum er skráð í S3, auk villna. Ekki gleyma að veita Kinesis hlutverkinu skrifaðgang að S3 fötunni. Ef Kinesis gæti ekki þáttað eitthvað mun það bæta villunum í sömu fötu.
Nú er hægt að skoða gögnin í Athena. Við skulum finna nýjustu beiðnirnar sem við skiluðum villum fyrir:
SELECT * FROM "db_name"."table_name" WHERE status > 499 ORDER BY created_at DESC limit 10;
Skanna allar færslur fyrir hverja beiðni
Nú hafa annálar okkar verið unnar og geymdar í S3 í ORC, þjappaðar og tilbúnar til greiningar. Kinesis Firehose skipulagði þær jafnvel í möppur fyrir hverja klukkustund. Hins vegar, svo framarlega sem borðið er ekki skipt í skipting, mun Athena hlaða gögnum allra tíma á hverja beiðni, með sjaldgæfum undantekningum. Þetta er stórt vandamál af tveimur ástæðum:
- Gagnamagn eykst stöðugt og hægir á fyrirspurnum;
- Innheimt er fyrir Athena miðað við magn skannaðra gagna, að lágmarki 10 MB á beiðni.
Til að laga þetta notum við AWS Glue Crawler, sem mun skríða gögnin í S3 og skrifa skiptingarupplýsingarnar í Glue Metastore. Þetta gerir okkur kleift að nota skipting sem síu þegar spurt er um Athena, og það mun aðeins skanna möppurnar sem tilgreindar eru í fyrirspurninni.
Setja upp Amazon Glue Crawler
Amazon Glue Crawler skannar öll gögnin í S3 fötunni og býr til töflur með skiptingum. Búðu til Glue Crawler úr AWS Glue stjórnborðinu og bættu við fötu þar sem þú geymir gögnin. Þú getur notað einn skrið fyrir nokkrar fötur, í því tilviki mun hann búa til töflur í tilgreindum gagnagrunni með nöfnum sem passa við nöfnin á fötunum. Ef þú ætlar að nota þessi gögn reglulega, vertu viss um að stilla ræsingaráætlun Crawler til að henta þínum þörfum. Við notum einn Crawler fyrir öll borð, sem keyrir á klukkutíma fresti.
Skipt töflur
Eftir fyrstu ræsingu skriðans ættu töflur fyrir hverja skannaða fötu að birtast í gagnagrunninum sem tilgreindur er í stillingunum. Opnaðu Athena stjórnborðið og finndu borðið með Nginx logs. Við skulum reyna að lesa eitthvað:
SELECT * FROM "default"."part_demo_kinesis_bucket"
WHERE(
partition_0 = '2019' AND
partition_1 = '04' AND
partition_2 = '08' AND
partition_3 = '06'
);
Þessi fyrirspurn mun velja allar færslur sem berast á milli klukkan 6:7 og 8:2019 þann XNUMX. apríl XNUMX. En hversu miklu skilvirkara er þetta en bara að lesa úr óskiptu borði? Við skulum finna út og velja sömu færslurnar og sía þær eftir tímastimpli:
3.59 sekúndur og 244.34 megabæti af gögnum á gagnasafni með aðeins viku af annálum. Við skulum reyna að sía eftir skipting:
Aðeins hraðar, en síðast en ekki síst - aðeins 1.23 megabæti af gögnum! Það væri miklu ódýrara ef ekki væri fyrir lágmark 10 megabæti á beiðni í verðlagningunni. En það er samt miklu betra og á stórum gagnasöfnum verður munurinn miklu áhrifameiri.
Byggja mælaborð með Cube.js
Til að setja saman mælaborðið notum við Cube.js greiningarrammann. Það hefur töluvert af aðgerðum, en við höfum áhuga á tvennu: getu til að nota skiptingarsíur sjálfkrafa og gagnaforsöfnun. Það notar gagnaskema
Búum til nýtt Cube.js forrit. Þar sem við erum nú þegar að nota AWS stafla er rökrétt að nota Lambda til dreifingar. Þú getur notað hraðsniðmátið fyrir kynslóð ef þú ætlar að hýsa Cube.js bakendann í Heroku eða Docker. Skjölin lýsa öðrum
$ npm install -g cubejs-cli
$ cubejs create nginx-log-analytics -t serverless -d athena
Umhverfisbreytur eru notaðar til að stilla aðgang að gagnagrunni í cube.js. Rafallinn mun búa til .env skrá þar sem þú getur tilgreint lyklana þína fyrir
Nú þurfum við
Í möppu schema
, búa til skrá Logs.js
. Hér er dæmi um gagnalíkan fyrir nginx:
Fyrirmyndarkóði
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`
}
}
});
Hér erum við að nota breytuna
Við stillum einnig mæligildi og færibreytur sem við viljum birta á mælaborðinu og tilgreinum forsamsetningar. Cube.js mun búa til viðbótartöflur með fyrirfram samanlögðum gögnum og mun sjálfkrafa uppfæra gögnin þegar þau berast. Þetta flýtir ekki aðeins fyrir fyrirspurnum heldur dregur einnig úr kostnaði við notkun Athena.
Við skulum bæta þessum upplýsingum við gagnaskemaskrána:
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`
)
}
}
}
Við tilgreinum í þessu líkani að nauðsynlegt sé að safna saman gögnum fyrir alla mælikvarða sem notuð eru og nota skiptingu eftir mánuðum.
Nú getum við sett saman mælaborðið!
Cube.js bakendi veitir
Cube.js þjónninn samþykkir beiðnina inn
{
"measures": ["Logs.errorCount"],
"timeDimensions": [
{
"dimension": "Logs.createdAt",
"dateRange": ["2019-01-01", "2019-01-07"],
"granularity": "day"
}
]
}
Við skulum setja upp Cube.js biðlarann og React íhlutasafnið í gegnum NPM:
$ npm i --save @cubejs-client/core @cubejs-client/react
Við flytjum inn íhluti cubejs
и QueryRenderer
til að hlaða niður gögnunum og safna mælaborðinu:
Kóði mælaborðs
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>
);
}}
/>
)
}
Heimildir mælaborðs eru fáanlegar á
Heimild: www.habr.com