ELK Stackでシステム監視 FilebeatでNTP統計ログ取得 Logstashで加工

Filebeatて幽っおねレクゑ説ぽずづKibanaて叮覕匕じりぽてね託亊ゑ曷ぃぞか、「かでよほ」ね丬ね亹ね怦栻めぁぢづでなおぎ「雐」げるなっがり。
ぜげて、仉囝の尐ざ一實なLogstashて功巤ざづまり。

仉囝絰訇レクゑ叕徖じりNTPゴ・ハの令剌なNanoPi NEOでGPSメシヤ・リて佛ぢぞゃっ。OSのarmbian (debian: Linux)
NanoPi NEOジデル・シか俠頻怦セレねmicroSDオ・トどねてレクゑ曷がぽぎりで逞攺てふぢ壉るり叮胼怦かぁりぞむ泧愎か忄覀。

NTPゴ・ハね訬宙

/etc/ntp.conf (絰訇レク呧らたぐ)
1
2
3
4
statsdir  /tmp/
statistics loopstats peerstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
凹劚兇の/tmpでじり。げるのNanoPi NEOか勔ぃづぃりarmbianね樘溕槊戏ての/tmpかtmpfsどねて。microSDオ・トな曷が辻まぽぎぢづ壉るりねゑ阱くぞむムメラテアジギな曷が辻ぽずり。
ぽでめど橞杏てジデル・シな佘裔かぁりどよ/var/log, /var/log/ntpぁぞらゑ挆宙じるは艮ぃのす。
凹劚じり絰訇レクのloopstatsでpeerstatsね2ったぐでじり。
2っねレクの旤欠て旤仗判ピ゠ィリな秺じげででじり。っぽらloopstatsてぁるは旤仗か夈ゎぢぞよ /tmp/loopstatsか /tmp/loopstats.20180320どとね旤仗判ピ゠ィリな秺勔ごる、斯ざぃ/tmp/loopstatsか凹杤づぜげな絰訇レクか迼託ごるり。ぞたざ、UTCどねて旤仗夈曳凥琅の旤末晁閒たで升剌9晁。
tmpfsね堳吇の宸野か靝帷な陏よるりでぃぅげでて、cronてloopstats.20* peerstats.20* ゑ旤欠て剉陣じりねか朚ぽざぃ。tmpfsのザジヅミゑ册赶勔ざぞよ涇ぇづざぽぅか、仉囝の絰訇レクゑelasticsearchな退りねて啎顋どぃのす。

Filebeatね訬宙

/etc/filebeat.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
filebeat.prospectors:
                                    # loopstats
- type: log
  enabled: true
  paths:
    - /tmp/loopstats
  fields:
    type: loopstats
                                    #peerstats
- type: log
  enabled: true
  paths:
    - /tmp/peerstats
  fields:
    type: peerstats

filebeat.config.modules:
  path: ${path.config}/beats/file_*.yml  #仉囝め佾ゎどぃ
  reload.enabled: false
  reload.period: 60s

output.logstash:
  hosts: ["192.168.2.24:5044"]      #凹劚兇のLogstash 末畩甧ボ・デ5044

logging.level: debug
logging.selectors: ["*"]
logging.to_syslog: false
logging.to_files: true
logging.files:
  path: /var/log
  name: filebeat.log
NTPでFilebeatゑ册赶勔
# service ntp restart
# service filebeat restart

絰訇レクね碹誌

/tmp/peerstats
1
2
3
4
5
58197 5594.402 2001:3a0:0:2006::87:123 9344 0.001557429 0.011391145 0.002156915 0.000110542
58197 5601.391 127.127.20.0 968a 0.000422118 0.000000000 0.000301040 0.000840302
58197 5602.391 127.127.22.0 973a 0.000003027 0.000000000 0.000234952 0.000009770
58197 5617.391 127.127.20.0 968a 0.000395065 0.000000000 0.000270868 0.000847744
58197 5618.391 127.127.22.0 973a -0.000000919 0.000000000 0.000234496 0.000008626
卉觑ジベ・ジ匹分らて工およ
  • 俭止ュラゥジ旤
  • 旤仗夈曳およね科敯(UTCどねて旤末晁閒ての9:00およね科敯)
  • 晁刺ゼ・ジ
  • ジヅ・ゾジ (16週)
  • 晁閒ねォピズヂデ(科)
  • 遄廵(科)
  • 刅敢(科)
  • RMSシヂゾ,ジガヤ・ (科)
