scrapy-doで実行するジョブからnewrelicのカスタムイベントを投げる

scrapy-doでスクレイピングのジョブが無事実行されたか、をnewrelicで監視するため、カスタムイベントを使ってみました。以前はPythonでは直接エンドポイントにカスタムイベントを投げる方法でしたが、現在は専用のエージェントを使えるようになっているようです。

インストール方法を調べると、こちらに手順が掲載されていました。Non-webの方の手順を試しましたが、うまくいかなかったので、Copilotとやり取りしながら色々試してようやくカスタムイベントを送る方法を見つけました。scrapy-doはジョブをワーカープロセスで実行するため、特殊な方法が必要となりました。実際に行った手順は以下の通り。scrapy-doはインストール済みである前提です。

まずnewrelicパッケージをインストール。

pip install newrelic

設定ファイルを作成(NRC_API_KEYはingest-license keyタイプのライセンスキーをセットした環境変数)

newrelic-admin generate-config $NRC_API_KEY /etc/newrelic.ini

ジョブ実行開始前にエージェントを初期化するため、以下の内容のファイル(/tmp/newrelic_init.py)を作成。ちなみに最後の行はCopilotによるとイベントを送れる状態になるまでブロックするために必要、とのこと。

import newrelic.agent
newrelic.agent.initialize("/etc/newrelic.ini")
newrelic.agent.register_application(timeout=10.0)

このファイルを使ってScrapyのワーカースクリプト(scrapy-doから起動される)を書き換えます。

sed -i '1r /tmp/newrelic_init.py' /usr/local/bin/scrapy

ScrapyのプロジェクトのPipelineクラスに以下のメソッドを追加します。

    @newrelic.agent.background_task(application=newrelic.agent.application())
    def notify_newrelic(self, content):
        try:
            newrelic.agent.record_custom_event("Scrapy", content)
        except Exception as e:
            print(f"[NewRelic通知エラー] {type(e).__name__}: {e}")

このメソッドを使ってclose_spiderで結果をカスタムイベントとして送ります。

    def close_spider(self, spider):
        try:
            stats = spider.crawler.stats.get_stats()
            content = {
                "name": "blog",
                "result": "success",
            }
        except:
            content = {
                "name": "blog",
                "result": "error",
            }
        self.notify_newrelic(content)

送ったカスタムイベントはNew Relicのアラートで利用できます。例えば、以下のようなクエリによりスクレイピングに失敗した件数が得られるので、これをAlert Conditionsに使えばスクレイピングの成否を監視できると思います。

SELECT filter(count(*), WHERE result = 'error') OR 0 AS Success FROM Scrapy WHERE name IN ('blog')

Copied title and URL