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

**URL:** <https://discuss.elastic.co/t/metricbeat/69551>\
**Category:** 日本語による質問・議論はこちら\
**Created:** [December 20, 2016, 10:16am UTC](https://discuss.elastic.co/t/metricbeat/69551 "2016-12-20T10:16:10Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![takumi](https://avatars.discourse-cdn.com/v4/letter/t/e5b9ba/32.png) [@takumi](https://discuss.elastic.co/u/takumi)\
**Post date:** [December 20, 2016, 10:16am UTC](https://discuss.elastic.co/t/metricbeat/69551/1 "2016-12-20T10:16:10Z")

</div>

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

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

---

<div class="post-metadata">

**Author:** ![tsgkdt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tsgkdt/32/39151_2.png) [@tsgkdt](https://discuss.elastic.co/u/tsgkdt)\
**Post date:** [December 20, 2016, 12:52pm UTC](https://discuss.elastic.co/t/metricbeat/69551/2 "2016-12-20T12:52:36Z")

</div>

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

 ![](https://us1.discourse-cdn.com/elastic/original/2X/9/9e660225f052947d5706c5e89566db41bec9a588.png)

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

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

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

# 試したこと

- metricbeatを起動し、elasticsearchにデータを送る
- コマンドプロンプトから以下を実行した（cmdlineに引数が入ることを確認するため）

```auto
ping localhost -t

```

- kibanaのConsoleから検索を行い、system.process.cmdlineに値が入っていることを確認

# 使用したmetricbeat.yml

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

```auto
#========================== 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を求めて、これで検索しました。  
この結果が、冒頭に貼り付けた画像の結果となります。

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

```

---

<div class="post-metadata">

**Author:** ![takumi](https://avatars.discourse-cdn.com/v4/letter/t/e5b9ba/32.png) [@takumi](https://discuss.elastic.co/u/takumi)\
**Post date:** [December 21, 2016, 5:36am UTC](https://discuss.elastic.co/t/metricbeat/69551/3 "2016-12-21T05:36:17Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![st1t](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/st1t/32/9188_2.png) [@st1t](https://discuss.elastic.co/u/st1t)\
**Post date:** [December 21, 2016, 9:27am UTC](https://discuss.elastic.co/t/metricbeat/69551/4 "2016-12-21T09:27:56Z")

</div>

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

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

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

# Procfsについて

> **[procfs](https://ja.wikipedia.org/wiki/Procfs)**
>
> procfsは、Process Filesystem の略で、Unix系システムにある擬似ファイルシステム。主にプロセスに関するカーネル情報にアクセスする手段を提供する。procfs は実際のファイルシステムではないので、ディスクスペースを消費しないし、メモリもごくわずかしか消費しない。 通常、procfs は立ち上げ時に /proc ディレクトリにマウントされる。Solaris、BSD、Linux、AIX、QNXなどでサポートされ、特にLinuxではプロセス関連以外のデータにも拡張されている（AIXのprocfsはLinuxベース）。procfs は機能をカーネルモードからユーザーモードに移すことに重要な役割を果たしている。例えば GNUプロジェクト版の psコマンドは全てのデータを procfs から得ており、特別なシステムコールを使用しない。

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

> **[elastic/beats](https://github.com/elastic/beats/tree/6b7df0c1b8b820da7826aa5871de40052ecaaf80/vendor/github.com/shirou/gopsutil/process)**
>
> beats - :tropical\_fish: Beats - Lightweight shippers for Elasticsearch & Logstash

---

<div class="post-metadata">

**Author:** ![st1t](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/st1t/32/9188_2.png) [@st1t](https://discuss.elastic.co/u/st1t)\
**Post date:** [December 21, 2016, 3:00pm UTC](https://discuss.elastic.co/t/metricbeat/69551/5 "2016-12-21T15:00:53Z")

</div>

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

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

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

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

 ![](https://us1.discourse-cdn.com/elastic/original/2X/8/86c84b1a19f6830b4c197d0bb881766d85260cb0.png)

---

<div class="post-metadata">

**Author:** ![st1t](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/st1t/32/9188_2.png) [@st1t](https://discuss.elastic.co/u/st1t)\
**Post date:** [December 21, 2016, 3:48pm UTC](https://discuss.elastic.co/t/metricbeat/69551/6 "2016-12-21T15:48:37Z")

</div>

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

- process\_linux.go  
[https://github.com/elastic/beats/blob/6b7df0c1b8b820da7826aa5871de40052ecaaf80/vendor/github.com/shirou/gopsutil/process/process\_linux.go](https://github.com/elastic/beats/blob/6b7df0c1b8b820da7826aa5871de40052ecaaf80/vendor/github.com/shirou/gopsutil/process/process_linux.go)

- 多分この辺

```auto
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

```auto
[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ではデータがないやつ

```auto
[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を書いたほうが良いかもしれない気がしてきたので、  
探して報告がなければ時間があるときに書いてみようと思います。

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

---

<div class="post-metadata">

**Author:** ![takumi](https://avatars.discourse-cdn.com/v4/letter/t/e5b9ba/32.png) [@takumi](https://discuss.elastic.co/u/takumi)\
**Post date:** [December 22, 2016, 12:29pm UTC](https://discuss.elastic.co/t/metricbeat/69551/7 "2016-12-22T12:29:08Z")

</div>

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

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

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

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [January 19, 2017, 12:29pm UTC](https://discuss.elastic.co/t/metricbeat/69551/8 "2017-01-19T12:29:15Z")

</div>

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