د ایمیزون ایتینا او Cube.js په کارولو سره د نګینکس لاګ تحلیلونه

عموما، سوداګریز محصولات یا چمتو شوي خلاصې سرچینې بدیلونه، لکه Prometheus + Grafana، د Nginx د عملیاتو نظارت او تحلیل لپاره کارول کیږي. دا د څارنې یا ریښتیني وخت تحلیلونو لپاره ښه اختیار دی ، مګر د تاریخي تحلیل لپاره خورا اسانه ندي. په هرې مشهورې سرچینې کې، د نګینکس لاګونو څخه د معلوماتو حجم په چټکۍ سره وده کوي، او د ډیټا لوی مقدار تحلیل کولو لپاره، دا منطقي ده چې یو څه نور تخصص وکاروئ.

پدې مقاله کې به زه تاسو ته ووایم چې تاسو څنګه کارولی شئ ایتینا د لاګونو تحلیل کولو لپاره ، د مثال په توګه نګینکس اخیستل ، او زه به وښیم چې څنګه د خلاصې سرچینې cube.js چوکاټ په کارولو سره د دې ډیټا څخه تحلیلي ډشبورډ راټول کړم. دلته د بشپړ حل جوړښت دی:

د ایمیزون ایتینا او Cube.js په کارولو سره د نګینکس لاګ تحلیلونه

TL:DR؛
بشپړ شوي ډشبورډ ته لینک.

د معلوماتو راټولولو لپاره چې موږ یې کاروو روانید پروسس لپاره - د AWS Kinesis Data Firehose и د AWS گلود ذخیره کولو لپاره - AWS S3. د دې بنډل په کارولو سره، تاسو کولی شئ نه یوازې د نګینکس لاګونه، بلکې نورې پیښې، او همدارنګه د نورو خدماتو لاګونه ذخیره کړئ. تاسو کولی شئ ځینې برخې د خپل سټیک لپاره ورته ورته سره ځای په ځای کړئ، د بیلګې په توګه، تاسو کولی شئ په مستقیم ډول د نینګکس څخه کینیسیس ته لاګونه ولیکئ، د فلوینډ څخه تېر شئ، یا د دې لپاره لوګسټاش وکاروئ.

د 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" غوره کړئ:

د ایمیزون ایتینا او Cube.js په کارولو سره د نګینکس لاګ تحلیلونه

په بل ټب کې، د "ریکارډ فارمیټ تبادله" غوره کړئ - "فعال شوی" او د ثبت کولو فارمیټ په توګه "اپاچی ORC" غوره کړئ. د ځینو څیړنو له مخې Owen O'Malleyدا د PrestoDB او اتینا لپاره غوره بڼه ده. موږ هغه جدول کاروو چې موږ پورته جوړ کړی د سکیما په توګه. مهرباني وکړئ په یاد ولرئ چې تاسو کولی شئ په کینیسیس کې د S3 ځای مشخص کړئ؛ یوازې سکیما د میز څخه کارول کیږي. مګر که تاسو د S3 مختلف ځای مشخص کړئ، نو تاسو به د دې میز څخه دا ریکارډونه ونه لوستل شئ.

د ایمیزون ایتینا او Cube.js په کارولو سره د نګینکس لاګ تحلیلونه

موږ د ذخیره کولو لپاره S3 غوره کوو او هغه بالټ چې موږ مخکې جوړ کړی. Aws Glue Crawler، چې زه به یې په اړه لږ وروسته خبرې وکړم، نشي کولی په S3 بالټ کې د مخکینیو سره کار وکړي، نو دا مهمه ده چې دا خالي پریږدئ.

د ایمیزون ایتینا او Cube.js په کارولو سره د نګینکس لاګ تحلیلونه

پاتې اختیارونه ستاسو د بار پراساس بدل کیدی شي؛ زه معمولا ډیفالټ کاروم. په یاد ولرئ چې S3 کمپریشن شتون نلري، مګر ORC د ډیفالټ لخوا اصلي کمپریشن کاروي.

