Fluentdで簡易的な監視シェルスクリプトを実行&Slack通知までしてみた

# はじめに
備忘録記事なのでわかりづらいかもです。

オンプレ環境を想定して、まずはcentos7のコンテナを起動し、そこに必要なものをインストールしていく手順を取ってます。

※docker-composeは使わない。

# Fluentd検証環境構築

## dockerコンテナ起動
※sudo使うために「--privileged」で「/sbin/init」を起動時に実行している。(システム起動時に実行することでprocessNo=1に/sbin/initが実行されるようになる)

```
$ docker run --privileged -d -v `pwd`:`pwd` -it --rm --name centos_like_work_env centos:centos7 /sbin/init

$ docker exec -it centos_like_work_env /bin/bash
```

## Fluentdのインストール

```
$ cat /etc/redhat-release
CentOS Linux release 8.3.2011

$ yum update -y && yum upgrade -y

$ yum install -y wget curl sudo

$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent4.sh | sh
// 省略
Error: Package: td-agent-4.1.1-1.amzn2.x86_64 (treasuredata)
           Requires: libc.so.6(GLIBC_2.25)(64bit)
Error: Package: td-agent-4.1.1-1.amzn2.x86_64 (treasuredata)
           Requires: libncurses.so.6()(64bit)
Error: Package: td-agent-4.1.1-1.amzn2.x86_64 (treasuredata)
           Requires: libtinfo.so.6()(64bit)
```

エラーが出た。

```
$ yum whatprovides libc.so.6
    Loaded plugins: fastestmirror, ovl
    Loading mirror speeds from cached hostfile
    * base: ty1.mirror.newmediaexpress.com
    * extras: ty1.mirror.newmediaexpress.com
    * updates: ty1.mirror.newmediaexpress.com
    glibc-2.17-317.el7.i686 : The GNU libc libraries
    Repo        : base
    Matched from:
    Provides    : libc.so.6

    glibc-2.17-322.el7_9.i686 : The GNU libc libraries
    Repo        : updates
    Matched from:
    Provides    : libc.so.6

    glibc-2.17-323.el7_9.i686 : The GNU libc libraries
    Repo        : updates
    Matched from:
    Provides    : libc.so.6

    glibc-2.17-324.el7_9.i686 : The GNU libc libraries
    Repo        : updates
    Matched from:
    Provides    : libc.so.6

$ yum whatprovides libncurses.so.6
    No matches found

$ yum whatprovides libtinfo.so.6
    No matches found

```


以上より、「glibc」を入れて（更新して）みた。

※「glibc」は、「ジーリブシー」と読み、「GNU C Library」の意味。「GNU Project」によるC言語の標準ライブラリ「libc（リブシー）」

```
$ yum clean all

$ yum -y update glibc
```

で、再度Fluentdのインストールを試みる！

```
$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent4.sh | sh
```

成功！


## Fluentdデーモン起動

```
$ systemctl status td-agent
● td-agent.service - td-agent: Fluentd based data collector for Treasure Data
   Loaded: loaded (/usr/lib/systemd/system/td-agent.service; enabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: https://docs.treasuredata.com/display/public/PD/About+Treasure+Data%27s+Server-Side+Agent

$ sudo systemctl start td-agent
Job for td-agent.service failed because a timeout was exceeded. See "systemctl status td-agent.service" and "journalctl -xe" for details.
```

起動失敗した。

```
$ systemctl status td-agent.service
● td-agent.service - td-agent: Fluentd based data collector for Treasure Data
   Loaded: loaded (/usr/lib/systemd/system/td-agent.service; enabled; vendor preset: disabled)
   Active: activating (start) since Tue 2021-06-01 02:35:42 UTC; 20s ago
     Docs: https://docs.treasuredata.com/display/public/PD/About+Treasure+Data%27s+Server-Side+Agent
  Process: 557 ExecStart=/opt/td-agent/bin/fluentd --log $TD_AGENT_LOG_FILE --daemon /var/run/td-agent/td-agent.pid $TD_AGENT_OPTIONS (code=exited, status=0/SUCCESS)
   CGroup: /docker/732f8c59988d831be02224cce0fc0618f6a0d85c43166bc8b4d03033d7eb3654/docker/732f8c59988d831be02224cce0fc0618f6a0d85c43166bc8b4d03033d7eb3654/system.slice/td-agent.service
           ├─563 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid
           └─566 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid --under-supervisor

Jun 01 02:35:42 732f8c59988d systemd[1]: Stopped td-agent: Fluentd based data collector for Treasure Data.
Jun 01 02:35:42 732f8c59988d systemd[1]: Starting td-agent: Fluentd based data collector for Treasure Data...
Jun 01 02:35:43 732f8c59988d systemd[1]: New main PID 563 does not belong to service, and PID file is not owned by root. Refusing.
Jun 01 02:35:43 732f8c59988d systemd[1]: New main PID 563 does not belong to service, and PID file is not owned by root. Refusing.
```


いろいろ調べて以下のように起動するユーザーをrootに修正してみた。

```
$ vi /usr/lib/systemd/system/td-agent.service
    [Service]
    User=root
    # User=td-agent
    Group=root
    # Group=td-agent
```


