ELK Stackでシステム監視 FilebeatでRaspberry Pi Zero WのVolumio楽曲再生ランキング

$ ssh volumio@192.168.2.117
volumio@192.168.2.117's password: 
                       ___                                      
                      /\_ \                        __           
         __  __    ___\//\ \    __  __    ___ ___ /\_\    ___   
        /\ \/\ \  / __`\\ \ \  /\ \/\ \ /' __` __`\/\ \  / __`\ 
        \ \ \_/ |/\ \L\ \\_\ \_\ \ \_\ \/\ \/\ \/\ \ \ \/\ \L\ \
         \ \___/ \ \____//\____\\ \____/\ \_\ \_\ \_\ \_\ \____/
          \/__/   \/___/ \/____/ \/___/  \/_/\/_/\/_/\/_/\/___/ 


        
             Free Audiophile Linux Music Player - Version 2.0

          C 2015 Michelangelo Guarise - Volumio Team - Volumio.org
                               

Volumioの内部では一応ログを出力していてどのような操作がされたのかなどを記録している。今回はそのログから楽曲の再生(再生開始)レコードをFilebeatで抽出してLogstashに送信する。Logstashでは送られたメッセージデータを加工して使えるデータにしてからelasticsearchに渡す。最後にKibanaで可視化(ランキング表を作成)するということにした。

volumioのログを覗いてみる

/var/log/volumio.log
ネットラジオ再生直前から再生開始までのログの一部
---------------------------- MPD announces state update: player
2018-03-17T03:49:37.582Z - info: ControllerMpd::getState
2018-03-17T03:49:37.587Z - info: ControllerMpd::sendMpdCommand status
2018-03-17T03:49:37.592Z - info: parsing response...
2018-03-17T03:49:37.612Z - info: sending command...
2018-03-17T03:49:37.635Z - info: ControllerMpd::parseState
2018-03-17T03:49:37.641Z - info: ControllerMpd::sendMpdCommand playlistinfo
2018-03-17T03:49:37.652Z - info: sending command...
2018-03-17T03:49:37.665Z - info: parsing response...
2018-03-17T03:49:37.671Z - info: ControllerMpd::parseState
2018-03-17T03:49:37.676Z - info: ControllerMpd::sendMpdCommand playlistinfo
2018-03-17T03:49:37.681Z - info: sending command...
2018-03-17T03:49:37.690Z - info: parsing response...
2018-03-17T03:49:37.696Z - info: parsing response...
2018-03-17T03:49:37.706Z - info: ControllerMpd::parseTrackInfo
2018-03-17T03:49:37.714Z - info: ControllerMpd::parseTrackInfo
2018-03-17T03:49:37.722Z - info: ControllerMpd::pushState
2018-03-17T03:49:37.727Z - info: CoreCommandRouter::servicePushState
2018-03-17T03:49:37.748Z - info: CoreStateMachine::syncState
2018-03-17T03:49:37.752Z - info: CorePlayQueue::getTrack 0
2018-03-17T03:49:37.758Z - info: STATE SERVICE {"status":"play","position":0,"seek":490,"duration":0,"samplerate":"48 KHz","bitdepth":"24 bit","channels":2,"random":false,"updatedb":false,"repeat":false,"isStreaming":false,"title":"francemusiqueclassiqueplus-hifi.mp3","artist":null,"album":null,"uri":"http://direct.francemusique.fr/live/francemusiqueclassiqueplus-hifi.mp3","trackType":"mp3"}

下2つはメディアサーバーの楽曲を再生した際のログで不要行を除いたの。

再生開始時のレコード
2018-03-16T13:31:54.201Z - info: STATE SERVICE {"status":"play","position":0,"seek":557,"duration":251,"samplerate":"44.1 KHz","bitdepth":"16 bit","channels":2,"random":false,"updatedb":false,"repeat":false,"isStreaming":false,"title":"ロンリィ・ピーポー II","artist":"太田裕美","album":"太田裕美 BEST COLLECTION","uri":"http://192.168.2.128:32469/object/828f16cd63b069b696c4/file.flac","trackType":"flac"}

一時停止時のレコード
2018-03-16T13:35:24.015Z - info: STATE SERVICE {"status":"pause","position":0,"seek":210767,"duration":251,"samplerate":"44.1 KHz","bitdepth":"16 bit","channels":2,"random":false,"updatedb":false,"repeat":false,"isStreaming":false,"title":"ロンリィ・ピーポー II","artist":"太田裕美","album":"太田裕美 BEST COLLECTION","uri":"http://192.168.2.128:32469/object/828f16cd63b069b696c4/file.flac","trackType":"flac"}

眺めた感じでは info: STATE SERVICE を含む行だけ抽出すればよいのかしら。
何故か1回の再生操作で再生開始のレコードが2回連続で出力されることがある。その出方の法則がわからない。だからこれを記録しても正しい楽曲再生記録にはならないかも。(しかし、無視して進める)