روانی

اوس چې موږ د لاګونو ذخیره کول او ترلاسه کول تنظیم کړل، موږ اړتیا لرو چې لیږل تنظیم کړو. موږ به وکاروو روانیځکه چې زه روبي سره مینه لرم، مګر تاسو کولی شئ لوګسټاش وکاروئ یا مستقیم کینیسیس ته لاګونه واستوئ. Fluentd سرور په څو لارو پیل کیدی شي، زه به تاسو ته د ډاکر په اړه ووایم ځکه چې دا ساده او مناسب دی.

لومړی، موږ د 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 لري د فایل tail پلگ ان.

راځئ چې پورته ترتیب شوي لاګ پارسینګ د روانی ترتیب کې اضافه کړو:

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

او Kinesis په کارولو سره لاګونه لیږل kinesis firehose پلگ ان:

<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 بجو پورې ترلاسه شوي ټول ریکارډونه غوره کړي. مګر دا د غیر تقسیم شوي میز څخه د لوستلو په پرتله څومره اغیزمن دی؟ راځئ چې ورته ریکارډونه ومومئ او غوره کړئ، د مهال ویش په واسطه یې فلټر کړئ:

د ایمیزون ایتینا او Cube.js په کارولو سره د نګینکس لاګ تحلیلونه

په ډیټا سیټ کې 3.59 ثانیې او 244.34 میګابایټ ډیټا یوازې د یوې اونۍ لاګونو سره. راځئ چې د تقسیم له مخې فلټر هڅه وکړو:

د ایمیزون ایتینا او Cube.js په کارولو سره د نګینکس لاګ تحلیلونه

یو څه ګړندی ، مګر خورا مهم - یوازې 1.23 میګابایټ ډیټا! دا به خورا ارزانه وي که چیرې په نرخ کې د هرې غوښتنې لږترلږه 10 میګابایټ لپاره نه وي. مګر دا لاهم خورا ښه دی ، او په لوی ډیټاسیټونو کې به توپیر خورا ډیر اغیزناک وي.

د Cube.js په کارولو سره د ډشبورډ جوړول

د ډشبورډ راټولولو لپاره، موږ د Cube.js تحلیلي چوکاټ کاروو. دا خورا ډیری دندې لري ، مګر موږ په دوه کې علاقه لرو: په اتوماتيک ډول د برخې فلټرونو کارولو وړتیا او د معلوماتو دمخه راټولول. دا د ډیټا سکیما کاروي د معلوماتو سکیما، په جاوا سکرپٹ کې لیکل شوی ترڅو SQL رامینځته کړي او د ډیټابیس پوښتنې اجرا کړي. موږ یوازې اړتیا لرو چې د ډیټا سکیما کې د برخې فلټر کارولو څرنګوالی وښیو.

راځئ چې یو نوی 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`
    }
  }
});

دلته موږ متغیر کاروو FILTER_PARAMSد برخې فلټر سره د SQL پوښتنې رامینځته کولو لپاره.

موږ میټریکونه او پیرامیټونه هم تنظیم کوو چې موږ یې په ډشبورډ کې ښودل غواړو او مخکې راټولول مشخص کړو. 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 پس منظر وړاندې کوي REST API او د مشهور مخکني چوکاټ چوکاټونو لپاره د پیرودونکي کتابتونونو سیټ. موږ به د ډشبورډ جوړولو لپاره د پیرودونکي عکس العمل نسخه وکاروو. Cube.js یوازې ډاټا چمتو کوي، نو موږ به د لید کتابتون ته اړتیا ولرو - زه دا خوښوم بیا چارټ، مګر تاسو کولی شئ هر یو وکاروئ.

د Cube.js سرور په کې غوښتنه مني د JSON بڼه، کوم چې اړین میټریکونه مشخص کوي. د مثال په توګه، د دې محاسبه کولو لپاره چې نګینکس په ورځ کې څومره غلطیانې ورکړي، تاسو اړتیا لرئ لاندې غوښتنه واستوئ:

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

Add a comment