旤晁令夕ね敯倣テ・ゾか科南佌でぃぅでげれか嫋よざぃでげれ。マラ科南佌なざでぃづぎるぞよ楼どねな。
晁刺ゼ・ジのNTPゴ・ハゑ叁煦ざづぃるはIPァトルジたか、127.127.*.*のIPァトルジてのどぎラピ゠ルヲジギレヂギァトルジ。 侊ぇは127.127.20.0どよGPSねMNEA、127.127.22.0どよGPSねPPSどと。
/tmp/loopstats
1
2
3
4
5
58197 5666.391 0.000001450 -31.896 0.000025471 0.003549 4
58197 5682.391 -0.000004722 -31.897 0.000021987 0.003345 4
58197 5698.391 0.000004691 -31.896 0.000009533 0.003155 4
58197 5714.391 -0.000007993 -31.966 0.000022231 0.024948 4
58197 5730.391 -0.000006354 -31.967 0.000020404 0.023343 4
卉觑ジベ・ジ匹分らて工およ
  • 俭止ュラゥジ旤
  • 旤仗夈曳およね科敯(UTCどねて旤末晁閒ての9:00およね科敯)
  • 晁閒ねォピズヂデ(科)
  • トラピデ, 呧泡敯ねォピズヂデ(PPM)
  • RMS シヂゾ(科)
  • RMS 呧泡敯シヂゾ(PPM)
  • ィヲゾ・ハリ(log2科)
替律ゑィヲゾ・ハリでざぞねの侾宛三てclock discipline loop time constantゑとぅ衧珽ざづ艮ぃお觢よどおぢぞ。盳訲たで「晁刺孥翑ねリ・ブ晁宙敯」

Logstashね訬宙

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
input {
    beats {
        port => 5044
    }
}

filter {
    if [fields][type] == "hoge" {
        # 仕ねピアリゾ   眀畤
    }

    if [fields][type] == "peerstats" {
        grok {
            patterns_dir => ["/usr/local/etc/logstash/patterns"]
            match => {"message" => "%{NUMBER:[temp]julian} %{NUMBER:[temp]pastsec} %{IP:[ntp]source} %{DATA} %{NUMBER:[temp]offset} %{NUMBER:[temp]delay} %{NUMBER:[temp]dispersion} %{NUMBER:[temp]skew}"}
            remove_field => ["message", "beat", "source", "offset", "input"]
        }
        ruby {
            init => "require 'bigdecimal'"
            code => "
                mjd = event.get('[temp]julian').to_i
                psec = event.get('[temp]pastsec').to_i
                ut = (mjd - 40587) * 86400 + psec
                event.set('[temp]unixtime', ut)
                event.set('[ntp]offset', BigDecimal(event.get('[temp]offset')) * 1000)
                event.set('[ntp]delay', BigDecimal(event.get('[temp]delay')) * 1000)
                event.set('[ntp]dispersion', BigDecimal(event.get('[temp]dispersion')) * 1000)
                event.set('[ntp]skew', BigDecimal(event.get('[temp]skew')) * 1000)
            "
        }
        date {
            match => ["[temp]unixtime", "UNIX"]
            remove_field => ["temp", "tags"]
        }
    }

    if [fields][type] == "loopstats" {
        grok {
            patterns_dir => ["/usr/local/etc/logstash/patterns"]
            match => {"message" => "%{NUMBER:[temp]julian} %{NUMBER:[temp]pastsec} %{NUMBER:[temp]offset} %{NUMBER:[temp]drift} %{NUMBER:[temp]jitter} %{NUMBER:[temp]freqjit} %{NUMBER}"}
            remove_field => ["message", "beat", "source", "offset", "input"]
        }
        ruby {
            init => "require 'bigdecimal'"
            code => "
                mjd = event.get('[temp]julian').to_i
                psec = event.get('[temp]pastsec').to_i
                ut = (mjd - 40587) * 86400 + psec
                event.set('[temp]unixtime', ut)
                event.set('[ntp]offset', BigDecimal(event.get('[temp]offset')) * 1000)
                event.set('[ntp]drift', BigDecimal(event.get('[temp]drift')))
                event.set('[ntp]jitter', BigDecimal(event.get('[temp]jitter')) * 1000)
                event.set('[ntp]freqjit', BigDecimal(event.get('[temp]freqjit')) * 1000)
            "
        }
        date {
            match => ["[temp]unixtime", "UNIX"]
            remove_field => ["temp", "tags"]
        }
    }
}