Filebeatのビルドとインストール

前回のMetricbeatのビルドとインストール手順の「metricbeat」を「filebeat」に置き換えたら同様で出来る。

Filebeatの設定

/etc/filebeat.yml (新規作成または雛形からの変更)
filebeat.prospectors:
- type: log
  enabled: true
  paths:
    - /var/log/volumio.log
  fields:
    type: volumio
  include_lines: ['info:\sSTATE\sSERVICE']
#↑include_linesの行頭はenabled,paths,fieldsと揃える

filebeat.config.modules:
  path: ${path.config}/beats/file_*.yml    #今回は/etc/beatsには関連ファイル無し
  reload.enabled: false
  reload.period: 10s

output.logstash:
  hosts: ["192.168.2.24:5044"]             #Logstash 本番用ポート5044

logging.level: debug
logging.selectors: ["*"]
logging.to_syslog: false                   #syslogへの出力はOFF
logging.to_files: false                    #ログファイルへの出力はOFF
logging.files:
  path: /var/log
  name: filebeat.log                       #↑trueにすると/var/log/metricbeat.logにログ出力

Filebeatのサービス設定

/lib/systemd/system/filebeat.service (新規作成)
[Unit]
Description=filebeat
Documentation=https://www.elastic.co/guide/en/beats/filebeat/6.2/index.html
Wants=userwork-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/filebeat -path.home /var/db/beats/filebeat -path.config /etc
Restart=always

[Install]
WantedBy=multi-user.target

# systemctl enable filebeat   #サービス有効化
# service filebeat start      #サービス開始

これでLogstashに渡ったデータは下のようになる。(Logstashのfilter設定無しで)

{
    "@timestamp" => 2018-03-17T03:58:56.201Z,
        "offset" => 31949,
        "source" => "/var/log/volumio.log",
          "beat" => {
            "name" => "volumio",
        "hostname" => "volumio",
         "version" => "7.0.0-alpha1"
    },
    "prospector" => {
        "type" => "log"
    },
       "message" => "2018-03-17T03:58:52.126Z - info: STATE SERVICE {\"status\":\"play\",\"position\":0,\"seek\":557,\"duration\":251,\"samplerate\":\"44.1 KHz\",\"bitdepth\":\"16 bit\",\"channels\":2,\"random\":false,\"updatedb\":false,\"repeat\":false,\"isStreaming\":false,\"title\":\"雨の音が聞こえる\",\"artist\":\"太田裕美\",\"album\":\"BEST COLLECTION\",\"uri\":\"http://192.168.2.128:32469/object/0badacd7ea823bf2ed65/file.flac\",\"trackType\":\"flac\"}",
          "tags" => [
        [0] "beats_input_codec_plain_applied"
    ],
          "host" => "volumio",
        "fields" => {
        "type" => "volumio"
    },
         "input" => {
        "type" => "log"
    },
      "@version" => "1"
}

メッセージ(message)に含まれる情報をバラバラに分離してその中で欲しい項目だけelasticsearchに渡すことにする。

Logstashの設定

/usr/local/etc/logstash.conf
input {
    beats {
        port => 5044
    }
}

filter {

    if [fields][type] == "hoge" {
        #他のフィルタ処理   省略
    }

    #今回の記事用のフィルタ処理 ここから
    if [fields][type] == "volumio" {
        mutate {
            gsub => ["message", "[\"]", ""]   #←messageフィールドの二重引用符を削除
        }
        grok {
            patterns_dir => ["/usr/local/etc/logstash/patterns"]

            match => { "message" => [
                '%{YEAR}-%{MONTHNUM}-%{MONTHDAY}T%{TIME}Z - info: STATE SERVICE \{status:%{DATA:[volumio]status},position:%{DATA},seek:%{DATA},duration:%{DATA},samplerate:%{DATA:[volumio]samplerate},bitdepth:%{DATA:[volumio]bitdepth},channels:%{DATA:[volumio]channels},random:%{DATA},updatedb:%{DATA},repeat:%{DATA},isStreaming:%{DATA:[volumio]isStreaming},title:%{DATA:[volumio]title},artist:%{DATA:[volumio]artist},album:%{DATA:[volumio]album},uri:%{DATA:[volumio]uri},trackType:%{DATA:[volumio]trackType}\}',
                '%{YEAR}-%{MONTHNUM}-%{MONTHDAY}T%{TIME}Z - info: STATE SERVICE \{status:%{DATA:[volumio]status},position:%{DATA},seek:%{DATA},duration:%{DATA},samplerate:%{DATA:[volumio]samplerate},bitdepth:%{DATA:[volumio]bitdepth},channels:%{DATA:[volumio]channels},random:%{DATA},updatedb:%{DATA},repeat:%{DATA},isStreaming:%{DATA:[volumio]isStreaming},title:%{DATA:[volumio]title},artist:%{DATA:[volumio]artist},album:%{DATA:[volumio]album},uri:%{DATA:[volumio]uri}\}'
                ]
            }
            remove_field => ["message", "beat", "tags", "source"]
        }
    }
    #今回の記事用のフィルタ処理 ここまで
}

