LoginSignup
26

More than 5 years have passed since last update.

Datadog ログ監視でログ本文を通知

Last updated at Posted at 2016-02-22

某abbix等だとログ本文を一覧で表示できたりしますが、
Datadogでは解析した物を使用する前提のようで、
本文を送る機能は用意されていません。

syslog(/var/log/messages)を対象に、
Datadogで任意の文字列に合致したログ本文を通知する設定を行いました。

事前準備

環境

CentOS 6.7

DatadogAgent インストール

Datadogのメニューから辿ると、各OS(distribution)用のインストールコマンドが用意されていますので、そちらに沿って対象サーバにインストールします。

  • [Integrations] -> [Agent] -> [CentOS/RedHat]

pyparsing インストール

ログをパースするのに必要になるのでpipでインストールします。

注意点としてDatadogAgentは独自でpythonを持っており、
OSにインストールされているpythonに対してインストールしてもDatadogAgent内の処理では使用されません。
尚、pipは古いバージョンだったのでアップグレードしました。

/opt/datadog-agent/embedded/bin/pip install -U pip pyparsing
# /opt/datadog-agent/embedded/bin/pip --version
pip 8.0.2 from /opt/datadog-agent/embedded/lib/python2.7/site-packages (python 2.7)

標準でインストールされていた python 2.6

/usr/bin/python 用のpipでインストールしてもDatadogAgent(collector)からは使用できません。

# which python
/usr/bin/python
# python --version
Python 2.6.6
# which pip
/usr/bin/pip
# pip --version
pip 8.0.2 from /usr/lib/python2.6/site-packages (python 2.6)

DatadogAgent(collector)用の Python 2.7

daemonの設定ファイルを見ると、ログ解析を行うcollectorが使用するpythonのパスが記載されています。
同ディレクトリにpipも存在するので、こちらを使用します。

# cat /etc/dd-agent/supervisor.conf
・・・略・・・
[program:collector]
command=/opt/datadog-agent/embedded/bin/python /opt/datadog-agent/agent/agent.py foreground --use-local-forwarder
・・・略・・・
# /opt/datadog-agent/embedded/bin/python --version
Python 2.7.10
# /opt/datadog-agent/embedded/bin/pip --version
/opt/datadog-agent/embedded/bin/pip --version
pip 6.1.1 from /opt/datadog-agent/embedded/lib/python2.7/site-packages/pip-6.1.1-py2.7.egg (python 2.7)

対象ファイルのパーミッション

今回の監視対象ログはsyslogであるため、root以外に権限がありません。
監視するためには読込権限が必要になるため、dd-agentユーザに付与します。(dd-agentをrootグループに所属させ、ファイルにはグループの読込権限のみ付与しています。)

# usermod -g dd-agent -G root dd-agent
# chmod 640 /var/log/messages
# usermod -g dd-agent -G root dd-agent
# chmod 640 /var/log/messages
# logrotate設定にも追加
# vi /etc/logrotate.d/syslog
・・・略・・・
create 0640 root root
・・・略・・・

カスタムログパーサ

CentOSのsyslog(messages)を例にパーサを作成します。
公式ドキュメントと先輩様のスクリプトの参考(拝借)です。

  • syslog-parser.py
from pyparsing import Word, alphas, Suppress, Combine, nums, string, Optional, Regex
from time import strftime
import os.path
import time

def payload_event(line, log_array, alert_type):
  payload = {}
  payload["alert_type"] = alert_type
  payload["event_type"] = "syslog.error"
  payload["aggregation_key"]  = log_array[3]
  payload["host"]  = log_array[3]
  payload["msg_title"] = log_array[4]
  payload["msg_text"] = os.path.basename(__file__) + ' : ' + line
  return payload

def syslog_parser(log, line):
  # ignore case (specified in lower case)
  if ' error ' in line.lower():
    alert_type = 'error'
  elif ' warning ' in line.lower():
    alert_type = 'warning'
  else:
    return
  # case sensitive
  #if ' error ' in line:
  #  alert_type = 'error'
  #elif ' warning ' in line:
  #  alert_type = 'warning'
  #else:
  #  return

  ints = Word(nums)
  month = Word(string.uppercase, string.lowercase, exact=3)
  day   = ints
  hour  = Combine(ints + ":" + ints + ":" + ints)
  timestamp = month + day + hour
  hostname = Word(alphas + nums + "_" + "-" + ".")
  appname = Word(alphas + "/" + "-" + "_" + ".") + Optional(Suppress("[") + ints + Suppress("]")) + Suppress(":")
  message = Regex(".*")

  pattern = timestamp + hostname + appname + message
  parsed = pattern.parseString(line)
  event = payload_event(line, parsed, alert_type)
  return [event]

def test():
  # Set up the test logger
  import sys
  import logging
  logging.basicConfig(level=logging.DEBUG)

  param = sys.argv
  if (len(param) != 2):
    print 'Usage: python %s "TestMessage"' %param[0]
    quit()

  # Call the parse function
  actual = syslog_parser(logging, param[1])

  # Validate the results
  print 'Input:'
  print param[1]
  print 'Output:'
  print actual

if __name__ == '__main__':
  # For local testing, callable as "python /path/to/syslog-parser.py"
  test()

各関数説明

payload_event

ログ本文からDatadogのイベントフィールドを生成します。

この例では message_text はログ全文と検索用にスクリプト名を設定しています。

syslog_parser

先頭のif文で error|warning の振り分けを行います。

マッチしない行に対しては何も処理しません。(ログ全行を送るのは避けています。)

test

テスト関数です。コマンドラインからのテストを実行します。

引数でログメッセージを渡す事で、渡した文字列とパース後の文字列を出力します。

テスト実行例

# python parser.py "テスト文字列"
/opt/datadog-agent/embedded/bin/python /opt/datadog-agent/agent/checks/libs/syslog-parser.py "`date +'%b %d %H:%M:%S'` `uname -n` dd.collector[9999]: WARNING (disk.py:74): Using \`use_mount\` in datadog.conf has been deprecated in favor of \`use_mount\` in disk.yaml"
# 出力例
Input:
Feb 22 04:00:03 demo-clpami6 dd.collector[9999]: WARNING (disk.py:74): Using `use_mount` in datadog.conf has been deprecated in favor of `use_mount` in disk.yaml
Output:
[{'alert_type': 'warning', 'event_type': 'syslog.error', 'msg_title': 'dd.collector', 'host': 'demo-clpami6', 'msg_text': 'Feb 22 04:00:03 demo-clpami6 dd.collector[9999]: WARNING (disk.py:74): Using `use_mount` in datadog.conf has been deprecated in favor of `use_mount` in disk.yaml', 'aggregation_key': 'demo-clpami6'}]

格納場所と設定ファイル

datadog.conf に監視対象のログとパーススクリプトを指定します。

# vi /etc/dd-agent/datadog.conf
・・・略・・・
dogstreams: /var/log/messages:syslog-parser:syslog_parser
・・・略・・・

DatadogAgentの PYTHONPATH 配下であればパスの記述を省略できます。

PYTHONPATH はdaemonの設定ファイルに記載されています。(ここでもcollectorが対象です)

# cat /etc/dd-agent/supervisor.conf
・・・略・・・
[program:collector]
・・・略・・・
environment=PYTHONPATH='/opt/datadog-agent/agent:/opt/datadog-agent/agent/checks/libs:$PYTHONPATH'
・・・略・・・

今回は PYTHONPATH であるlibs配下に格納しています。

/opt/datadog-agent/agent/checks/libs/syslog-parser.py

有効化と確認

スクリプトの配置、設定ファイルへの追加、読込権限付与等、
準備が整った所でDatadogAgentを再起動して反映します。

# service datadog-agent restart
Stopping Datadog Agent (using killproc on supervisord):    [  OK  ]
Starting Datadog Agent (using supervisord):                [  OK  ]

/var/log/datadog/collector.log に以下のようなログが出力されていれば成功です。

yyyy-mm-dd hh:mm:dd JST | INFO | dd.collector | checks.collector(datadog.py:151) | dogstream: parsing /var/log/messages with <function syslog_parser at 0xXXXXXXXXXX> (requested syslog-parser:syslog_parser)

Datadog上での確認

参照

[Events] で参照できます。

Datadog_LogMonitoring_01.png

通知設定

[Monitors] -> [New Monitor] から通知設定を行います。

今回はSlackのチャンネルへ通知します。

Datadog_LogMonitoring_02.png

通知テスト

適当にログ出力を行い、Monitor設定で正しく通知されるかを確認します。

# logger -t TEST "`date +'%b %d %H:%M:%S'` `uname -n` dd.collector[9999]: warning LogParseTest"

通知メッセージにログ本文が含まれています。

Datadog_LogMonitoring_03.png

今後の課題

試行回数が少ないのですが、連続して出力があった場合に通知が飛ばない事があるようです。
Monitorの設定で最短(1分)にした場合にどの程度軽減できるか等確認が必要と思います。

Datadog_LogMonitoring_04.png

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26