Blend day's Note

思い立ったことをメモする

Datadog で 録画鯖 を監視した話

監視はZabbixとオリジナルで十分でしたが…

あと、ログ監視が思っていたことと違ったので、そのあたりをまとめようと思った次第。

ことのはじまり

Datadogというサービスを耳にする機会があり、それが思いの外面白そうという話を 盗み聞きしたので、私も流行に乗ってやってみようかと。

今回のゴール

  1. Datadog で Apache を監視
  2. Apacheのログを読み取り、異常系(4xx,5xx)のステータスコードがあった場合、Eventとして通知。

対象は、ログ監視をしたいしたいと思っていた録画鯖*1にしました。

Datadog の初期設定

ここはほとんど詰まることが無かったので簡単に。

参考サイト↓

docs.datadoghq.com

blog.a-know.me

1. Datadog にアカウントを作る

公式ページからFree Trialを選択して始めていきます。

www.datadoghq.com

チュートリアルに従ってアカウントを作っていきます。 英語だらけですが、英語に弱い私でもできたので大丈夫です。

2. datadog-agent のインストール

チュートリアルの最後に、agentのインストールを促されます。 入れたいOSを選んで、出てくるワンライナーコードをコピペします。

f:id:kayo_tozaki:20171029143740p:plain

このコードを、監視したいサーバにて実行します。

この時、管理者権限 が必要になりますので注意です(yum install等を実行するため)

インストール後、datadog-agent が実行されると、このチュートリアルの右下"Finish"が有効となり、次に進めます。

Apache を監視する

1. Integration を有効化する

右側のメニューから、「Integrations」を探して、メニューを開きます。

f:id:kayo_tozaki:20171029144255p:plain

後は、Apacheを選択して、Configurationタブの中にある「Install Integration」を選択してインストールします。

f:id:kayo_tozaki:20171029144433p:plain

2. Apache の設定をする

datadog-agent は、Apacheの情報を取得するために、"mod_status"で出力されるデータをhttp経由で取得するようです。 その受付の準備をしておきます。

デフォルトのApacheを想定して以下記述しますが、やり方は山ほどあるはずなので、 やりやすいようにお願いします。


まずは、/etc/httpd/conf/httpd.conf にて、mod_status が読み込まれていることを確認します。

# 読込確認
$ cat /etc/httpd/conf/httpd.conf | grep mod_status.so
LoadModule status_module modules/mod_status.so

次に、/server-statusにて、mod_status で表示されるserver-statusの情報を表示するように設定を追加*2します。

# vim  /etc/httpd/conf.d/httpd-info.conf 

(以下を記述し保存)

ExtendedStatus On
<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from localhost
</Location>

この時、ExtenedStatus を有効化(On) にすることを忘れないようにします。 datadog-agent で必要とのこと。

docs.datadoghq.com

後は、セキュリティ的なことを考えて、localhostからのアクセスのみ許可しています。

ちなみに、Apache 2.4系の場合は記述方法が異なるので注意。*3

# vim  /etc/httpd/conf.d/httpd-info.conf 

(以下を記述し保存)

ExtendedStatus On
<Location /server-status>
    SetHandler server-status
    Require all denied
    Require local
</Location>

設定後、通常通りApacheを再起動し、データが取れることを確認します。

3. datadog-agent の設定

datadog-agent 側の integration 向け設定ファイルは、/etc/dd-agent/conf.d/ 以下に転がっています。 この中から、必要な.yaml.sampleファイルを .yamlにリネーム等して、有効化します。

Apacheの場合、ほとんど変える必要はないですが、2 にて server-status の位置を変えた場合は、 - apache_status_url: を変更する必要があります。

##設定ファイルの設置

# cp /etc/dd-agent/conf.d/apache.yaml.sample /etc/dd-agent/conf.d/apache.yaml

# cat /etc/dd-agent/conf.d/apache.yaml
init_config:

instances:
  - apache_status_url: http://localhost/server-status?auto
    # apache_user: example_user
    # apache_password: example_password
    # tags:
    #   - optional_tag

    # The (optional) disable_ssl_validation will instruct the check
    # to skip the validation of the SSL certificate of the URL being tested.
    # Defaults to false, set to true if you want to disable SSL certificate validation.
    #
    # disable_ssl_validation: false

    # The (optional) connect_timeout will override the default value, and fail
    # the check if the time to establish the (TCP) connection exceeds the
    # connect_timeout value (in seconds)
    # connect_timeout: 5
    
    # The (optional) receive_timeout will override the default value, and fail
    # the check if the time to receive the server status from the Apache server
    # exceeds the receive_timeout value (in seconds)
    # receive_timeout: 15

設定完了後、datadog-agent を再起動し、agentからデータが送信されることを確認します。

##datadog-agent 再起動&ロード確認

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


# service datadog-agent info
====================
Collector (v 5.18.1)
====================

(中略)

  Checks
  ======
  
    apache (5.18.1)
    ---------------
      - instance #0 [OK]
      - Collected 6 metrics, 0 events & 1 service check
  
(中略)

4. Dashboad の追加

最後に、Dashboadを追加。

"Dashboard List" を開き、右側のリストから「Apache」を選択(おそらく出ているはず)

f:id:kayo_tozaki:20171029151118p:plain

すると、きれいなグラフが出ているはずです。 どんなグラフかは、入れてからのお楽しみということで。

Apache のログ監視

今回のメインでわりと詰んだ部分。 結論的には、良く読んで理解してからやれってことでした。

1. Datadog のログ監視の仕様

Datadogのデフォルトで読み取れるログ形式がどうも決まっている様子です。(ちゃんとドキュメントを読んでない証拠)

docs.datadoghq.com

で、Apacheのログ形式は、このログ形式から外れているので、扱いはカスタムログとなります。 つまり、

カスタムログ = 自分でパーサを書く

コーディングが苦手な私には、非常に辛いです…が、世の中の先人方が、 Apacheログ用のパーサを既に書いてくださっていました。とても便利。

今回はコレを丸パクリしようと思いました…動かなかったですが。

2. datadog-agent でのログ監視設定

コレは簡単です。

/etc/dd-agent/datadog.conf に、下記設定を追記するだけです。

# vim /etc/dd-agent/datadog.conf


(追記)

dogstreams: /var/log/httpd/access_log:/etc/dd-agent/apachelog.py:apache_log_parser

この段階で、acccess_log が dd-agent ユーザ(ないしグループ)で見れるように調整することをおすすめします。

3. Apacheログパーサの追加

先人の知恵を大いに拝借しつつ、チョット改変しましたのが下記スクリプト*4になります。

inokara.hateblo.jp

これ↓を、/etc/dd-agent/apachelog.py として保存します。

from time import strftime
import re
import time

def apache_log_parser(log, line):
    # regex = '([(d.)]+) - - [(.*?)] "(.*?)" (d+) (.*?) "(.*?)" "(.*?)"'
    regex = '(.*?) - - \[(.*?)\] "(.*?)" (\d+) (\d+) "(.*?)" "(.*?)"'
    # localhost - - [28/Oct/2017:14:35:17 +0900] "GET /server-status?auto HTTP/1.1" 200 434 "-" "Datadog Agent/5.18.1"
    parsed = list(re.match(regex, line).groups())
    # print parsed

    event = {}
    event["aggregation_key"]  = "****.apache.log-monitor"
    event["timestamp"] = int(time.time())
    event["msg_title"] = "usamin Apache log monitor / Got status code: " + parsed[3]
    event["msg_text"] = "From: " + parsed[0] + " / " + "User-Agent: " + parsed[6]

    if re.match('^5\d\d$', parsed[3]):
        event["alert_type"] = "error"
        event["event_type"] = "apache.error"
        return [event]
    elif re.match('^4\d\d$', parsed[3]):
        event["alert_type"] = "warning"
        event["event_type"] = "apache.warning"
        return [event]
    else:
        event["alert_type"] = "info"
        event["event_type"] = "apache.info"

    #print (event)

#logs = 'localhost - - [28/Oct/2017:14:35:17 +0900] "GET /server-status?auto HTTP/1.1" 200 434 "-" "Datadog Agent/5.18.1"'
#print (logs)
#apache_log_parser(logs, 1)

パーサで詰んだ部分を簡単に解説

大きくわけて2点あります。

Ⅰ) 正規表現が上手く動かない

ログが正規表現に上手くマッチしなくて困りました。

ソースコード内にもログ形式は乗せてあるのですが、今回パースしたいログは、下記の形式になっています

localhost - - [28/Oct/2017:14:35:17 +0900] "GET /server-status?auto HTTP/1.1" 200 434 "-" "Datadog Agent/5.18.1"

これを、正規表現で読ませるには、次のような形式なります。

'(.*?) - - \[(.*?)\] "(.*?)" (\d+) (\d+) "(.*?)" "(.*?)"'

これの確認は、正規表現確認ツールという素晴らしいものがあったので、 Pythonのドキュメントとにらめっこしながら、正規表現を組みました。案外大変でした。

http://www.rexv.org/

6.2. re — 正規表現操作 — Python 3.6.3 ドキュメント

ちなみに、ステータスコード正規表現もオリジナルと書き換えてます。

Ⅱ)Eventが溢れかえる

デバッグ時ならば、ログが出てくることでとても喜ばしいのですが、 いざ実際に監視しようと思うと、必要外の情報はいらないわけで…

f:id:kayo_tozaki:20171029155054p:plain

簡単に言うと、return [event]の記述を、エラーコードのときのみに引っ掛けてます。 それ以外の情報はいらないという判断です。

f:id:kayo_tozaki:20171029155249p:plain

コレが理想の形です。

4. datadog-agentの再起動と確認

パーサーの設置まで終わると、最後にagentの再起動をすればおkです。

再起動後、/var/log/datadog/collector.log を眺めて、エラーなくコレクティングできてることを確認します。

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

# tail /var/log/datadog/collector.log 
(略)
2017-10-29 15:28:27 JST | INFO | dd.collector | checks.collector(collector.py:531) | Finished run #80. Collection time: 5.09s. Emit time: 0.03s
(略)

後は、DatadogのEventを眺めながら、404を叩いてみると、warningとして上がってくると思います。

f:id:kayo_tozaki:20171029155249p:plain

ここまででやりたいことは終わりです。


まとめ

リッチなグラフを眺めながら、リソースの使用率を知ることができ、 更にはアラートも流すことができ…と、好印象。

ただ、私がやりたかったこととはずれてたので、 また別ツールを触らないといけないことが分かりました…

次はEKLですかね…?

今回は、自分の読解力のなさを露呈しつつ、パーサ内の正規表現及びEventへの上げ方をまとめました。 誰かのお役に立てば良いなと。

それではまた


おまけ

ブログのUIを少しいじりました。

横幅のカスタマイズ

プレビューするときでも見にくいので、ここは改善。

wannabe-jellyfish.hatenablog.com

ソースコード表示

気にはなっていたが、やっぱり嫌だった。 調べたら、とても良い先人がいらっしゃったので、ありがたく利用させていただきます。

mmorley.hatenablog.com

*1:不正アクセス怖い

*2:Apache 2.2.15 にて動作確認済み

*3:動作未検証

*4:Python 3.5.2 で動作確認済み