output {
    #stdout { codec => rubydebug }
    elasticsearch { hosts => [ "localhost:9200" ] }
}

メッセージ(message)は中の各項目名と各値がダブルクォーテーションで括られているが、数値やtrue, falseなどは括られない。ここまでは良いのだが、文字列が入る筈の欄がnullだったりするとlogstashのmatchではダブルクォーテーションの有無の不一致でも簡単にマッチしなくなってしまうので非常に扱いづらい。そこで、ダブルクォーテーションは除去してからmatchさせることにした。
初稿ではstatusがstopのときのmatch条件が抜けていた。Volumioのログでstatus:stopでは何故かtrackTypeだけ出力しないのでtrackType入りのmatch条件では不適合になる。

Logstashの出力例

Volumio Selectionに入っているネットラジオ France Musique Classique Plusを再生してみた。

{
          "host" => "volumio",
        "fields" => {
        "type" => "volumio"
    },
        "offset" => 494960,
       "volumio" => {
             "artist" => "null",
          "trackType" => "mp3",
        "isStreaming" => "false",
             "status" => "play",
         "samplerate" => "48 KHz",
           "channels" => "2",
           "bitdepth" => "24 bit",
              "title" => "francemusiqueclassiqueplus-hifi.mp3",
              "album" => "null",
                "uri" => "http://direct.francemusique.fr/live/francemusiqueclassiqueplus-hifi.mp3"
    },
         "input" => {
        "type" => "log"
    },
    "prospector" => {
        "type" => "log"
    },
      "@version" => "1",
    "@timestamp" => 2018-03-17T09:19:52.729Z
}

アーティストがnullなのは解るとしてisStreamingがfalseってネットラジオはストリーミングじゃないのかしら?(改めて見たらアレっ?)

メディアサーバーから楽曲再生してみた。

{
          "host" => "volumio",
        "fields" => {
        "type" => "volumio"
    },
        "offset" => 487961,
       "volumio" => {
             "artist" => "太田裕美",
          "trackType" => "flac",
        "isStreaming" => "false",
             "status" => "play",
         "samplerate" => "44.1 KHz",
           "channels" => "2",
           "bitdepth" => "16 bit",
              "title" => "雨の音が聞こえる",
              "album" => "太田裕美 BEST COLLECTION",
                "uri" => "http://192.168.2.128:32469/object/0badacd7ea823bf2ed65/file.flac"
    },
         "input" => {
        "type" => "log"
    },
    "prospector" => {
        "type" => "log"
    },
      "@version" => "1",
    "@timestamp" => 2018-03-17T09:19:52.685Z
}

Kibanaで楽曲再生ランキング表作成

新しいフィールドが増えているがインデックスを更新しないとそれが反映されない。Kibanaの左列メニューの (Management)からIndex Patternsを選択し、右上の (Refresh)を押す。

FilebeatでVolumioの楽曲再生ランキング作成 1
Discover(Search)で確認する。とりあえず、hostでvolumioのホスト、fields.typeでvolumioという2つの条件で絞ってみた。
保存する必要はない。

FilebeatでVolumioの楽曲再生ランキング作成 2
左列でVisualizeを選択。 (新規作成)をクリック。
Data Tableを選択する。From a New Search, Select Indexのlogstash-* (或いはvolumioのデータが入っている筈のインデックス)を選択。
左上の方にあるAdd a filterで絞り込条件を追加する。

[host] [is][volumioのホスト名]
[volumio.status] [is] [play]

選択或いは入力して[Save]を押す。本当はさらに先にLogstashのFilterで分離したisStreamingでストリーミングの有無で絞り、2つのVisualizeを作成するつもりだったが、試した限りではisStreamingがtrueになることがないので絞っていない。
MetricsはMetric:Countにする。(初期値なので触らない)
今回はBucketsを3つ作成。3つともSplit Rowsにする。(好みで作れば良い)

1つめのSplit Rows:
Aggregation: Terms、 Fields: volumio.title.keword、 Order By: metric:Count

2つめのSplit Rows:
Aggregation: Terms、 Fields: volumio.artist.keword、 Order By: Terms

3つめのSplit Rows:
Aggregation: Terms、 Fields: volumio.album.keword、 Order By: Terms

任意の名称で保存する。

FilebeatでVolumioの楽曲再生ランキング作成 3
ダッシュボードに貼ったらこんな感じ。(左下の表)

関連記事:


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です