きな粉もち.net

.NET関連仕事に携わっています。OSSのソースを読んで気がついたことを中心に呟いたりブログに投稿したりしています。最近はUiPathを使ったRPAも研究中。気軽にフォローやツッコミよろしくおねがいします! Gitはここを使っています https://github.com/kinakomotitti

FileBeats×Logstash×.NET Core コンソールアプリのログを出力する設定をまとめてみた

この記事の目的

この記事では、
.NET coreのコンソールアプリから出力されるメッセージ(ログ)を

Filebeats×Logstashで収集・加工・表示するための設定をまとめること
を目的としています。


本題

★.NET coreのアプリ作成

コンソールアプリを含んだDockerImageを作成します。特に凝ったことはしないで、1回だけ、ログを出力する処理を実装します。

using System;
using System.Text;
namespace SampleConsoleApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("Sample01");
            builder.Append(",");
            builder.Append("Parameter01");
            builder.Append(",");
            builder.Append("Parameter02");
            builder.Append(",");
            builder.Append("Parameter03");
            Console.WriteLine(builder.ToString());
        }
    }
}

Dockerfileはこんな感じです。

FROM microsoft/dotnet:2.1-runtime AS base
WORKDIR /app

FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY SampleConsoleApp.csproj SampleConsoleApp/
RUN dotnet restore SampleConsoleApp/SampleConsoleApp.csproj
COPY Program.cs SampleConsoleApp/
WORKDIR /src/SampleConsoleApp
RUN dotnet build SampleConsoleApp.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish SampleConsoleApp.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "SampleConsoleApp.dll"]


作ったDockerImageは、DockerHubでも、Gitlabでもどこでもよいので、Pushしておきます。


★Logstash×Filebeatsの環境

こんな感じのフォルダ構成で各種ファイルを用意します。

.
├── filebeats
│   ├── config
│   │   └── filebeat.docker.yml
│   └── runbeats.bash
└── logstash 
    ├── config
    │   ├── logstash.conf
    │   └── logstash.yml
    └── runstash.bash


★Logstash

config/logstash.confに以下の設定を記述します。これらは、logstashの入力、加工、出力の設定をするための設定になります。

input {
        stdin { }
        beats { port => 5044 }  ←ココを追加。(Beatsから情報を受け取るための口)
}

filter { grok { match => { "message" => [
  'Sample01,%{DATA:parameter01},%{DATA:parameter02},%{DATA:parameter03}$'
] } } }

output {  stdout { codec => rubydebug } }

Gorkの記述などは、こっちに記載
www.kinakomotitti.net


↓logstash.ymlを設定する↓

http.host: "0.0.0.0"
#xpack.monitoring.elasticsearch.url: http://elasticsearch:9200 

コメントアウトしている個所がデフォルトで設定されており、elasticsearchを設定していない場合エラーが発生してしまいます。そのため、あえてコメントアウトした設定ファイルを指定しています。
www.elastic.co


ここまでで、logstashの設定ファイルの準備ができたので、Logstashを起動します。
↓のコマンドでLogstashを起動↓

sudo docker run  --rm -it  \
--volume="$(pwd)/config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf" \
--volume="$(pwd)/config/logstash.yml:/usr/share/logstash/config/logstash.yml" \
-p 8082:5044 \
docker.elastic.co/logstash/logstash:6.5.0


★Filebeats


↓/config/filebeat.docker.yml↓。Filebeatsの設定ファイル

filebeat.config:
  modules:
    path: ${path.config}/modules.d/*.yml
    reload.enabled: false

filebeat.autodiscover:
  providers:
    - type: docker
      templates:
        - condition:
            contains:
              docker.container.image: sample-console ←監視対象にしたいイメージ名を設定
          config:
#参考)https://www.elastic.co/guide/en/beats/filebeat/master/filebeat-input-docker.html
            - type: docker
              containers.ids:
                - "${data.docker.container.id}"
              exclude_lines: ["^\\s+[\\-`('.|_]"]  # drop asciiart lines

output.logstash:
         hosts: ["kinakolab.westus.cloudapp.azure.com:8082"]

www.elastic.co


今回は、Auto Discover機能のHints設定は利用していません。Hintsの詳細は、以下のURLを参照します。
www.elastic.co


sample-consoleのDockerImageを利用したコンテナの監視設定を有効にしたFileBeatsの準備ができたので、以下のコマンドでFileBeatsを起動します。

sudo docker run --rm -it \
                --name=filebeat \
                --user=root \
                --volume="$(pwd)/config/filebeat.docker.yml:/usr/share/filebeat/filebeat.yml:ro" \
                --volume="/var/lib/docker/containers:/var/lib/docker/containers:ro" \
                --volume="/var/run/docker.sock:/var/run/docker.sock:ro" \
                docker.elastic.co/beats/filebeat:6.5.0 filebeat -e -strict.perms=false



★動作確認

Docker psコマンドを実行し、2つのコンテナが起動していることを確認します。
f:id:kinakomotitti:20190213222412p:plain

ここで、SampleConsoleのDockerImageをrunします。実行は以下のコマンドを利用します。

docker run --rm -it kinacontainerregistry.azurecr.io/sample-console
#出力
# Sample01,Parameter01,Parameter02,Parameter03

無事、Sample01から始まるメッセージが出力されることを確認します。Sample-Consoleを使ったコンテナの標準出力は、これまで設定してきたFileBeatsによって監視され、出力内容はLogstashに連携されます。
そのため、Logstashのコンテナには、以下のような形式の情報が出力されます。

{
     <b>"parameter02" => "Parameter02", ←ココとか</b>
          "input" => {
        "type" => "docker"
    },
           "tags" => [
99        [0] "beats_input_codec_plain_applied"
    ],
         "docker" => {
        "container" => {
            "labels" => {},
                "id" => "7eaf18d",
             "image" => "kinacontainerregistry.azurecr.io/sample-console",
              "name" => "unruffled_kalam"
        }
    },
    "stream" => "stdout",
     <b>"parameter01" => "Parameter01", ←ココとか</b>
     "@timestamp" => 2019-02-07T13:27:56.911Z,
           "beat" => {
         "version" => "6.5.0",
        "hostname" => "6d5038dbf6a3",
            "name" => "6d5038dbf6a3"
    },
         "source" => "/var/lib/docker/containers/8d-json.log",
   <b> "parameter03" => "Parameter03", ←ココ</b>
         <b> "message" => "Sample01,Parameter01,Parameter02,Parameter03",</b>
     "prospector" => {
        "type" => "docker"
    },
       "@version" => "1",
           "host" => {
        "name" => "6d5038dbf6a3"
    },
         "offset" => 0
}

上記のように、Parameter01-03でメッセージの各要素が適切に分類されることを確認できたら成功です!



まとめ

今回は、Docker環境でのFileBeats、Logstash連携環境構築をしました。
ただ、監視したのは、特定のコンテナの標準出力だけです。FileBeatsには、いろいろな種類のモジュールが提供されているので、実際の運用ではそれらの利用についても考えないといけないですね(´△`)
Elastic Stackとの戦いはまだまだこれから・・・