عموما، سوداګریز محصولات یا چمتو شوي خلاصې سرچینې بدیلونه، لکه Prometheus + Grafana، د Nginx د عملیاتو نظارت او تحلیل لپاره کارول کیږي. دا د څارنې یا ریښتیني وخت تحلیلونو لپاره ښه اختیار دی ، مګر د تاریخي تحلیل لپاره خورا اسانه ندي. په هرې مشهورې سرچینې کې، د نګینکس لاګونو څخه د معلوماتو حجم په چټکۍ سره وده کوي، او د ډیټا لوی مقدار تحلیل کولو لپاره، دا منطقي ده چې یو څه نور تخصص وکاروئ.
پدې مقاله کې به زه تاسو ته ووایم چې تاسو څنګه کارولی شئ
TL:DR؛
د معلوماتو راټولولو لپاره چې موږ یې کاروو
د 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" "-"
دوی تجزیه کیدی شي ، مګر د نګینکس ترتیب سم کول خورا اسانه دي ترڅو دا په 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 وکاروو. دا تاسو ته اجازه درکوي چې لاګونه په یو ځای کې ذخیره او تحلیل کړئ، ځکه چې اتینا کولی شي په مستقیم ډول په S3 کې د معلوماتو سره کار وکړي. وروسته په مقاله کې زه به تاسو ته ووایم چې څنګه په سمه توګه د لاګونو اضافه کول او پروسس کول، مګر لومړی موږ په S3 کې پاک بالټ ته اړتیا لرو، په کوم کې چې نور هیڅ شی به زیرمه نشي. دا دمخه په پام کې نیولو سره ارزښت لري چې تاسو به په کومه سیمه کې خپل بالټ جوړ کړئ، ځکه چې ایتینا په ټولو سیمو کې شتون نلري.
د ایتینا کنسول کې د سرکټ رامینځته کول
راځئ چې د لاګونو لپاره په اتینا کې میز جوړ کړو. دا د لیکلو او لوستلو دواړو لپاره اړین دی که تاسو د کیینیسس فایر هوز کارولو پلان لرئ. د ایتینا کنسول خلاص کړئ او یو میز جوړ کړئ:
د 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 جریان جوړول
Kinesis Firehose به په ټاکل شوي ب formatه کې له Nginx څخه S3 ته ترلاسه شوي معلومات ولیکي ، دا به د YYYY/MM/DD/HH ب formatه کې لارښودونو ته وویشي. دا به د معلوماتو لوستلو په وخت کې ګټور وي. تاسو کولی شئ، البته، مستقیم له روانی څخه S3 ته ولیکئ، مګر پدې حالت کې تاسو باید JSON ولیکئ، او دا د فایلونو لوی اندازې له امله غیر موثر دی. برسیره پردې، کله چې د PrestoDB یا اتینا کاروئ، JSON د ډیټا خورا ورو بڼه دی. نو د Kinesis Firehose کنسول خلاص کړئ ، "د تحویلۍ جریان رامینځته کړئ" کلیک وکړئ ، د " تحویلي" ساحه کې "مستقیم PUT" غوره کړئ:
په بل ټب کې، د "ریکارډ فارمیټ تبادله" غوره کړئ - "فعال شوی" او د ثبت کولو فارمیټ په توګه "اپاچی 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 روان یو، موږ کولی شو هلته د نګینکس لاګونه واستوو. موږ معمولا نګینکس په ډاکر کانټینر کې چلوو ، په دې حالت کې ډاکر د فلینټډ لپاره اصلي لاګینګ ډرایور لري:
$ 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 لري
راځئ چې پورته ترتیب شوي لاګ پارسینګ د روانی ترتیب کې اضافه کړو:
<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>
ایتینا
که تاسو هرڅه په سمه توګه تنظیم کړي وي، نو یو څه وروسته (د ډیفالټ په واسطه، کیینیسس ریکارډونه په هر 10 دقیقو کې یو ځل ډاټا ترلاسه کوي) تاسو باید په S3 کې د لاګ فایلونه وګورئ. د Kinesis Firehose "څارنې" مینو کې تاسو کولی شئ وګورئ چې په S3 کې څومره ډاټا ثبت شوي، او همدارنګه غلطی. د Kinesis رول ته د S3 بالټ ته د لیکلو لاسرسی مه هیروئ. که کینیسیس نشي کولی یو څه تجزیه کړي ، نو دا به ورته بالټ کې غلطۍ اضافه کړي.
اوس تاسو کولی شئ په ایتینا کې ډاټا وګورئ. راځئ چې وروستي غوښتنې ومومئ چې موږ یې غلطۍ بیرته راګرځولې:
SELECT * FROM "db_name"."table_name" WHERE status > 499 ORDER BY created_at DESC limit 10;
د هرې غوښتنې لپاره ټول ریکارډونه سکین کول
اوس زموږ لاګونه پروسس شوي او په ORC کې په S3 کې زیرمه شوي، فشار شوي او د تحلیل لپاره چمتو دي. Kinesis Firehose حتی دوی د هر ساعت لپاره لارښودونو کې تنظیم کړل. په هرصورت، تر هغه چې جدول ویشل شوی نه وي، اتینا به په هره غوښتنه کې هر وخت ډاټا بار کړي، د نادر استثناء سره. دا د دوو دلیلونو لپاره یوه لویه ستونزه ده:
- د معلوماتو حجم په دوامداره توګه وده کوي، پوښتنې ورو کوي؛
- ایتینا د سکین شوي ډیټا حجم پراساس بیل کیږي ، په هره غوښتنه کې لږترلږه 10 MB سره.
د دې د حل کولو لپاره، موږ د AWS ګلو کرالر کاروو، کوم چې به په S3 کې ډاټا کرال کړي او د ویش معلومات د ګلو میټاسټور ته ولیکئ. دا به موږ ته اجازه راکړي چې پارټیشنونه د فلټر په توګه وکاروو کله چې د ایتینا پوښتنه کوي، او دا به یوازې هغه لارښودونه سکین کړي چې په پوښتنې کې مشخص شوي.
د ایمیزون ګلو کرالر تنظیم کول
د ایمیزون ګلو کرالر په S3 بالټ کې ټول معلومات سکین کوي او د برخو سره میزونه رامینځته کوي. د AWS Glue کنسول څخه د ګلو کرالر جوړ کړئ او یو بالټ اضافه کړئ چیرې چې تاسو ډاټا ذخیره کوئ. تاسو کولی شئ د څو بالټونو لپاره یو کرالر وکاروئ ، پدې حالت کې به دا په ټاکل شوي ډیټابیس کې د نومونو سره میزونه رامینځته کړي چې د بالټونو نومونو سره سمون لري. که تاسو پلان لرئ چې دا ډاټا په منظمه توګه وکاروئ، ډاډ ترلاسه کړئ چې د خپلو اړتیاو سره سم د کرالر لانچ مهالویش تنظیم کړئ. موږ د ټولو میزونو لپاره یو کرالر کاروو، کوم چې هر ساعت تیریږي.
ویشل شوي میزونه
د کرالر د لومړي لانچ وروسته، د هر سکین شوي بالټ میزونه باید په ترتیباتو کې مشخص شوي ډیټابیس کې ښکاره شي. د اتینا کنسول خلاص کړئ او د نګینکس لاګونو سره میز ومومئ. راځئ هڅه وکړو چې یو څه ولولئ:
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 سټیک کاروو ، نو دا منطقي ده چې د ګمارنې لپاره لامبډا وکاروئ. تاسو کولی شئ د نسل لپاره ایکسپریس ټیمپلیټ وکاروئ که تاسو په هیروکو یا ډاکر کې د Cube.js بیکینډ کوربه کولو پلان لرئ. اسناد نور بیانوي
$ npm install -g cubejs-cli
$ cubejs create nginx-log-analytics -t serverless -d athena
د چاپیریال تغیرات په cube.js کې د ډیټابیس لاسرسي تنظیم کولو لپاره کارول کیږي. جنریټر به یو .env فایل رامینځته کړي چې تاسو کولی شئ خپل کلیدونه مشخص کړئ
اوس موږ اړتیا لرو
په لارښود کې schema
، یو فایل جوړ کړئ Logs.js
. دلته د نګینکس لپاره د ډیټا ماډل مثال دی:
د ماډل کوډ
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 به د مخکې راټول شوي ډیټا سره اضافي میزونه رامینځته کړي او په اتوماتيک ډول به ډاټا تازه کړي کله چې راشي. دا نه یوازې پوښتنې ګړندۍ کوي ، بلکه د ایتینا کارولو لګښت هم کموي.
راځئ چې دا معلومات د ډیټا سکیما فایل کې اضافه کړو:
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 پس منظر وړاندې کوي
د Cube.js سرور په کې غوښتنه مني
{
"measures": ["Logs.errorCount"],
"timeDimensions": [
{
"dimension": "Logs.createdAt",
"dateRange": ["2019-01-01", "2019-01-07"],
"granularity": "day"
}
]
}
راځئ چې د NPM له لارې د Cube.js مراجع او د عکس العمل برخې کتابتون نصب کړو:
$ 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