Metricbeatで取得する情報について

metricbeat(5.1.1-1)を利用しております。
監視対象で同一プロセス名のものが複数起動しており、それらを区別したいと考えています。
以下のURLではsystem.process.cmdlineにコマンドラインの情報が含まれるようですが、私の構築環境ではコマンドラインの情報が送信されてきません。
https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-metricset-system-process.html

metricbeat.ymlに設定が不足しているのでしょうか
なお、module: systemのmetricsetsの設定はmetricbeat.ymlのデフォルトから変更しておりません。

Windows版の5.1.1で試しましたが、system.process.cmdlineに引数を含めた値が入ることが確認できました。

デフォルトのymlの設定でcmdlineに値は入ると思いますが、何も入らないということでしょうか?
デフォルトの設定ですと、CPUやメモリの値のデータに紛れてしまい、見落としてしまう可能性もあるため、
processだけに絞ってやってみてはいかがでしょう?

以下、こちらで試したときの内容を記載します。

  • elasticsearch: 5.1.1
  • metricbeat: 5.1.1
    ともにlocalhostで実行。

試したこと

  • metricbeatを起動し、elasticsearchにデータを送る
  • コマンドプロンプトから以下を実行した(cmdlineに引数が入ることを確認するため)
ping localhost -t
  • kibanaのConsoleから検索を行い、system.process.cmdlineに値が入っていることを確認

使用したmetricbeat.yml

今回はprocessの内容でしたので、不要なものをすべてコメントアウトし、processだけ送るように設定しました。

#==========================  Modules configuration ============================
metricbeat.modules:

#------------------------------- System Module -------------------------------
- module: system
  metricsets:
    # CPU stats
    #- cpu

    # System Load stats
    #- load

    # Per CPU core stats
    #- core

    # IO stats
    #- diskio

    # Per filesystem stats
    #- filesystem

    # File system summary stats
    #- fsstat

    # Memory stats
    #- memory

    # Network stats
    #- network

    # Per process stats
    - process
  enabled: true
  period: 10s
  processes: ['.*']

検索クエリ

プロセスが多すぎて探しにくいため、"ping localhost -t" としたPIDを求めて、これで検索しました。
この結果が、冒頭に貼り付けた画像の結果となります。

GET metricbeat-2016.12.20/_search
{
  "query": {
      "match": {
        "system.process.pid": "xxxx"
      }
  }
}

回答ありがとうございます。
改めて確認したところ、metricbeatから送信されるデータ(system.process)に、cmdlineが含まれているものと含まれていないものがありました。
cmdlineが含まれない条件がわかればご教授いただきたいです。

結論から言うと、以下の区分けになるようです。

  • cmdlineの中身あり:ユーザモードによるプロセス起動
  • cmdlineの中身なし:カーネルモードによるプロセス起動

cmdlineの情報引用元はコードを見ていると、
Linuxに限っては/proc/PID/cmdlineファイルを元にしているように思います。
このあたりはmetricbeatがというよりは、UnixのProcfsやカーネル周りの話になるかと思います。
なぜカーネルモードによるプロセス起動はcmdlineが空になっているのか、
という点についてはカーネルスレッドの話になって私も理解しきれていない部分が多いので上手く説明できないです。。。
興味があれば突っ込んでも面白い領域だと思いますが、
まずはcmdlineは空であるプロセスとそうじゃないものがある程度の認識でも良いかと思います。

Procfsについて

beatsのコードについて@OS毎のprocess情報収集周り

すいません、もう少しよく見たら起動モード関係なしに確かにcmdlineがあるものとないものがありますね、、、
もう少しよく見てみます。

監視対象で同一プロセス名のものが複数起動しており、それらを区別したいと考えています。

本題のこちらの件ですが、
一番それっぽくわけられるのは「system.process.pid」を使う形かなと思います。
あとは区別した結果、どういう風にデータを使いたい(見たい)のか、になるかなと。
例えば、同一プロセス名のCPU使用率のグラフを描画したいと考えるなら以下のような形で表現出来ると思います。

SSHDのプロセスID別CPU使用率のグラフ

@st1t
goを触った経験がない&cmdlineファイルを修正できないので、
きちんとした検証はできてないのですが、
恐らくcmdlineファイルに記載があるにもかかわらずうまく表示されないものは、
/proc/PID/cmdline内にnull文字が入ってなくて空のスライスを返しちゃうためかと思います。

func (p *Process) fillFromCmdline() (string, error) {
	pid := p.Pid
	cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
	cmdline, err := ioutil.ReadFile(cmdPath)
	if err != nil {
		return "", err
	}
	ret := strings.FieldsFunc(string(cmdline), func(r rune) bool {
		if r == '\u0000' {
			return true
		}
		return false
	})

	return strings.Join(ret, " "), nil
}

null文字の有無を確認してみた

  • nullが含まれているcmdline
[root@SERVER ~]# cat  /proc/1373/cmdline
/sbin/udevd-d[root@SERVER ~]# 
[root@SERVER ~]# sed -e "s/\x0/,/g" /proc/1373/cmdline 
/sbin/udevd,-d,[root@SERVER ~]#
  • cmdlineがあるけどKibanaではデータがないやつ
[root@SERVER ~]# cat  /proc/18023/cmdline 
sshd: USER [priv][root@SERVER ~]# 
[root@SERVER ~]# sed -e "s/\x0/,/g" /proc/18023/cmdline 
sshd: USER [priv][root@SERVER ~]# 
[root@SERVER ~]#

PR or issueを書いたほうが良いかもしれない気がしてきたので、
探して報告がなければ時間があるときに書いてみようと思います。

連続投稿すいません。。。

1 Like

調査および、回答ありがとうございます。大変参考になりました。

プロセス名、SIDを使えば区別して表示できることは理解していたのですが、今回の監視環境は同一プロセス名で用途が違うものが混在している状況で、それらを区別して確認したいということがやりたいことでした。
(複数のNodeプロセスが異なる役目で動いており、それぞれの分析をしたい。)

リアルタイムに環境に入ってPIDを確認しながらであれば、ある程度のこともできそうですが、過去の情報等を分析したいとなったときにこのPIDは何用途のものだった?というのがわからなくなるため、cmdlineの情報を用いて区別しようと考えていました。

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.