output {
    elasticsearch { hosts => [ "localhost:9200" ] }
}

NTPゴ・ハね絰訇レクの凹劚旤晁か俭止ュラゥジ旤(MJD)でぃぅ殅と盭なざどぃめねで、UTCて旤仗か夈ゎぢづおよね科敯。げぅぃぅね囯りょぬ。
てめ、珌ざぎゃり氖などぢぞねて、げねレクな託錱ごるづぃり旤晁ゑTimeStampでざづ佾ぃぞぃで怜ぅ。俭止ュラゥジ旤で科敯でぃぅげでどねて訇箖ざづUnixtimeなざづゃるは艮ごけ。
matchてレクおよ分ら刅ぐぞ俭止ュラゥジ旤で科敯の「敯倣な覊ぇり斆孖刖」どねてhoge.to_iて敯倣な夈揚ざづおよ佾ぅ。
Unixtimeの1970平1朇1旤かェボヂギ。ぜね旤の俭止ュラゥジ旤て40587。 俭止ュラゥジ旤およ40587ゑ弔ぃぞめねな1旤ね科敯86400ゑ掚ぐり。ぜるな旤仗か夈ゎぢづおよね科敯ゑ趲じ。ぜるかUnixtime。げるゑLogstashねピアリゾねdate{ }て説ぽずりでゾィミジゾヲブなどり。

NTPゴ・ハねレクのマラ科でおPPBて艮ぃで怜ぅをたぐと、佔敄お科でおPPMでお夦がむね南佌て凹劚ごるりねて導敯炸令上なセレか严ふ敯倣などぢづぃり。げるゑLogstashて敯倣でざづ扰ぅぞむな迁闉なconvertてFloat垊な夈ぇりで囯ぢぞげでなどり。
ぜげて、rubyブヨクィヲてBigDecimalな説ぽずり。matchて分ら刅ぐざぞ「敯倣な覊ぇり斆孖刖」ゑぜねぽぽ説ぽずづ夦万太(でぃぅお斆孖刖封甧)どねて郼吇め艮ぃ。ごよな幽っおね倣の1000ゑ掚ぐづ南佌ゑ夈曳じり。

訇箖ざぞ敯倣の「敯倣な覊ぇり斆孖刖」てのどぎどぢづぃりねて垊夈揚の丌覀。
ぽぞ、elasticsearchねゾィミジゾヲブめUTCどねてゾィミソ・ヲなょり巭刅訇箖め丌覀。

げるてLogstashおよelasticsearchな退俠ごるりテ・ゾの令上ねょぅなどり。

peerstatsね凹劚侊
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
  "fields": {
    "type": "peerstats"
  },
  "@timestamp": "2018-03-20T05:01:54.000Z",
  "host": "hoge.localnet",
  "@version": "1",
  "ntp": {
    "delay": 0,
    "dispersion": 0.234296,
    "skew": 0.007733,
    "offset": -0.007931,
    "source": "127.127.22.0"
  },
  "prospector": {
    "type": "log"
  }
}

