集中式日志分析平臺(tái) - ELK Stack - 關(guān)于logstash的監(jiān)控

運(yùn)行 Logstash 時(shí),它會(huì)自動(dòng)捕獲可用于監(jiān)視Logstash部署的運(yùn)行狀況和性能的運(yùn)行時(shí)指標(biāo)。

Logstash 收集的指標(biāo)包括:

  • Logstash 節(jié)點(diǎn)信息,如配置信息,OS 信息和 JVM 信息;
  • 插件信息,包括已安裝插件的列表;
  • 節(jié)點(diǎn)統(tǒng)計(jì)信息,如 JVM 統(tǒng)計(jì)信息,進(jìn)程統(tǒng)計(jì)信息,事件相關(guān)(event-related)統(tǒng)計(jì)信息和流水線運(yùn)行時(shí)(pipeline runtime)統(tǒng)計(jì)信息;
  • 熱線程;

我們可以使用 X-Pack 中的monitoring UI 來(lái)查看這些指標(biāo),深入了解 Logstash 如何運(yùn)行,或者可以使用 Logstash 提供的基本監(jiān)視 API 來(lái)檢索這些指標(biāo)。對(duì)于我灣,調(diào)研確定采用 searchguard 作為核心安全插件,所以不會(huì)為了一個(gè)無(wú)法整合到監(jiān)控平臺(tái)的 X-Pack monitoring 功能而去引入,我決定直接走 API 的方式提供指標(biāo)數(shù)據(jù)。

監(jiān)控 API 介紹

Logstash提供以下監(jiān)視API來(lái)檢索有關(guān)Logstash的運(yùn)行時(shí)指標(biāo):

  • 節(jié)點(diǎn)信息API
  • 插件信息API
  • 節(jié)點(diǎn)統(tǒng)計(jì)API
  • 熱線程API

您可以使用根資源來(lái)檢索有關(guān)Logstash實(shí)例的一般信息,包括主機(jī)和版本。

curl -XGET 'localhost:9600/?pretty'

響應(yīng)示例:

{
   "host": "skywalker",
   "version": "5.5.0",
   "http_address": "127.0.0.1:9600"
}

默認(rèn)情況下,監(jiān)視 API 嘗試綁定到 tcp:9600。如果此端口已被另一個(gè) Logstash 實(shí)例使用,則需要使用指定的—http.port 標(biāo)志啟動(dòng) Logstash 以綁定到其他端口。有關(guān)詳細(xì)信息,請(qǐng)參閱命令行標(biāo)志。

通用選項(xiàng)

以下選項(xiàng)可以應(yīng)用于所有 Logstash 監(jiān)控 API。

  • Pretty 式返回

當(dāng)對(duì)任何請(qǐng)求進(jìn)行追加 ?pretty=true 時(shí),返回的 JSON 將被格式化展示(僅用于調(diào)試);

  • Human-Readable 式輸出

對(duì)于Logstash 5.5.0,只有 Hot Threads API 支持該選項(xiàng)。當(dāng)指定 human=true 時(shí),結(jié)果將以純文本而不是 JSON 格式返回。默認(rèn)值為false。

統(tǒng)計(jì)信息會(huì)以適合人類閱讀的格式(例如 "exists_time": "1h" or "size": "1kb")和計(jì)算機(jī)適合解釋處理的格式(例如 "exists_time_in_millis": 3600000 or "size_in_bytes": 1024)返回。可以通過(guò)向查詢字符串添加 ?human=false 來(lái)關(guān)閉。當(dāng)統(tǒng)計(jì)數(shù)據(jù)的結(jié)果被監(jiān)視工具消費(fèi)時(shí),而不是為人類消費(fèi)而言,這是有道理的。human 標(biāo)識(shí)位默認(rèn)為 false。

節(jié)點(diǎn)信息 API

該 API 用于獲取關(guān)于 logstash 節(jié)點(diǎn)的信息:

curl -XGET 'localhost:9600/_node/<types>'

<types> 是可選項(xiàng),用來(lái)指定返回哪個(gè)類型的數(shù)據(jù)。

我們可以通過(guò)以下幾種類型的組合來(lái)限制返回的信息(類型之間用逗號(hào)間隔):

類型 描述
pipeline 獲取 pipeline 相關(guān)的信息和配置;
os 獲取節(jié)點(diǎn)級(jí)別的 OS 信息;
jvm 獲取節(jié)點(diǎn)級(jí)別的 JVM 信息,包括線程信息;

Pipeline 信息

以下的請(qǐng)求返回 pipeline 相關(guān)信息,包括 workers 的數(shù)量,批處理大小,以及批處理延遲:

curl -XGET 'localhost:9600/_node/pipeline?pretty'

如果想獲得更多的 pipeline 信息,比如各個(gè) input/filter/output 的信息,可以參閱 Pipeline Stats 部分。

返回示例:

{
  "pipeline": {
    "workers": 8,
    "batch_size": 125,
    "batch_delay": 5,
    "config_reload_automatic": true,
    "config_reload_interval": 3
    "id" : "main"
  }

OS 信息

以下請(qǐng)求返回關(guān)于 OS 相關(guān)信息,比如 OS 名稱、架構(gòu)、版本和可用的處理器個(gè)數(shù):

curl -XGET 'localhost:9600/_node/os?pretty'

返回示例:

{
  "os": {
    "name": "Mac OS X",
    "arch": "x86_64",
    "version": "10.12.4",
    "available_processors": 8
  }

JVM 信息

以下請(qǐng)求返回節(jié)點(diǎn)級(jí)別 JVM 信息,比如節(jié)點(diǎn)級(jí)別 JVM 進(jìn)程號(hào)、版本、VM 信息、內(nèi)存使用率以及 GC 信息:

curl -XGET 'localhost:9600/_node/jvm?pretty'

返回示例:

{
  "jvm": {
    "pid": 59616,
    "version": "1.8.0_65",
    "vm_name": "Java HotSpot(TM) 64-Bit Server VM",
    "vm_version": "1.8.0_65",
    "vm_vendor": "Oracle Corporation",
    "start_time_in_millis": 1484251185878,
    "mem": {
      "heap_init_in_bytes": 268435456,
      "heap_max_in_bytes": 1037959168,
      "non_heap_init_in_bytes": 2555904,
      "non_heap_max_in_bytes": 0
    },
    "gc_collectors": [
      "ParNew",
      "ConcurrentMarkSweep"
    ]
  }
}

插件信息 API

插件信息 API 可以獲取所有已安裝的 logstash 的插件信息。該 API 是基于 bin/logstash-plugin list --verbose 命令返回的信息進(jìn)行處理后得到的。

curl -XGET 'localhost:9600/_node/plugins?pretty'

返回示例:

{
  "total": 93,
  "plugins": [
    {
      "name": "logstash-codec-cef",
      "version": "4.1.2"
    },
    {
      "name": "logstash-codec-collectd",
      "version": "3.0.3"
    },
    {
      "name": "logstash-codec-dots",
      "version": "3.0.2"
    },
    {
      "name": "logstash-codec-edn",
      "version": "3.0.2"
    },
    .
    .
    .
  ]

節(jié)點(diǎn)狀態(tài) API

節(jié)點(diǎn)狀態(tài) API 用于獲取 logstash 運(yùn)行時(shí)的統(tǒng)計(jì)信息。

curl -XGET 'localhost:9600/_node/stats/<types>'

<types> 是可選項(xiàng),用于指定具體返回類型。

默認(rèn)情況下,所有狀態(tài)都會(huì)返回。我們可以通過(guò)各種類型組合(以逗號(hào)分隔)來(lái)過(guò)濾出我們想要的信息:

類型 描述
jvm 獲取 JVM 狀態(tài),包括線程信息、內(nèi)存使用率、GC 和 uptime。
process 獲取進(jìn)程信息,包括文件描述符、內(nèi)存占用以及 CPU 使用率。
pipeline 獲取運(yùn)行時(shí) logstash pipeline 信息。
reloads 獲取運(yùn)行時(shí)配置 reload 的失敗和成功信息。
os 獲取運(yùn)行時(shí)當(dāng) logstash 運(yùn)行在容器中的 cgroups 信息。

JVM 信息

以下請(qǐng)求返回 JVM 信息:

curl -XGET 'localhost:9600/_node/stats/jvm?pretty'

返回示例:

{
  "jvm": {
    "threads": {
      "count": 35,
      "peak_count": 36
    },
    "mem": {
      "heap_used_in_bytes": 318691184,
      "heap_used_percent": 15,
      "heap_committed_in_bytes": 519045120,
      "heap_max_in_bytes": 2075918336,
      "non_heap_used_in_bytes": 189382304,
      "non_heap_committed_in_bytes": 200728576,
      "pools": {
        "survivor": {
          "peak_used_in_bytes": 8912896,
          "used_in_bytes": 9538656,
          "peak_max_in_bytes": 35782656,
          "max_in_bytes": 71565312,
          "committed_in_bytes": 17825792
        },
        "old": {
          "peak_used_in_bytes": 106946320,
          "used_in_bytes": 181913072,
          "peak_max_in_bytes": 715849728,
          "max_in_bytes": 1431699456,
          "committed_in_bytes": 357957632
        },
        "young": {
          "peak_used_in_bytes": 71630848,
          "used_in_bytes": 127239456,
          "peak_max_in_bytes": 286326784,
          "max_in_bytes": 572653568,
          "committed_in_bytes": 143261696
        }
      }
    },
    "gc": {
      "collectors": {
        "old": {
          "collection_time_in_millis": 58,
          "collection_count": 2
        },
        "young": {
          "collection_time_in_millis": 338,
          "collection_count": 26
        }
      }
    },
    "uptime_in_millis": 382701
  }

進(jìn)程信息

以下請(qǐng)求返回進(jìn)程信息:

curl -XGET 'localhost:9600/_node/stats/process?pretty'

返回示例

{
  "process": {
    "open_file_descriptors": 164,
    "peak_open_file_descriptors": 166,
    "max_file_descriptors": 10240,
    "mem": {
      "total_virtual_in_bytes": 5399474176
    },
    "cpu": {
      "total_in_millis": 72810537000,
      "percent": 0,
      "load_average": {
        "1m": 2.41943359375
      }
    }
  }
}

Pipeline 信息

以下請(qǐng)求返回 pipeline 信息,包括:

  • Input/filter/output 的事件數(shù)量;
  • 配置的各個(gè) filter/output 信息;
  • Config reload 成功或失敗的信息(當(dāng) config reload enable 情況下);
  • 持久化隊(duì)列的信息(當(dāng) persistent queues enable 情況下);
curl -XGET 'localhost:9600/_node/stats/pipeline?pretty'

返回示例:

{
  "pipeline" : {
    "events" : {
      "duration_in_millis" : 1955,
      "in" : 100,
      "filtered" : 100,
      "out" : 100,
      "queue_push_duration_in_millis" : 71
    },
    "plugins" : {
      "inputs" : [ {
        "id" : "729b0efdc657715a4a59103ab2643c010fc46e77-1",
        "events" : {
          "out" : 100,
          "queue_push_duration_in_millis" : 71
        },
        "name" : "beats"
      } ],
      "filters" : [ {
        "id" : "729b0efdc657715a4a59103ab2643c010fc46e77-2",
        "events" : {
          "duration_in_millis" : 64,
          "in" : 100,
          "out" : 100
        },
        "matches" : 100,
        "patterns_per_field" : {
          "message" : 1
        },
        "name" : "grok"
      } ],
      "outputs" : [ {
        "id" : "729b0efdc657715a4a59103ab2643c010fc46e77-3",
        "events" : {
          "duration_in_millis" : 1724,
          "in" : 100,
          "out" : 100
        },
        "name" : "stdout"
      } ]
    },
    "reloads" : {
      "last_error" : null,
      "successes" : 2,
      "last_success_timestamp" : "2017-05-25T02:40:40.974Z",
      "last_failure_timestamp" : null,
      "failures" : 0
    },
    "queue" : {
      "events" : 0,
      "type" : "persisted",
      "capacity" : {
        "page_capacity_in_bytes" : 262144000,
        "max_queue_size_in_bytes" : 8589934592,
        "max_unread_events" : 0
      },
      "data" : {
        "path" : "/path/to/data/queue",
        "free_space_in_bytes" : 89280552960,
        "storage_type" : "hfs"
      }
    },
    "id" : "main"
  }
}

Reload 信息

以下請(qǐng)求返回配置 reload 成功和失敗的信息:

curl -XGET 'localhost:9600/_node/stats/reloads?pretty'

返回示例:

{
  "reloads": {
    "successes": 0,
    "failures": 0
  }
}

OS 信息

當(dāng) logstash 運(yùn)行在容器中時(shí),以下請(qǐng)求返回 cgroups 相關(guān)信息,我們可以從中獲取更精確的 CPU 負(fù)載,包括容器是否達(dá)到瓶頸:

curl -XGET 'localhost:9600/_node/stats/os?pretty'

返回示例:

{
  "os" : {
    "cgroup" : {
      "cpuacct" : {
        "control_group" : "/elastic1",
        "usage_nanos" : 378477588075
                },
      "cpu" : {
        "control_group" : "/elastic1",
        "cfs_period_micros" : 1000000,
        "cfs_quota_micros" : 800000,
        "stat" : {
          "number_of_elapsed_periods" : 4157,
          "number_of_times_throttled" : 460,
          "time_throttled_nanos" : 581617440755
        }
      }
    }
  }

熱線程 API

熱線程 API 用來(lái)獲取當(dāng)前 logstash 的熱線程信息。熱線程的定義是:該線程占用很高的 CPU并且執(zhí)行指令持續(xù)很長(zhǎng)時(shí)間。

curl -XGET 'localhost:9600/_node/hot_threads?pretty'

返回示例:

{
    "time": "2017-01-12T12:09:45-08:00",
    "busiest_threads": 3,
    "threads": [
      {
        "name": "LogStash::Runner",
        "percent_of_cpu_time": 1.07,
        "state": "timed_waiting",
        "traces": [
          "java.lang.Object.wait(Native Method)",
          "java.lang.Thread.join(Thread.java:1253)",
          "org.jruby.internal.runtime.NativeThread.join(NativeThread.java:75)",
          "org.jruby.RubyThread.join(RubyThread.java:697)",
          "org.jruby.RubyThread$INVOKER$i$0$1$join.call(RubyThread$INVOKER$i$0$1$join.gen)",
          "org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:663)",
          "org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:198)",
          "org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)",
          "org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)",
          "org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:60)"
        ]
      },
      {
        "name": "[main]>worker7",
        "percent_of_cpu_time": 0.71,
        "state": "waiting",
        "traces": [
          "sun.misc.Unsafe.park(Native Method)",
          "java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)",
          "java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)",
          "java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)",
          "java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)",
          "java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)",
          "org.jruby.RubyThread.lockInterruptibly(RubyThread.java:1470)",
          "org.jruby.ext.thread.Mutex.lock(Mutex.java:91)",
          "org.jruby.ext.thread.Mutex.synchronize(Mutex.java:147)",
          "org.jruby.ext.thread.Mutex$INVOKER$i$0$0$synchronize.call(Mutex$INVOKER$i$0$0$synchronize.gen)"
        ]
      },
      {
        "name": "[main]>worker3",
        "percent_of_cpu_time": 0.71,
        "state": "waiting",
        "traces": [
          "sun.misc.Unsafe.park(Native Method)",
          "java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)",
          "java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)",
          "java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)",
          "java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)",
          "java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)",
          "org.jruby.RubyThread.lockInterruptibly(RubyThread.java:1470)",
          "org.jruby.ext.thread.Mutex.lock(Mutex.java:91)",
          "org.jruby.ext.thread.Mutex.synchronize(Mutex.java:147)",
          "org.jruby.ext.thread.Mutex$INVOKER$i$0$0$synchronize.call(Mutex$INVOKER$i$0$0$synchronize.gen)"
        ]
      }
    ]
  }
}

被允許使用的參數(shù)包括:

參數(shù) 描述
threads 返回的熱線程個(gè)數(shù),默認(rèn)為 3。
human 如為 true,返回 plain text,反之則是 json,默認(rèn)是 false。
ignore_idle_threads 如為 true,不返回閑置線程,默認(rèn)是 true。

可以使用 ?human 參數(shù)返回可讀性較高的格式。

curl -XGET 'localhost:9600/_node/hot_threads?human=true'

human-readable 返回示例:

 ::: {}
 Hot threads at 2017-01-12T12:10:15-08:00, busiestThreads=3:
 ================================================================================
 1.02 % of cpu usage, state: timed_waiting, thread name: 'LogStash::Runner'
        java.lang.Object.wait(Native Method)
        java.lang.Thread.join(Thread.java:1253)
        org.jruby.internal.runtime.NativeThread.join(NativeThread.java:75)
        org.jruby.RubyThread.join(RubyThread.java:697)
        org.jruby.RubyThread$INVOKER$i$0$1$join.call(RubyThread$INVOKER$i$0$1$join.gen)
        org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:663)
        org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:198)
        org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
        org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
        org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:60)
 --------------------------------------------------------------------------------
 0.71 % of cpu usage, state: waiting, thread name: '[main]>worker7'
        sun.misc.Unsafe.park(Native Method)
        java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
        java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
        java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
        java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
        org.jruby.RubyThread.lockInterruptibly(RubyThread.java:1470)
        org.jruby.ext.thread.Mutex.lock(Mutex.java:91)
        org.jruby.ext.thread.Mutex.synchronize(Mutex.java:147)
        org.jruby.ext.thread.Mutex$INVOKER$i$0$0$synchronize.call(Mutex$INVOKER$i$0$0$synchronize.gen)
 --------------------------------------------------------------------------------
 0.71 % of cpu usage, state: timed_waiting, thread name: '[main]>worker3'
        sun.misc.Unsafe.park(Native Method)
        java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
        java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
        java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
        sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
        sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        java.lang.reflect.Method.invoke(Method.java:497)
        org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(JavaMethod.java:466)
        org.jruby.javasupport.JavaMethod.invokeDirect(JavaMethod.java:324)

參考文獻(xiàn)

https://www.elastic.co/guide/en/logstash/current/monitoring-logstash.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容