NLogの出力先をfluentd にしてmongodb経由で中身を見る

NLogのtargetにはいろいろあってasp で作ったWEB Serviceやらファイルやらが使えるけど、 fluentd にすると様々なログ収集が便利になる.

例えばS3に出力するなら
https://docs.fluentd.org/output/s3

ただし内容の確認は `less /var/log/foo.log` みたいなやり方だとLogLevelによるフィルタリングが面倒だったりするので内容を mongodbに集めて見やすくしたい。

ここでは docker 使って fluentd,mongodbを実行してみる


### ディレクトリ構成

```
fluentd
│  docker-compose.yml
├─fluentd
│  │  Dockerfile
│  │
│  └─conf
│          fluentd.conf

```

### docker-compose.yml

```yml
version: '3'
services:
  fluentd:
    build: ./fluentd
    ports:
        - "24224:24224"
        - "24224:24224/udp"
    volumes:
        - ./fluentd/conf:/fluentd/etc
    environment:
        FLUENTD_CONF: fluentd.conf
  mongo:
    image: mongo
    volumes:
        - ./mongo:/data/db
    ports:
        - 27017:27017

```

fluentd と mongodb を起動するようにする。
それぞれ port はデフォルトのまま。

### fluentd/Dockerfile

```dockerfile
FROM fluent/fluentd:latest

# below RUN includes plugin as examples elasticsearch is not required
# you may customize including plugins as you wish

RUN apk add --update --virtual .build-deps \
        sudo build-base ruby-dev \
 && sudo gem install \
        fluent-plugin-mongo \
 && sudo gem sources --clear-all \
 && apk del .build-deps \
 && rm -rf /var/cache/apk/* \
           /home/fluent/.gem/ruby/2.5.0/cache/*.gem
```

fluentd イメージに mongo プラグインを追加する

### fluentd/conf/fluentd.conf

```
<source>
  type forward
  port 24224
  bind 0.0.0.0
</source>

<match consoleapp2.*>
  @type mongo
  host mongo
  port 27017
  database fluentd
  collection consoleapp2

  # for capped collection
  capped
  capped_size 1024m

  # key name of timestamp
  time_key time

  # flush
  flush_interval 10s

</match>
```

fluentd に送信されたログを mongodbに送るような設定。
match に指定しているのは nlog.conf に指定したタグ。

## C# アプリでの設定

### Nlog.Target.Fluentd.NetStandard 

パッケージマネージャーでNlog..Fluentd.NetStandard をインストール

```
install-package  Nlog.Target.Fluentd.NetStandard 
```

## nlog.config

```xml
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Trace"
      internalLogFile="${basedir}\logs\internal-nlog.log">

  <extensions>
  </extensions>

  <variable name="logDirectory" value="${basedir}\logs" />
  <targets>
    <target xsi:type="Fluentd" name="fluentd"
            host="localhost"
            port="24224"
            tag="consoleapp2.log"
            layout="[${level:uppercase=true}] [${threadid}] ${callsite:includeNamespace=false}#${callsite-linenumber} ${message} ${exception:format=tostring}"/>
  </targets>
  <rules>
    <logger name="*" minlevel="Trace" writeTo="fluentd,console" />
  </rules>
</nlog>
```

level とか layout は要件に合わせて適宜設定する

## docker 起動

いつものように

```
docker compose up -d
```

## アプリケーション 実行

```
.\consoleapp2.exe
```

dotnet コマンドの場合

```
dotnet run
```

## データの確認

A5SQL:MK2 とか MongoDB Compass とか使って localhost:27017 に接続する。
対象のコレクション(RDBで言うテーブル)  は fluentd.conf に記述した database、collection となる

こんな感じ

|consoleapp2._id|consoleapp2.level|consoleapp2.message|consoleapp2.logger_name|consoleapp2.sequence_id|consoleapp2.time|
|:---|:---|:---|:---|---:|---:|
|60BB4E09CCC3320012542A29|Trace|[TRACE] [1] TraceInterceptorAsync.InterceptSynchronous#38 Service DoSomething method start |ConsoleApp2.Services.Service|3|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A2A|Trace|[TRACE] [1] TransactionInterceptorAsync.InterceptSynchronous#41 Service DoSomething method start |ConsoleApp2.Services.Service|4|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A2B|Trace|[TRACE] [1] TransactionInterceptorAsync.InterceptSynchronous#45 Service DoSomething method end |ConsoleApp2.Services.Service|5|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A2C|Trace|[TRACE] [1] TraceInterceptorAsync.InterceptSynchronous#40 Service DoSomething method end |ConsoleApp2.Services.Service|6|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A2D|Trace|[TRACE] [1] TraceInterceptorAsync.InternalInterceptAsynchronous#66 Service DoSomethingAsync method start |ConsoleApp2.Services.Service|7|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A2E|Trace|[TRACE] [1] TransactionInterceptorAsync.InternalInterceptAsynchronous#73 Service DoSomethingAsync method start |ConsoleApp2.Services.Service|8|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A2F|Trace|[TRACE] [1] Service.DoSomethingAsync#31 DoSomethingAsync start |ConsoleApp2.Services.Service|9|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A30|Trace|[TRACE] [4] Service.\<DoSomethingAsync\>b__7_0#33 DoSomethingAsync invoking |ConsoleApp2.Services.Service|10|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A31|Trace|[TRACE] [4] TransactionInterceptorAsync.MoveNext#76 Service DoSomethingAsync method end |ConsoleApp2.Services.Service|11|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A32|Trace|[TRACE] [4] TraceInterceptorAsync.MoveNext#68 Service DoSomethingAsync method end |ConsoleApp2.Services.Service|12|2021/06/05 10:11:21|
|60BB4E09CCC3320012542A33|Trace|[TRACE] [4] Service.Dispose#22 Service disposed |ConsoleApp2.Services.Service|13|2021/06/05 10:11:21|

## その他

オンプレミスやらクラウドやらに各サービスを載せたいならそれなりにする。

## 参考

この記事自体の参考は

https://yurufuwa-tech.hatenablog.com/entry/2018/11/11/224441

他各サービス等

https://www.fluentd.org/
https://github.com/NLog/NLog
https://www.mongodb.com/