Logstashメモ - (1)インストール/簡易操作

# はじめに
Logstashについてのメモ書きです。

## 関連記事
[Logstashメモ - (1)インストール/簡易操作](https://qiita.com/tomotagwork/items/a40844aabfaec7449514)
[Logstashメモ - (2) 設定ファイル関連](https://qiita.com/tomotagwork/items/da11057781d6eb7abdad)

# Logstash概要
LogstashはElastic社が提供しているログ収集のためのミドルウェア(OSS)です。
多種多様なログをリアルタイムにパイプライン処理を行い、フォーマット変換などを行って、目的の転送先(データストアなど)に送ることができます。
例えば、様々なプラットフォーム/ミドルウェア/アプリケーションのログなどを、統一的なフォーマットに変換してElasticsearchに投入して管理する、といったことができます。

Logstashでは、主に、以下の流れでデータを処理しますので、それぞれに対してどのような処理を行うかを、構成ファイルで定義していくことになります。

- **input**: 入力となる情報を定義します。特定のディレクトリの特定の名前のファイルを読み込んだり、特定のポートをListenしてTCP経由でデータを受け取ったりすることができます。また、そこで受け付けるデータのフォーマット(CSVやJSONなど)を指定することになります。
- **filter**: 必要に応じて受け取ったデータの変換処理を行います(フォーマット変換や不要なフィールドの削除など)
- **output**: データ転送先を指定します。Elasticsearchなどのデータストアに対して結果を格納したり、デバッグ用に標準出力に結果を吐き出すこともできます。

参考: [Logstashの実践的な説明](https://www.elastic.co/jp/blog/a-practical-introduction-to-logstash)


# Linux(RHEL)
## インストール
以下から適当なパッケージを選択してダウンロードします。
[Download Logstash](https://www.elastic.co/jp/downloads/logstash)

ここではRHELの想定で、RPMファイルをダウンロードし、rpmコマンドでインストールします。

LogstashはJavaで実装されているので、事前にjavaコマンドが実行できる状態にしておく必要があります。
参考: [Installing Logstash](https://www.elastic.co/guide/en/logstash/7.5/installing-logstash.html)

## 簡易操作例1

標準入力から3カラムのCSVデータをインプットし、それを解釈させて、標準出力に結果を表示する、というのをやってみます。

適当なディレクトリにtest01.confという構成ファイルを作成します。

```ruby:~/logstash/test01.conf
input {
        stdin { }
}

filter {
        csv{
                columns => ["field01","field02","field03"]
        }
}

output {
        stdout{ }
}
```

Logstashを起動します。

```
[root@test08 ~/logstash]# /usr/share/logstash/bin/logstash -f test01.conf
OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules (file:/usr/share/logstash/logstash-core/lib/jars/jruby-complete-9.2.7.0.jar) to field java.io.FileDescriptor.fd
WARNING: Please consider reporting this to the maintainers of com.headius.backport9.modules.Modules
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Thread.exclusive is deprecated, use Thread::Mutex
WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs errors to the console
[WARN ] 2020-01-21 09:01:24.853 [LogStash::Runner] multilocal - Ignoring the 'pipelines.yml' file because modules or command line options are specified
[INFO ] 2020-01-21 09:01:24.864 [LogStash::Runner] runner - Starting Logstash {"logstash.version"=>"7.2.0"}
[WARN ] 2020-01-21 09:01:27.255 [[main]-pipeline-manager] LazyDelegatingGauge - A gauge metric of an unknown type (org.jruby.RubyArray) has been create for key: cluster_uuids. This may result in invalid serialization.  It is recommended to log an issue to the responsible developer/development team.
[INFO ] 2020-01-21 09:01:27.261 [[main]-pipeline-manager] javapipeline - Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>6, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>750, :thread=>"#<Thread:0x6d44dcf8 run>"}
[INFO ] 2020-01-21 09:01:27.360 [[main]-pipeline-manager] javapipeline - Pipeline started {"pipeline.id"=>"main"}
The stdin plugin is now waiting for input:
[INFO ] 2020-01-21 09:01:27.425 [Ruby-0-Thread-1: /usr/share/logstash/lib/bootstrap/environment.rb:6] agent - Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[INFO ] 2020-01-21 09:01:27.665 [Api Webserver] agent - Successfully started Logstash API endpoint {:port=>9600}
```

標準入力からデータを受け取るようにしているので、ここに、CSVデータを手入力してEnterをおします。ここでは、「aaa,bbb,ccc」と打ってEnter押してみます。

```
aaa,bbb,ccc
/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/awesome_print-1.7.0/lib/awesome_print/formatters/base_formatter.rb:31: warning: constant ::Fixnum is deprecated
{
       "field02" => "bbb",
       "field03" => "ccc",
          "host" => "test08",
       "field01" => "aaa",
       "message" => "aaa,bbb,ccc",
      "@version" => "1",
    "@timestamp" => 2020-01-21T00:02:47.331Z
}
```

元のデータは、"message"というフィールドで扱われます。field01, field02, field03という項目で、それぞれ、"aaa", "bbb", "ccc"がハンドリングされたことが分かります。その他@timestampでデータが取り込まれた時刻などの情報が一緒に保持されていることが確認できます。

Ctrl-Cでlogstashが停止します。

## 簡易操作例2

標準入力ではなく、CSVファイルを入力として同様のことを実施してみます。
入力データとなるCSVファイルを用意します。

```csv:/root/logstash/data/test02a.csv
aaa,bbb,ccc
ddd,eee,fff
```

CSVファイルを入力とする構成ファイルを用意します。

```ruby:~/logstash/test02.conf
input{
        file{
                path => ["/root/logstash/data/test02*.csv"]
                start_position => "beginning"
                sincedb_path => "/root/logstash/data/test02.sincedb"
        }
}

filter {
        csv{
                columns => ["field01","field02","field03"]
        }
}

output {
        stdout{ }
}
```

上の構成ファイルを指定してLogstashを起動します。

```
[root@test08 ~/logstash]# /usr/share/logstash/bin/logstash -f test02.conf
OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules (file:/usr/share/logstash/logstash-core/lib/jars/jruby-complete-9.2.7.0.jar) to field java.io.FileDescriptor.fd
WARNING: Please consider reporting this to the maintainers of com.headius.backport9.modules.Modules
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Thread.exclusive is deprecated, use Thread::Mutex
WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs errors to the console
[WARN ] 2020-01-21 09:07:28.078 [LogStash::Runner] multilocal - Ignoring the 'pipelines.yml' file because modules or command line options are specified
[INFO ] 2020-01-21 09:07:28.087 [LogStash::Runner] runner - Starting Logstash {"logstash.version"=>"7.2.0"}
[WARN ] 2020-01-21 09:07:30.435 [[main]-pipeline-manager] LazyDelegatingGauge - A gauge metric of an unknown type (org.jruby.RubyArray) has been create for key: cluster_uuids. This may result in invalid serialization.  It is recommended to log an issue to the responsible developer/development team.
[INFO ] 2020-01-21 09:07:30.439 [[main]-pipeline-manager] javapipeline - Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>6, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>750, :thread=>"#<Thread:0x4ded9789 run>"}
[INFO ] 2020-01-21 09:07:30.783 [[main]-pipeline-manager] javapipeline - Pipeline started {"pipeline.id"=>"main"}
[INFO ] 2020-01-21 09:07:30.838 [[main]<file] observingtail - START, creating Discoverer, Watch with file and sincedb collections
[INFO ] 2020-01-21 09:07:30.855 [Ruby-0-Thread-1: /usr/share/logstash/lib/bootstrap/environment.rb:6] agent - Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[INFO ] 2020-01-21 09:07:31.122 [Api Webserver] agent - Successfully started Logstash API endpoint {:port=>9600}
/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/awesome_print-1.7.0/lib/awesome_print/formatters/base_formatter.rb:31: warning: constant ::Fixnum is deprecated
{
          "path" => "/root/logstash/data/test02.csv",
      "@version" => "1",
       "field02" => "bbb",
       "field01" => "aaa",
       "field03" => "ccc",
       "message" => "aaa,bbb,ccc",
    "@timestamp" => 2020-01-21T00:07:31.260Z,
          "host" => "test08"
}
{
          "path" => "/root/logstash/data/test02.csv",
      "@version" => "1",
       "field02" => "eee",
       "field01" => "ddd",
       "field03" => "fff",
       "message" => "ddd,eee,fff",
    "@timestamp" => 2020-01-21T00:07:31.284Z,
          "host" => "test08"
}
```

test02*.csvファイルが読まれて、各行のカラムが個別のフィールドとして解釈されていることが分かります。Logstashを起動した状態のまま、test02a.csvファイルに行を追加してみます。

```xxx:行追加
[root@test08 ~/logstash/data]# echo ggg,hhh,iii >> test02a.csv
```

```logstash出力結果
{
       "message" => "ggg,hhh,iii",
          "host" => "test08",
       "field02" => "hhh",
       "field03" => "iii",
       "field01" => "ggg",
          "path" => "/root/logstash/data/test02a.csv",
      "@version" => "1",
    "@timestamp" => 2020-01-21T00:26:56.225Z
}
```

追加された行も同様に解釈されることが分かります。(file input pluginでは、デフォルトではtail modeで稼働するため、対象のファイルをtailで監視している状態になる)

## 簡易操作例3

TCP経由でJSONデータを送信するようなアプリがある前提で、それをLogstashで受け付けることを想定します。
以下の構成ファイルを作成します。

```ruby:~/logstash/test03.conf
input{
        tcp{
                port => 8081
        }
}

filter {
        json { source => "message" }
}

output {
        stdout{ }
}
```

上の構成ファイルを指定してLogstashを起動します。

```
[root@test08 ~/logstash]# /usr/share/logstash/bin/logstash -f test03.conf
OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules (file:/usr/share/logstash/logstash-core/lib/jars/jruby-complete-9.2.7.0.jar) to field java.io.FileDescriptor.fd
WARNING: Please consider reporting this to the maintainers of com.headius.backport9.modules.Modules
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Thread.exclusive is deprecated, use Thread::Mutex
WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs errors to the console
[WARN ] 2020-01-22 18:00:48.294 [LogStash::Runner] multilocal - Ignoring the 'pipelines.yml' file because modules or command line options are specified
[INFO ] 2020-01-22 18:00:48.304 [LogStash::Runner] runner - Starting Logstash {"logstash.version"=>"7.2.0"}
[WARN ] 2020-01-22 18:00:50.115 [[main]-pipeline-manager] LazyDelegatingGauge - A gauge metric of an unknown type (org.jruby.RubyArray) has been create for key: cluster_uuids. This may result in invalid serialization.  It is recommended to log an issue to the responsible developer/development team.
[INFO ] 2020-01-22 18:00:50.119 [[main]-pipeline-manager] javapipeline - Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>6, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>750, :thread=>"#<Thread:0x74d114c run>"}
[INFO ] 2020-01-22 18:00:50.446 [[main]-pipeline-manager] javapipeline - Pipeline started {"pipeline.id"=>"main"}
[INFO ] 2020-01-22 18:00:50.462 [[main]<tcp] tcp - Starting tcp input listener {:address=>"0.0.0.0:8081", :ssl_enable=>"false"}
[INFO ] 2020-01-22 18:00:50.686 [Ruby-0-Thread-1: /usr/share/logstash/lib/bootstrap/environment.rb:6] agent - Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[INFO ] 2020-01-22 18:00:50.890 [Api Webserver] agent - Successfully started Logstash API endpoint {:port=>9600}
```

8081ポートがListenされていることを確認します。

```
[root@test08 ~]# netstat -an | grep 8081
tcp6       0      0 :::8081                 :::*                    LISTEN
```

telnetコマンドで8081ポートに接続し、以下のようなJSONデータを送り込んでみます。
{"fieldA":"AAA","fieldB":"BBB","fieldC":"CCC","message":"XXX,YYY,ZZZ"}

```
[root@test08 ~]# telnet localhost 8081
Trying ::1...
Connected to localhost.
Escape character is '^]'.
{"fieldA":"AAA","fieldB":"BBB","fieldC":"CCC","message":"XXX,YYY,ZZZ"}
```

Logstashの出力を確認します。

```
{
        "fieldB" => "BBB",
       "message" => "XXX,YYY,ZZZ",
    "@timestamp" => 2020-01-22T09:01:23.190Z,
        "fieldC" => "CCC",
          "host" => "localhost",
          "port" => 59986,
      "@version" => "1",
        "fieldA" => "AAA"
}
```

送信したJSONデータが認識されており、加えて、タイムスタンプや送信元ホスト名などの情報が付与されている様子が分かります。


# Windows
## インストール
以下からZipを選択してダウンロードします。
[Download Logstash](https://www.elastic.co/jp/downloads/logstash)

zipを適当な場所に展開します。
例えば、ここではC:\x\logstash-7.5.1に展開します。

LogstashはJavaで実装されているので、インストールされていなければJREをインストールします。
以下からダウンロードしてインストール
[Windows版64ビットJava](https://java.com/ja/download/)

PATHとJAVA_HOME環境変数を設定して、javaコマンドが実行できる状態にします。
参考: [Logstash Reference 7.11 » Setting Up and Running Logstash » Running Logstash on Windows](https://www.elastic.co/guide/en/logstash/current/running-logstash-windows.html)

```
c:\>java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

c:\>echo %JAVA_HOME%
C:\x\Java\jdk1.8.0_144
```

## 簡易操作例1

標準入力から3カラムのCSVデータをインプットし、それを解釈させて、標準出力に結果を表示する、というのをやってみます。

Logstashを展開したディレクトリのconfig以下に、test01.confという構成ファイルを作成します。

```ruby:c_\x\logstash-7.5.1\config\test01.conf
input {
	stdin { }
}

filter {
	csv{
		columns => ["field01","field02","field03"]
	}
}

output {
	stdout{ }
}
```

Logstash起動します。

```
c:\x\logstash-7.5.1>.\bin\logstash.bat -f .\config\test01.conf
Thread.exclusive is deprecated, use Thread::Mutex
Sending Logstash logs to c:/x/logstash-7.5.1/logs which is now configured via log4j2.properties
[2020-01-20T19:11:47,422][INFO ][logstash.setting.writabledirectory] Creating directory {:setting=>"path.queue", :path=>"c:/x/logstash-7.5.1/data/queue"}
[2020-01-20T19:11:47,522][INFO ][logstash.setting.writabledirectory] Creating directory {:setting=>"path.dead_letter_queue", :path=>"c:/x/logstash-7.5.1/data/dead_letter_queue"}
[2020-01-20T19:11:47,612][WARN ][logstash.config.source.multilocal] Ignoring the 'pipelines.yml' file because modules or command line options are specified
[2020-01-20T19:11:47,632][INFO ][logstash.runner          ] Starting Logstash {"logstash.version"=>"7.5.1"}
[2020-01-20T19:11:47,662][INFO ][logstash.agent           ] No persistent UUID file found. Generating new UUID {:uuid=>"a3f8473e-defa-4ca9-8487-dff955d5ffb5", :path=>"c:/x/logstash-7.5.1/data/uuid"}
[2020-01-20T19:11:49,027][INFO ][org.reflections.Reflections] Reflections took 30 ms to scan 1 urls, producing 20 keys and 40 values
[2020-01-20T19:11:50,692][WARN ][org.logstash.instrument.metrics.gauge.LazyDelegatingGauge][main] A gauge metric of an unknown type (org.jruby.RubyArray) has been create for key: cluster_uuids. This may result in invalid serialization.  It is recommended to log an issue to the responsible developer/development team.
[2020-01-20T19:11:50,702][INFO ][logstash.javapipeline    ][main] Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>8, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>1000, "pipeline.sources"=>["c:/x/logstash-7.5.1/config/test01.conf"], :thread=>"#<Thread:0x77b99c2a run>"}
[2020-01-20T19:11:50,802][INFO ][logstash.javapipeline    ][main] Pipeline started {"pipeline.id"=>"main"}
The stdin plugin is now waiting for input:
[2020-01-20T19:11:50,871][INFO ][logstash.agent           ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[2020-01-20T19:11:51,241][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9600}
```

標準入力からデータを受け取るようにしているので、ここに、CSVデータを手入力してEnterをおします。ここでは、「aaa,bbb,ccc」と打ってEnter押してみます。

```
aaa,bbb,ccc
C:/x/logstash-7.5.1/vendor/bundle/jruby/2.5.0/gems/awesome_print-1.7.0/lib/awesome_print/formatters/base_formatter.rb:31: warning: constant ::Fixnum is deprecated
{
    "@timestamp" => 2020-01-20T10:15:18.252Z,
       "message" => "aaa,bbb,ccc\r",
       "field03" => "ccc",
       "field02" => "bbb",
          "host" => "DESKTOP-U7UON7M",
      "@version" => "1",
       "field01" => "aaa"
}
```

元のデータは、"message"というフィールドで扱われます。field01, field02, field03という項目で、それぞれ、"aaa", "bbb", "ccc"がハンドリングされたことが分かります。その他@timestampでデータが取り込まれた時刻などの情報が一緒に保持されていることが確認できます。

Ctrl-Cでlogstashが停止します。


## 簡易操作例2
標準入力ではなく、CSVファイルを入力として同様のことを実施してみます。
入力データとなるCSVファイルを用意します。

```csv:/root/logstash/data/test02a.csv
aaa,bbb,ccc
ddd,eee,fff
```

CSVファイルを入力とする構成ファイルを用意します

```ruby:c_\x\logstash-7.5.1\config\test02.conf
input{
	file{
		path => ["C:/x/logstash-7.5.1/data/test02*.csv"]
		start_position => "beginning"
		sincedb_path => "C:/x/logstash-7.5.1/data/test02.sincedb"
	}
}

filter {
	csv{
		columns => ["field01","field02","field03"]
	}
}

output {
	stdout{ }
}
```

<font color="red">Windowsの場合、パス指定時のディレクトリ区切り文字は、バックスラッシュ(\\)ではなくスラッシュ(/)にしないといけないようです。</font>

上の構成ファイルを指定してLogstashを起動します。

```
c:\x\logstash-7.5.1>.\bin\logstash.bat -f .\config\test02.conf
Thread.exclusive is deprecated, use Thread::Mutex
Sending Logstash logs to c:/x/logstash-7.5.1/logs which is now configured via log4j2.properties
[2020-01-21T09:42:45,298][WARN ][logstash.config.source.multilocal] Ignoring the 'pipelines.yml' file because modules or command line options are specified
[2020-01-21T09:42:45,400][INFO ][logstash.runner          ] Starting Logstash {"logstash.version"=>"7.5.1"}
[2020-01-21T09:42:47,028][INFO ][org.reflections.Reflections] Reflections took 33 ms to scan 1 urls, producing 20 keys and 40 values
[2020-01-21T09:42:49,201][WARN ][org.logstash.instrument.metrics.gauge.LazyDelegatingGauge][main] A gauge metric of an unknown type (org.jruby.RubyArray) has been create for key: cluster_uuids. This may result in invalid serialization.  It is recommended to log an issue to the responsible developer/development team.
[2020-01-21T09:42:49,214][INFO ][logstash.javapipeline    ][main] Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>8, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>1000, "pipeline.sources"=>["c:/x/logstash-7.5.1/config/test02.conf"], :thread=>"#<Thread:0x422ccb1f run>"}
[2020-01-21T09:42:49,874][INFO ][logstash.javapipeline    ][main] Pipeline started {"pipeline.id"=>"main"}
[2020-01-21T09:42:49,932][INFO ][filewatch.observingtail  ][main] START, creating Discoverer, Watch with file and sincedb collections
[2020-01-21T09:42:49,938][INFO ][logstash.agent           ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[2020-01-21T09:42:50,607][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9600}
C:/x/logstash-7.5.1/vendor/bundle/jruby/2.5.0/gems/awesome_print-1.7.0/lib/awesome_print/formatters/base_formatter.rb:31: warning: constant ::Fixnum is deprecated
{
       "field02" => "eee",
    "@timestamp" => 2020-01-21T00:42:50.696Z,
          "host" => "DESKTOP-U7UON7M",
          "path" => "C:/x/logstash-7.5.1/data/test02a.csv",
      "@version" => "1",
       "field03" => "fff",
       "field01" => "ddd",
       "message" => "ddd,eee,fff\r"
}
{
       "field02" => "bbb",
    "@timestamp" => 2020-01-21T00:42:50.652Z,
          "host" => "DESKTOP-U7UON7M",
          "path" => "C:/x/logstash-7.5.1/data/test02a.csv",
      "@version" => "1",
       "field03" => "ccc",
       "field01" => "aaa",
       "message" => "aaa,bbb,ccc\r"
}
```

test02*.csvファイルが読まれて、各行のカラムが個別のフィールドとして解釈されていることが分かります。Logstashを起動した状態のまま、test02a.csvファイルに行を追加してみます。

```xxx:行追加
c:\x\logstash-7.5.1\data>echo 111,222,333>>test02a.csv
```

```logstash出力結果
{
       "field02" => "222",
    "@timestamp" => 2020-01-21T00:48:11.359Z,
          "host" => "DESKTOP-U7UON7M",
          "path" => "C:/x/logstash-7.5.1/data/test02a.csv",
      "@version" => "1",
       "field03" => "333",
       "field01" => "111",
       "message" => "111,222,333\r"
}
```

追加された行も同様に解釈されることが分かります。(file input pluginでは、デフォルトではtail modeで稼働するため、対象のファイルをtailで監視している状態になる)

## 簡易操作例3

TCP経由でJSONデータを送信するようなアプリがある前提で、それをLogstashで受け付けることを想定します。
以下の構成ファイルを作成します。

```ruby:~/logstash/test03.conf
input{
        tcp{
                port => 8081
        }
}

filter {
        json { source => "message" }
}

output {
        stdout{ }
}
```

上の構成ファイルを指定してLogstashを起動します。

```
c:\x\logstash-7.5.1>.\bin\logstash.bat -f .\config\test03.conf
Thread.exclusive is deprecated, use Thread::Mutex
Sending Logstash logs to c:/x/logstash-7.5.1/logs which is now configured via log4j2.properties
[2020-01-21T10:27:25,346][WARN ][logstash.config.source.multilocal] Ignoring the 'pipelines.yml' file because modules or command line options are specified
[2020-01-21T10:27:25,443][INFO ][logstash.runner          ] Starting Logstash {"logstash.version"=>"7.5.1"}
[2020-01-21T10:27:26,917][INFO ][org.reflections.Reflections] Reflections took 30 ms to scan 1 urls, producing 20 keys and 40 values
[2020-01-21T10:27:28,353][WARN ][org.logstash.instrument.metrics.gauge.LazyDelegatingGauge][main] A gauge metric of an unknown type (org.jruby.RubyArray) has been create for key: cluster_uuids. This may result in invalid serialization.  It is recommended to log an issue to the responsible developer/development team.
[2020-01-21T10:27:28,366][INFO ][logstash.javapipeline    ][main] Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>8, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>1000, "pipeline.sources"=>["c:/x/logstash-7.5.1/config/test03.conf"], :thread=>"#<Thread:0x6bce130c run>"}
[2020-01-21T10:27:28,477][INFO ][logstash.inputs.tcp      ][main] Automatically switching from json to json_lines codec {:plugin=>"tcp"}
[2020-01-21T10:27:28,697][INFO ][logstash.javapipeline    ][main] Pipeline started {"pipeline.id"=>"main"}
[2020-01-21T10:27:28,710][INFO ][logstash.inputs.tcp      ][main] Starting tcp input listener {:address=>"0.0.0.0:8081", :ssl_enable=>"false"}
[2020-01-21T10:27:28,759][INFO ][logstash.agent           ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[2020-01-21T10:27:29,272][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9600}
```

8081ポートがListenされていることを確認します。

```
c:\x\logstash-7.5.1>netstat -ano | find "8081"
  TCP         0.0.0.0:8081           0.0.0.0:0              LISTENING       6204
  TCP         [::]:8081              [::]:0                 LISTENING       6204
```

telnetコマンドで8081ポートに接続し、以下のようなJSONデータを送り込んでみます。
{"fieldA":"AAA","fieldB":"BBB","fieldC":"CCC","message":"XXX,YYY,ZZZ"}

Logstashの出力を確認します。

```
{
          "port" => 58339,
    "@timestamp" => 2020-01-21T01:46:22.619Z,
        "fieldB" => "BBB",
       "message" => "XXX,YYY,ZZZ",
        "fieldC" => "CCC",
        "fieldA" => "AAA",
      "@version" => "1",
          "host" => "0:0:0:0:0:0:0:1"
}
```

送信したJSONデータが認識されており、加えて、タイムスタンプや送信元ホスト名などの情報が付与されている様子が分かります。