በተለምዶ የንግድ ምርቶች ወይም ዝግጁ-የተሰሩ ክፍት ምንጭ አማራጮች፣ እንደ Prometheus + Grafana፣ የ Nginxን አሠራር ለመቆጣጠር እና ለመተንተን ያገለግላሉ። ይህ ለክትትል ወይም ለእውነተኛ ጊዜ ትንታኔ ጥሩ አማራጭ ነው, ነገር ግን ለታሪካዊ ትንተና በጣም ምቹ አይደለም. በማንኛውም ታዋቂ ምንጭ ላይ ከ nginx ምዝግብ ማስታወሻዎች የሚገኘው የውሂብ መጠን በፍጥነት እያደገ ነው, እና ብዙ መጠን ያለው መረጃን ለመተንተን, የበለጠ ልዩ የሆነ ነገር መጠቀም ምክንያታዊ ነው.
በዚህ ጽሑፍ ውስጥ እንዴት መጠቀም እንደሚችሉ እነግርዎታለሁ
TL፡DR;
የምንጠቀመውን መረጃ ለመሰብሰብ
የ Nginx ምዝግብ ማስታወሻዎችን መሰብሰብ
በነባሪ የ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" "-"
እነሱ ሊተነተኑ ይችላሉ፣ ግን የNginx ውቅርን ለማስተካከል በ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 ውስጥ ንጹህ ባልዲ ያስፈልገናል, በውስጡም ሌላ ምንም ነገር አይቀመጥም. ባልዲዎን በየትኛው ክልል እንደሚፈጥሩ አስቀድመው ማጤን ተገቢ ነው ምክንያቱም አቴና በሁሉም ክልሎች ውስጥ አይገኝም።
በአቴና ኮንሶል ውስጥ ወረዳ መፍጠር
በአቴና ውስጥ ለሎግ የሚሆን ጠረጴዛ እንፍጠር። Kinesis Firehose ለመጠቀም ካቀዱ ለመጻፍ እና ለማንበብ ለሁለቱም ያስፈልጋል. የአቴና ኮንሶል ይክፈቱ እና ጠረጴዛ ይፍጠሩ:
የ 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 ከ Nginx ወደ S3 የተቀበለውን መረጃ በተመረጠው ቅርጸት ይጽፋል, በዓዓዓዓዓ / ወወ / ቀን / ዲ / ኤችኤች ቅርጸት ወደ ማውጫዎች ይከፍላል. ይህ መረጃ በሚያነቡበት ጊዜ ጠቃሚ ይሆናል. ለነገሩ በቀጥታ ከቅልጥፍና ወደ S3 መጻፍ ትችላለህ፣ ነገር ግን በዚህ አጋጣሚ JSON መፃፍ አለብህ፣ እና ይህ በፋይሎቹ ትልቅ መጠን የተነሳ ውጤታማ አይደለም። በተጨማሪም፣ PrestoDB ወይም Athena ሲጠቀሙ፣ JSON በጣም ቀርፋፋው የውሂብ ቅርጸት ነው። ስለዚህ Kinesis Firehose ኮንሶሉን ይክፈቱ ፣ “የመላኪያ ዥረት ፍጠር” ን ጠቅ ያድርጉ ፣ በ “ማድረስ” መስክ ውስጥ “ቀጥታ PUT” ን ይምረጡ።
በሚቀጥለው ትር ውስጥ "ቅርጸት ቅየራ" - "ነቅቷል" የሚለውን ይምረጡ እና "Apache 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 ወደብ ነው።
አሁን Fluentd ሩጫ ስላለን Nginx logs ወደዚያ መላክ እንችላለን። እኛ ብዙውን ጊዜ Nginxን በ Docker ኮንቴይነር ውስጥ እናስኬዳለን፣ በዚህ ጊዜ Docker ለ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>
አቴና
ሁሉንም ነገር በትክክል ካዋቀሩ, ከጥቂት ጊዜ በኋላ (በነባሪ, Kinesis መዛግብት በየ 10 ደቂቃው አንድ ጊዜ ውሂብ ተቀብለዋል) በ S3 ውስጥ የምዝግብ ማስታወሻ ፋይሎችን ማየት አለብዎት. በ Kinesis Firehose "ክትትል" ምናሌ ውስጥ በ S3 ውስጥ ምን ያህል ውሂብ እንደሚመዘገብ እና እንዲሁም ስህተቶችን ማየት ይችላሉ. ለ S3 ባልዲ ለኪኔሲስ ሚና የመፃፍ መዳረሻ መስጠትን አይርሱ። Kinesis የሆነ ነገር መተንተን ካልቻለ ስህተቶቹን ወደ ተመሳሳይ ባልዲ ይጨምራል።
አሁን በአቴና ውስጥ ያለውን ውሂብ ማየት ይችላሉ. ስህተቶችን የተመለስንባቸውን የቅርብ ጊዜ ጥያቄዎችን እንፈልግ፡-
SELECT * FROM "db_name"."table_name" WHERE status > 499 ORDER BY created_at DESC limit 10;
ለእያንዳንዱ ጥያቄ ሁሉንም መዝገቦች በመቃኘት ላይ
አሁን የእኛ ምዝግብ ማስታወሻዎች ተዘጋጅተው በ S3 በ ORC ውስጥ ተከማችተዋል፣ ተጨምቀው ለመተንተን ዝግጁ ናቸው። Kinesis Firehose በየሰዓቱ ወደ ማውጫዎች እንኳን አደራጅቷቸዋል። ነገር ግን፣ ሠንጠረዡ እስካልተከፈለ ድረስ፣ አቴና በእያንዳንዱ ጥያቄ ላይ ሁል ጊዜ ውሂብን ትጭናለች፣ ከስንት ለየት ያሉ ሁኔታዎች። ይህ በሁለት ምክንያቶች ትልቅ ችግር ነው.
- የውሂብ መጠን በየጊዜው እያደገ ነው, መጠይቆችን ይቀንሳል;
- አቴና የሚከፈለው በተቃኘው የውሂብ መጠን ላይ በመመስረት ነው፣ በጥያቄ ቢያንስ 10 ሜባ።
ይህንን ለማስተካከል AWS Glue Crawlerን እንጠቀማለን፣ ይህም መረጃውን በS3 ውስጥ ይጎበኛል እና የክፍፍል መረጃውን ወደ Glue Metastore ይጽፋል። ይህ አቴናን ስንጠይቅ ክፍልፋዮችን እንደ ማጣሪያ እንድንጠቀም ያስችለናል እና በጥያቄው ውስጥ የተጠቀሱትን ማውጫዎች ብቻ ይቃኛል።
Amazon Glue Crawler በማዘጋጀት ላይ
Amazon Glue Crawler በ S3 ባልዲ ውስጥ ያሉትን ሁሉንም መረጃዎች ይቃኛል እና ከክፍልፋዮች ጋር ጠረጴዛዎችን ይፈጥራል። ከAWS Glue ኮንሶል የማጣበቂያ ክራውለር ይፍጠሩ እና ውሂቡን የሚያከማቹበት ባልዲ ይጨምሩ። ለብዙ ባልዲዎች አንድ ክሬን መጠቀም ይችላሉ, በዚህ ጊዜ በተጠቀሰው የውሂብ ጎታ ውስጥ ከባልዲዎች ስም ጋር የሚዛመዱ ስሞችን ሰንጠረዦች ይፈጥራል. ይህን ውሂብ በመደበኛነት ለመጠቀም ካቀዱ፣ የCrawler's ማስጀመሪያ መርሐግብር ከፍላጎትዎ ጋር እንዲስማማ ማዋቀርዎን ያረጋግጡ። ለሁሉም ጠረጴዛዎች አንድ ክራውለር እንጠቀማለን፣ እሱም በየሰዓቱ ይሰራል።
የተከፋፈሉ ጠረጴዛዎች
ጎብኚው ከመጀመሪያው ጅምር በኋላ ለእያንዳንዱ የተቃኘ ባልዲ ጠረጴዛዎች በቅንብሮች ውስጥ በተጠቀሰው የውሂብ ጎታ ውስጥ መታየት አለባቸው። የአቴና ኮንሶል ይክፈቱ እና ጠረጴዛውን ከ Nginx ምዝግብ ማስታወሻዎች ጋር ያግኙ። የሆነ ነገር ለማንበብ እንሞክር፡-
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 am እስከ 2019 ጥዋት ድረስ የተቀበሉትን ሁሉንም መዝገቦች ይመርጣል። ግን ይህ ያልተከፋፈለ ጠረጴዛን ከማንበብ የበለጠ ምን ያህል ውጤታማ ነው? በጊዜ ማህተም በማጣራት አንድ አይነት መዝገቦችን እንወቅ እና እንምረጥ፡
3.59 ሰከንድ እና 244.34 ሜጋባይት ዳታ በአንድ ሳምንት መዝገቦች ብቻ። ማጣሪያን በክፍል እንሞክር፡-
ትንሽ ፈጣን, ግን ከሁሉም በላይ አስፈላጊ - 1.23 ሜጋባይት ውሂብ ብቻ! በዋጋው ውስጥ ቢያንስ 10 ሜጋባይት በጥያቄ ካልሆነ በጣም ርካሽ ይሆናል። ግን አሁንም በጣም የተሻለ ነው, እና በትልቅ የውሂብ ስብስቦች ላይ ልዩነቱ በጣም የሚደነቅ ይሆናል.
Cube.js በመጠቀም ዳሽቦርድ መገንባት
ዳሽቦርዱን ለመሰብሰብ፣ Cube.js የትንታኔ ማዕቀፍ እንጠቀማለን። እሱ በጣም ብዙ ተግባራት አሉት ፣ ግን እኛ ለሁለት እንፈልጋለን-የክፍል ማጣሪያዎችን እና የውሂብ ቅድመ-ውህደትን በራስ-ሰር የመጠቀም ችሎታ። የውሂብ ንድፍ ይጠቀማል
አዲስ Cube.js መተግበሪያ እንፍጠር። አስቀድመን የAWS ቁልል እየተጠቀምን ስለሆነ ላምዳ ለማሰማራት መጠቀሙ ምክንያታዊ ነው። የ Cube.js ደጋፊን በ Heroku ወይም Docker ለማስተናገድ ካቀዱ ለትውልድ ፈጣን አብነት መጠቀም ይችላሉ። ሰነዱ ሌሎችን ይገልፃል።
$ npm install -g cubejs-cli
$ cubejs create nginx-log-analytics -t serverless -d athena
የአካባቢ ተለዋዋጮች በcube.js ውስጥ የውሂብ ጎታ መዳረሻን ለማዋቀር ይጠቅማሉ። ጀነሬተሩ ቁልፎችዎን የሚገልጹበት የ.env ፋይል ይፈጥራል
አሁን ያስፈልገናል
በማውጫው ውስጥ schema
, ፋይል ይፍጠሩ Logs.js
. ለ nginx የውሂብ ሞዴል ምሳሌ ይኸውና፡
የሞዴል ኮድ
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 backend ያቀርባል
የCube.js አገልጋይ ጥያቄውን በ ውስጥ ይቀበላል
{
"measures": ["Logs.errorCount"],
"timeDimensions": [
{
"dimension": "Logs.createdAt",
"dateRange": ["2019-01-01", "2019-01-07"],
"granularity": "day"
}
]
}
የCube.js ደንበኛን እና የReact አካል ላይብረሪውን በNPM በኩል እንጫን፡-
$ 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>
);
}}
/>
)
}
ዳሽቦርድ ምንጮች በ ላይ ይገኛሉ
ምንጭ: hab.com