再度Fluentdの起動を試みる！

```
$ sudo systemctl start td-agent.service

$ systemctl status td-agent.service
```

成功！

Fluentdの自動起動設定だけ追加でしておく

```
$ systemctl enable td-agent.service
```

## Fluentdのプロセスを確認

```
$ yum clean all

$ yum -y update ps

$ ps auxf | grep td-agent
    root       988  0.0  0.0   9104   924 pts/1    S+   12:58   0:00  \_ grep --color=auto td-agent
    root       920  0.1  1.9 266196 40428 ?        Sl   07:54   0:22 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid
    root       923  0.2  2.4 280444 49300 ?        Sl   07:54   0:44  \_ /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid --under-supervisor
```

親子関係がわかる。


# 簡易監視スクリプトの配置
Fluentdより実行する簡易的なシェルスクリプトを先に配置しておく。
シェルスクリプトは以下の通り。

CPU監視を想定した簡易スクリプト

```
#!/bin/bash

#CPU使用率閾値 100%=100で記載。閾値を超えるようにあえて2に設定。
CPU_LIMIT=2

#CPU使用率取得
CPU_USED=`vmstat | sed '1, 2d' | awk '{print $13 + $14}' | awk '{printf("%d\n",$1)}'`

#CPU使用率の閾値チェック
if [ $CPU_USED -ge $CPU_LIMIT ]; then
echo "cpu over $CPU_USED%, hostname is $HOSTNAME"
fi
```

メモリ監視を想定した簡易スクリプト

```
#!/bin/bash

#メモリ閾値 100%=100で記載。閾値を超えるようにあえて80に設定。
MEM_LIMIT=80

#メモリ使用率取得
MEM_USED=`free | grep Mem | awk '{ print ($2-$3)/$2*100 }' | awk '{printf("%d\n",$1)}'`

#メモリ使用量の閾値チェック
if [ $MEM_USED -ge $MEM_LIMIT ]; then
echo "memory over $MEM_USED%, hostname is $HOSTNAME"
fi
```

スワップ監視を想定した簡易スクリプト

```
#!/bin/bash

#スワップ閾値 100%=100で記載。閾値を超えるよにあえて10に設定。
SWAP_LIMIT=10

#スワップ使用率取得
SWAP_USED=`free | grep Swap | awk '{ print $3/$2*100 }' | awk '{printf("%d\n",$1)}'`

#スワップ使用量の閾値チェック
if [ $SWAP_USED -ge $SWAP_LIMIT ]; then
echo "swap over $SWAP_USED%, hostname is $HOSTNAME"
fi
```

以下のコマンドで、Slackプラグインのインストールをして、

```
sudo td-agent-gem install fluent-plugin-slack
```


以下を参考にwebhook urlの取得をした。
  https://cly7796.net/blog/other/send-a-message-to-slack-using-the-incoming-webhook/

# Fluentdの設定ファイルを編集

既存のtd-agent.confをバックアップ

```
$ mv /etc/td-agent/td-agent.conf /etc/td-agent/default-td-agent.conf
```

設定ファイルを作成

```
$ vi /etc/td-agent/td-agent.conf
```

以下のように記述した。

  ```
  <source>
    @type exec
    tag check.cpu
    run_interval 30s
    command sh /Users/fukazawakeisuke/training/centos_like_work/check_cpu.sh
    format none
  </source>
  
  <source>
    @type exec
    tag check.memory
    run_interval 30s
    command sh /Users/fukazawakeisuke/training/centos_like_work/check_memory.sh
    format none
  </source>
  
  <source>
    @type exec
    tag check.swap
  
    run_interval 30s
    command sh /Users/fukazawakeisuke/training/centos_like_work/check_swap.sh
    format none
  </source>
  
  <match check.*>
    @type slack
    webhook_url https://hooks.slack.com/services/T021RTXSF2M/B02444USS9Y/  j7AcHMKnoKUuIatQOZhe17Kw
    channel er-playground
    color warning
    message %s
    message_keys message
    flush_interval 10s
  </match>
  ```

td-agentを再起動する

```
$ systemctl restart td-agent.service
```

fluentdのログファイルを確認。
Slackに通知が行かないなど、Fluentdがうまく動いていない場合はここにログが出ているはず。
なおFluetndのoutputプラグインでの標準出力もここに出力される。

```
$ tail -f /var/log/td-agent/td-agent.log
```

# 動かすまでに作成したfluentdの設定ファイル達

バージョン1

```
  <source>
    @id in_forward
    @type forward
    port 24224
  </source>
  
  <match test.**>
    @type stdout
  </match>
```

動作検証コマンド

```
$ echo '{"user":"1","message":"Hello World"}' | /opt/td-agent/bin/fluent-cat test.debug
```

バージョン2

```
  <source>
    @type exec
    tag in_exec_test
    command sh /Users/fukazawakeisuke/training/centos_like_work/   surveillance_memory.sh
    format none
    run_interval 30s
  </source>

  <match in_exec_test>
    @type file
    path /tmp/in_exec_test.log
  </match>
```