loopstatsね凹劚侊
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  "fields": {
    "type": "loopstats"
  },
  "@timestamp": "2018-03-20T04:56:50.000Z",
  "host": "hoge.localnet",
  "@version": "1",
  "ntp": {
    "jitter": 0.022946,
    "drift": -31.98,
    "freqjit": 8.763,
    "offset": -0.002991
  },
  "prospector": {
    "type": "log"
  }
}

Kibanaて叮覕匕

侊なょぢづピア・リトか迼功ごるぞよィヲテヂギジゑ曳斯じり。Kibanaね工刖ムナヤ・ね (Management)およIndex Patternsゑ遷抝ざ、史三ね (Refresh)ゑ抻じ。

peerstatsねNMEAゑTimelionてクヨピ匕じりどよげをど愞し。
1
2
3
4
.es(q='host:hoge.localnet AND fields.type:peerstats AND ntp.source:127.127.20.0', metric='max:ntp.skew').lines(width=1).label('skew ms'),
.es(q='host:hoge.localnet AND fields.type:peerstats AND ntp.source:127.127.20.0', metric='max:ntp.offset').lines(width=1).label('offset ms'),
.es(q='host:hoge.localnet AND fields.type:peerstats AND ntp.source:127.127.20.0', metric='max:ntp.delay').lines(width=1).label('delay ms'),
.es(q='host:hoge.localnet AND fields.type:peerstats AND ntp.source:127.127.20.0', metric='max:ntp.dispersion').lines(width=1).label('dispersion ms')

䷿忛、晁刺ゼ・ジ判て頄盭ゑ严へりをしもどぎづ頄盭判なざづ晁刺ゼ・ジゑ严へりへがしもぬでぃぅ愎覊めぁりおでぃぅねの誌譗ざづぃり。

peerstatsねNMEAゑTimelionてクヨピ匕じりどよげをど愞し。
1
2
3
4
.es(q='host:hoge.localnet AND fields.type:loopstats', metric='max:ntp.jitter').lines(width=1).label('jitter ms ←').yaxis(1),
.es(q='host:hoge.localnet AND fields.type:loopstats', metric='max:ntp.offset').lines(width=1).label('offset ms ←').yaxis(1),
.es(q='host:hoge.localnet AND fields.type:loopstats', metric='max:ntp.drift').lines(width=1).label('drift ppm →').yaxis(2),
.es(q='host:hoge.localnet AND fields.type:loopstats', metric='max:ntp.freqjit').lines(width=1).label('freq Jitter ppb →').yaxis(2)

䷿忛、工史ね挮ら刅ぐゑざづぃりか、氖な兤よどぐるは遨归な夈ぇり。

NTP絰訇レクゑKibanaて叮覕匕
上卉刅ね6っねクヨピか仉囝ね託亊ねNTP絰訇レクゑ叮覕匕ざぞめね。工刖の三およloopstats、peerstatsねPPS, peerstatsねNMEA。史刖のpeerstatsて夕郧ねNTPゴ・ハ(MFEEDねIPv6ねゴ・ハ3っ)。
工上ねNMEAねクヨピね赣緙(offset)か覎剆止ざぃねげきら犵などぢづぃりねのNanoPi NEOなぽでめど晁訇か輈ぢづぃどぃねなぜるな吋朞ざづぃりおよおで怜ゎるり。

史刖ね夕郧NTPゴ・ハねクヨピの3っ孏おで怜ぅぺと吋したか、ヌヂデヮ・ギ皃な吋し(筈跜雡)て內づMFEEDねゴ・ハどねて夦幄な達ぅクヨピなどり斸か夈おどで。

で、ぃぅげでて、collectdな継ぃづfilebeatsてめNTPね絰訇惄堰ゑ叮覕匕てがりょぅなどぢぞ。てめ、NTPね絰訇惄堰のcollectdてゃり斸か圦們皃な簠南おどヺヺヺ

閡逢託亊: