VMware ESXiのsyslogをElasticsearchに送る方法について

# はじめに
Syslogプロトコルを使ってVMware ESXiのログをElasticsearchに送る方法について説明します。


下の図はVMware ESXiをElasticsearchに送るまでの流れを表した図です。
VMware ESXiからLogstashにログを転送するとElasticsearchにログが転送されます。
![Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888574/fd3e7ca0-0667-46cd-a04c-2f5bcfbfc312.png)



# 環境
本記事で紹介する機器の名前とバージョンについてです。
- VMware ESXi：8.0 Update 2
- Elasticsearch：8.5.1
- Logstash：8.5.1

# Logstashの設定について
Logstashの設定とインストールについて説明します。
Logstashはhelmを使用してKubernetesにインストールしました。

### 手順
1.ls-values.yamlの中身を書きます。
設定ファイルにポート番号が2つ書かれています。
1つ目はsyslogのポート番号31514です。2つ目はbeatsのポート番号30544です。
本記事ではsyslogの送り方なのでポート番号は31514番です。
下記の設定ファイルの20行目`nodePort: 31514`の部分です。

Syslogを送るElasticsearchのアドレスは`http://elasticsearch-master:9200`です。
下記の設定ファイルの下から4行目`hosts => ["http://elasticsearch-master:9200"]`の部分です。


```
logstashJavaOpts: "-Xmx1g -Xms1g"
resources:
  requests:
    cpu: "100m"
    memory: "1Gi"
  limits:
    cpu: "1000m"
    memory: "1Gi"
persistence:
  enabled: True
extraPorts:
  - name: beats
    containerPort: 5044
service:
  type: NodePort
  ports:
    - name: syslog
      port: 5140
      protocol: UDP
      nodePort: 31514
    - name: beats
      port: 5044
      protocol: TCP
      nodePort: 30544
logstashConfig:
  logstash.yml: |
    http.host: 0.0.0.0
    xpack.monitoring.enabled: false
logstashPipeline:
  logstash.conf: |
    input {
      syslog {
        port => 5140
        add_field => { "[@metadata][input_id]" => "syslog_input" }
      }
      beats {
        port => 5044
        add_field => { "[@metadata][input_id]" => "beats_input" }
      }
    }

    filter {
      if [@metadata][input_id] == "syslog_input" {
        mutate {
          replace => { "[@metadata][index_prefix]" => "syslog" }
        }

        grok {
          match => {
            "message" => "%{SYSLOG5424LINE}"
          }
          overwrite => [ "message" ]
          tag_on_failure => ["syslog_parse_failed"]
        }

        if "syslog_parse_failed" in [tags] {
          grok {
            match => {
              "message" => "<%{POSINT:syslog_pri}>%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_host} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}"
            }
            overwrite => [ "message" ]
            remove_tag => ["syslog_parse_failed"]
            tag_on_failure => ["syslog_rfc3164_failed"]
          }
        }

        date {
          match => [ "syslog_timestamp", "ISO8601", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
          target => "@timestamp"
        }
      }
      else if [@metadata][input_id] == "beats_input" {
        if "weblog" in [tags] {
          mutate {
            replace => { "[@metadata][index_prefix]" => "weblog" }
          }

          grok {
            match => { "message" => "%{HTTPD_COMBINEDLOG}" }
            overwrite => [ "message" ]
            tag_on_failure => ["weblog_parse_failed"]
          }

          date {
            match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
            target => "@timestamp"
          }

          if "access_log" in [tags] {
            dissect {
              mapping => {
                "[log][file][path]" => "%{path}/access.%{domain}.log.1"
              }
            }
          }
          if "error_log" in [tags] {
            dissect {
              mapping => {
                "[log][file][path]" => "%{path}/error.%{domain}.log.1"
              }
            }
          }
        }
        else {
          mutate {
            replace => { "[@metadata][index_prefix]" => "beats" }
          }
        }
      }
      else {
        mutate {
          add_field => { "[@metadata][index_prefix]" => "default" }
        }
      }
    }

    output {
      # stdout { codec => rubydebug }
      elasticsearch {
        hosts => ["http://elasticsearch-master:9200"]
        index => "%{[@metadata][index_prefix]}-%{+YYYY.MM.dd}"
      }
    }
```

2.Elasticsearchのhelmを使用するために、以下のコマンドでHelmリポジトリの追加をします
```
helm repo add elastic https://helm.elastic.co
```
```
helm repo update
```

3.Logstashのインストールします
```
helm install ls elastic/logstash -f ls-values.yaml
```
# VMware ESXiのsyslogをElasticsearchに送る方法について
VMware ESXiのsyslogをElasticsearchに送る際の手順について説明します。

### 手順
１. コマンドプロンプトを起動して、ESXiにSSHで接続をします。
```
ssh root@192.168.100.22
```
今回はrootユーザで、IPアドレスが`192.168.100.22`とします。

２. 以下のコマンドでSyslogサーバの設定を行います。
```
esxcli system syslog config set --loghost=192.168.100.192:31514
```
syslogを送る先のLogstashのIPアドレスは192.168.100.192で、ポート番号は31514です。

３. Syslogサーバの設定を反映させるために以下のコマンドを実行します。
```
esxcli system syslog reload
```
４. 以下のコマンドで設定が反映されているかを確認します。
```
esxcli system syslog config get
```
`Remote Host（画像の赤線の部分）`にログサーバのアドレスが表示されていればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888574/2c16e8fa-88e8-40a9-88da-1287521600fc.png)

５. ファイアウォールがありログの転送ができないため、ファイアウォールに許可ルールを追加します。
```
esxcli network firewall ruleset set --ruleset-id=syslog --enabled=true
```
６. 以下のコマンドでファイアウォールの許可ルールを確認します。
```
esxcli network firewall ruleset list --ruleset-id=syslog
```
以下の表示がされたらOKです。
```
Name    Enabled
------  -------
syslog     true
```
↓実際の画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888574/9ca92880-80de-4eb8-a752-c5ac0db464b6.png)

７. Kibanaにアクセスをして、host.hostnameがESXiのホスト名に一致するログを検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888574/0dc7fe7e-b6ef-4aad-a0a2-98872521a338.png)
↑このようにログの確認ができればOKです。


# まとめ
本記事では、ESXiのsyslogをElasticsearchに送る方法について紹介しました。
これにより、ESXiのログをElasticsearchに送ることができるようになります。



# 参考資料
Logstashのインストールについて
https://github.com/cdsl-research/lab-log-elastic/blob/main/elastic-2025/ls-values.yaml
helmのインストールについて
https://artifacthub.io/packages/helm/elastic/logstash