メインコンテンツへスキップ

ServiceNowの外部連携が届かないときどこを見る? ECC Queueに答えが無い理由


    外部システムとの連携が届かないとき、多くの担当者がまずecc_queueを開きます。ところが今回のPDIでは、ecc_queueは約1,260件が全てprocessed・outputで、詰まりも失敗もありませんでした。答えは別のテーブルにありました。ServiceNowから外部へのREST通信はsys_outbound_http_logに69,217件記録されており、桁が2つ違います。Zurich PDIで実際の画面を追って確認します。

    検証環境:Zurich PDI / OOTB / 2026-08-08 確認

    結論:見る場所は連携方式で決まる

    先に全体像です。

    • まず連携方式を決めます。MID Server経由か、ServiceNowから外部へのREST・SOAPか、外部からServiceNowへの受け側APIかで、見るテーブルがまったく違います。

    • ECC QueueはMID Server用の待ち行列です。今回の環境のようにMID Serverを使っていなければ、ここに何を探しに行っても見つかりません。

    • 外向きのREST通信はsys_outbound_http_logという別テーブルに出ます。ECC Queueの約1,260件に対して、こちらは69,217件でした。


    画像

    上の図が今回の切り分け方です。連携が届かないという相談を受けたとき、いきなりテーブルを開くのではなく、まず「どの方式の連携か」を決めるところから始めます。3つの矢印の先に、それぞれ別のテーブルが待っています。この環境ではMID Serverが0台なので、左のルートは最初から使われていません。残る答えは、真ん中か右のどちらかです。

    ECC Queueをstateで見ると、詰まりも失敗も無い

    まずは相談を受けたときに最初に開かれがちなecc_queueから見ます。stateでグループ化すると、状態の分布がひと目で分かります。


    画像

    グループはprocessedの1つだけでした。詰まりはゼロです。readyで止まっているレコードも、errorになっているレコードもありません。ECC Queueのstateは、メッセージが登録された直後はready、MID Serverが取りに来て処理するとprocessed、途中で失敗するとerrorに変わる仕組みです。readyのまま増え続けていればMID Server側の処理が追いついていないサインですし、errorが積み上がっていれば認証やスクリプトの失敗を疑う場面です。今回はそのどちらでもなく、既に処理を終えたレコードだけが並んでいました。

    ECC Queueをqueueで見ると、全部がoutput(外向き)

    もう一つ、queueという列でも見方が変わります。この列はメッセージの向きを表します。


    画像

    出てきたグループはoutputだけでした。inputに分類されたレコードは1件もありません。ECC Queueは本来、ServiceNowからMID Serverへ渡す指示(output)と、MID Serverから返ってくる結果(input)の両方を記録するテーブルです。今回はoutputしかないということは、指示を出す仕組みは動いているのに、それを受け取って処理を返すMID Server側が存在しないという状態を意味します。

    MID Serverは0台 — ecc_queueにinputが無い理由

    ここまでの2つの画面で、ECC Queueに詰まりが無いこと、そしてinputが無いことが分かりました。MID Serverは、ServiceNowのインスタンスと社内ネットワークの間に置かれる中継エージェントで、Discoveryのスキャン結果やオンプレミス機器との通信を橋渡しする役割を持ちます。ECC Queueへの記録は、このMID Serverが稼働していて初めて生まれる仕組みです。原因はMID Serverの登録数を見ると分かります。


    画像

    MID Serverの登録は0台でした。ECC Queueのinputは、MID Serverが処理結果を書き込むことで生まれる仕組みです。書き込む主体そのものが存在しなければ、inputが増えることはありません。Discoveryやオンプレミスのデータベース連携、社内ネットワーク内のエージェントレス接続など、MID Serverを介する連携方式は他にも複数あります。そうした方式を使っていない環境では、ECC Queueをどれだけ眺めても連携の状況は分かりません。この環境にMID Serverが無いのは事実ですが、MID Serverそのものが不要という意味ではありません。Discovery連携やオンプレミス接続を計画する場合は、別途MID Serverの導入が前提になります。MID Serverの追加はよくある作業の一つで、対象システムが増えるたびに台数を見直す運用が一般的です。

    外向きの通信はsys_outbound_http_logに出る

    ECC Queueが本命ではないと分かったところで、ServiceNowから外部への通信を記録しているテーブルを見ます。


    画像

    このテーブルには69,217件が記録されていました。列にはCreated・Sequence・URL hostname・Response status・Response timeが並びます。URL hostnameの列には宛先のホスト名が入りますが、この画面では実際の値の掲載を控えます。Response timeの値を見ると、4,000ミリ秒台の値が何度も繰り返し並んでいました。数秒おきに同じような時間で応答が返る通信が続いている様子から、定期的なジョブが同じ宛先へ繰り返しアクセスしていると読めます。ServiceNowから外部への通信は、REST MessageやScripted REST APIの呼び出しに限らず、こうしたバックグラウンド処理からも発生します。

    定義の数と通信の数が桁違いになる理由

    外向き通信の量が分かったところで、その通信の元になる定義も見ておきます。


    画像

    REST Messageの定義はわずか4件でした。Firebase Cloud Messaging向けが2件、モバイルアプリのプッシュ通知向けが1件、株価情報を取得するYahoo Finance向けが1件です。どれも標準機能に最初から用意されているサンプル的な定義で、自分で作った連携ではありません。定義4件に対して通信69,217件という差は、単純計算で1件の定義が平均1万7千回以上呼ばれていることになります。もっとも、外向き通信はREST Messageの定義を経由しない呼び出しも含むため、この平均値がそのまま実態を表すわけではありません。定義の数だけを見て「連携が少ない環境だ」と判断すると、実際に流れている通信量を見落とすことになります。

    受け側の定義はsys_ws_definition — 画面表記はScripted REST APIs

    ここまではServiceNowから外部への向きでした。逆に、外部からServiceNowを呼び出す側の定義も確認します。


    画像

    このテーブルの物理名はsys_ws_definitionですが、開いた画面のタイトルは「Scripted REST APIs」と表示されます。件数は246件でした。列にはName・API ID・Base API path・Active・Is versionedが並び、/api/now/から始まるパスが多く見えます。ここが外部システムから見た「入口」の一覧です。定義があるということは、その分だけ外部から呼び出せる窓口が用意されているということでもあります。1つの定義の中には複数のリソース(実際のエンドポイント)がぶら下がる作りになっており、リソース側の実体を数えると1,259件でした。246件の入口の奥に、さらに細かい窓口が控えている構造です。

    受信したRESTリクエストはTransaction Logで追える

    定義の数だけでは、実際にどれだけ呼び出されているかは分かりません。受信した通信そのものはTransaction Logに記録されます。


    画像

    type=RESTで絞り込むと、15,961件が記録されていました。Response timeの平均は177.83ミリ秒、最大は40,459ミリ秒です。ほとんどのリクエストは短時間で処理を終えていますが、一部に極端に時間のかかったものが混ざっていることが分かります。列にはOrigin Applicationも含まれており、GlobalやWhats New Framework Coreといったアプリケーションから内部的にAPIが呼ばれている様子も見て取れました。外部から届いたリクエストと、ServiceNow内部の別アプリからのAPI呼び出しは同じログに混在します。原因を絞り込むには、URLやOrigin Applicationでさらに条件を絞り込む作業が必要です。SQL countやSQL timeの列も並んでいるため、応答が遅いリクエストがDB処理側で時間を食っているのか、外部との通信待ちなのかを見分ける手がかりにもなります。


    画像

    ここまでの数字を一つの表にまとめました。6つのテーブルを並べて見ると、連携方式ごとに記録される場所と件数の差が一望できます。MID経由の約1,260件、外向きREST・SOAPの69,217件、受け側の15,961件は、それぞれ性質の異なる記録です。件数の大小だけを比べて「連携が多い・少ない」と判断するよりも、まず自分が調べたい通信がどの列にあたるのかを見極める材料として使うのが実務的な使い方です。

    実際に1回叩いてみると、記録はこう変わる

    ここまでは既存のログを読む話でした。ここからは実際に外向きの通信を1回発生させ、sys_outbound_http_logに記録が出る瞬間を確認します。

    Scripts - Backgroundで次のスクリプトを実行しました。GETリクエストを2回投げるだけの読み取り専用スクリプトで、レコードの作成・更新・削除は一切行いません。認証情報もリクエストボディも使いません。

    /* 外向きのHTTP通信を1回発生させ、sys_outbound_http_logに記録が出るかを確認する(読み取り専用)
       RESTMessageV2でGETを2回投げるだけ。認証情報・リクエストボディは一切使わない。
       PDIのレコードは作成・更新・削除しない(ログは通信の副産物として自動で増えるだけ) */
    
    function tryGet(label, url) {
        var req = new sn_ws.RESTMessageV2();
        req.setHttpMethod('GET');
        req.setEndpoint(url);
        req.setHttpTimeout(15000);
        var res = req.execute();
        var status = res.getStatusCode();
        var err = res.getErrorMessage();
        gs.print(label + ' -> status=' + status + (err ? ('  error=' + err) : ''));
    }
    
    gs.print('=== 1) GETを2回投げる ===');
    tryGet('成功する先 (www.servicenow.com)', 'https://www.servicenow.com/');
    tryGet('失敗する先 (存在しないホスト)', 'https://this-host-does-not-exist.invalid/');
    
    gs.print('');
    gs.print('=== 2) sys_outbound_http_log 直近5件(新しい順) ===');
    var gr = new GlideRecord('sys_outbound_http_log');
    gr.orderByDesc('sys_created_on');
    gr.setLimit(5);
    gr.query();
    while (gr.next()) {
        gs.print(gr.getValue('sys_created_on') + '  ' + gr.getValue('hostname') +
            '  status=' + gr.getValue('response_status') + '  ' + gr.getValue('response_time') + 'ms');
    }

    1つ目はhttps://www.servicenow.com/への単純なGET、2つ目はわざと存在しないホストhttps://this-host-does-not-exist.invalid/へのGETです。実行結果は次の画面です。


    画像

    成功した方はstatus=200で返ってきました。存在しないホストへのGETは、RESTResponseV2のgetStatusCode()が0を返し、getErrorMessage()にはUnknownHostExceptionというJavaの例外名がそのまま入っていました。DNSの名前解決そのものが失敗していることが、エラーメッセージから読み取れます。

    スクリプトの後半では、実行直後にsys_outbound_http_logを新しい順に5件読んでいます。実行結果に続けて、一覧画面でも同じ2件を確認します。


    画像

    一覧の一番上に、たった今実行した2件が並んでいます。その下に続く行が、この記事の前半で触れた「4,000ミリ秒台の値が何度も繰り返す」通信そのものです。スクリプトの出力で宛先ホスト名まで読むと、signaldc.service-now.comという名前が数秒おきにresponse_status=-1で記録され続けていました。用途までは今回の検証範囲外ですが、正体不明だった繰り返し通信の宛先が、実際に叩いて比較したことで具体的な名前として見えるようになりました。

    成功と失敗で記録の何が違うか

    成功と失敗を並べると、違いは3か所に出ます。

    • response_status … 成功は200。失敗は-1でした。スクリプト実行直後にgetStatusCode()で見た値は0でしたが、テーブルに保存された値は-1です。同じ失敗でも、APIの戻り値とログテーブルの値が一致しない場面があります。

    • getErrorMessage()の有無 … 成功時は空文字列。失敗時はUnknownHostExceptionを含む文字列が入ります。

    • response_time … 成功が874ミリ秒、失敗が123ミリ秒でした。名前解決の段階で失敗するため、実際に接続を待つ成功時より短時間で記録が終わっています。

    ここから読者が持ち帰れること

    「連携が届かない」と言われたとき、既存のログをいくら眺めても手がかりが薄いことがあります。そんなときは、今回のような読み取り専用のGETを1回自分で叩いてみることが有効です。sys_outbound_http_logに記録が出るかどうかで、切り分けが一歩進みます。記録さえ出ていれば、通信そのものは発生している状態です。原因の候補からBusiness RuleやScript Includeの条件分岐を外し、宛先側やネットワーク経路に絞り込めます。逆に記録が1件も出なければ、リクエストを送る処理そのものに到達していないことになり、疑う場所は条件分岐やスクリプトの手前に移ります。

    実機で気づいたこと

    今回いちばん意外だったのは、ECC Queueをグループ化した瞬間に出てくるグループが、どちらの画面でも1つしか無かったことです。stateはprocessedのみ、queueはoutputのみ。複数の状態が入り混じっているだろうという予想は外れました。MID Serverを使っていない環境のECC Queueは、これほどきれいに1色に染まるものかと驚きました。

    もう一つ気づいたのは、sys_ws_definitionというテーブルを開いた先の画面タイトルが「Scripted REST APIs」だったことです。テーブル名だけを頼りに「Web Serviceの定義」だと思い込んでいましたが、実際に開いてみると受け側のREST API定義そのものでした。物理テーブル名と画面の呼び名が一致しないケースは他のテーブルでもよくあることですが、実機で開いて初めて気づく類いの差です。

    数字が撮影の途中で動いていたことにも気づきました。作業を始めた時点でecc_queueは1,259件でしたが、スクリーンショットを撮り直すころには1,260件に増えていました。PDIは操作していない間もバックグラウンドで動き続けていて、件数は常にその瞬間のスナップショットでしかありません。

    Outbound HTTP Logsの応答時間が4,000ミリ秒台で何度も揃っていたのも印象的でした。人が操作するたびに発生する通信であれば、応答時間はもっとばらつくはずです。一定の間隔で似たような時間の通信が繰り返される様子からは、スケジュールされたジョブが背後で動いている可能性を感じました。断定はできませんが、調査の初手として「これは人の操作由来か、定期ジョブ由来か」を疑う材料にはなります。

    Response statusの列も引っかかりました。画面に表示された直近10件は、いずれも-1という値でした。200や404のような一般的なHTTPステータスコードとは違う値で、何を意味するかはこの検証の範囲外です。ただ、正常なステータスコードが並んでいないパターンに気づけたこと自体は、次に同じ画面を開いたときの見方を変えてくれます。件数の多さだけでなく、Response statusの列にも目を通す価値があると感じました。

    実務では何に使えるか:連携の問い合わせを受けたときの確認順

    本番環境で「連携が届かない」という相談を受けたとき、自分なら次の順番で見ます。

    1. まず相手システムとの接続構成を確認し、MID Server経由か、直接RESTか、受け側APIかを決める

    2. MID経由ならecc_queueのstateを見る。readyで滞留していないか、errorが積み上がっていないかを確認する

    3. 外向きのREST・SOAPならsys_outbound_http_logを宛先や時間帯で絞り込み、通信自体が発生しているかを見る

    4. 外部からの受信ならsyslog_transactionをtype=RESTで絞り、Origin ApplicationやURLで対象のリクエストを特定する

    5. 通信の有無が分かった後で、初めてsys_rest_messageやsys_ws_definitionの定義側を確認する

    6. どのテーブルにも記録が無い場合は、ServiceNow側のログを追う工程を離れ、ネットワークやファイアウォールなど接続経路そのものを疑う段階に切り替える

    順番を逆にして定義から調べ始めると、この環境なら246件のScripted REST APIsを1件ずつ開く作業になりかねません。先に通信の記録を確認し、そもそも通信が発生しているかどうかを切り分けてから定義を見るほうが、遠回りをせずに済みます。1〜5のどの段階でも記録が一切見つからないなら、ServiceNow側のログを追う工程そのものが空振りに終わっている合図です。その場合はネットワーク担当者と合流し、経路上のプロキシやファイアウォールの設定を確認する段階に進むことになります。


    画像

    MID Serverの追加や設定変更は本番環境への影響が大きいため、変更の前後にはインシデントやチェンジの記録を残しておくと、あとから状況を追いやすくなります。

    関連記事

    よくある質問

    Q1. ECC Queueに何も無ければ、連携は問題無いと判断してよいですか

    判断できません。今回のようにMID Serverを使っていない環境では、ECC Queueに記録が残る対象そのものが無いだけです。連携方式がMID経由かどうかを先に確認し、違う方式なら別のテーブルを見る必要があります。

    Q2. sys_outbound_http_logに記録が無い場合、何を疑いますか

    REST Messageやスクリプトの実行そのものに到達していない可能性があります。Business RuleやScript Includeの条件分岐でリクエスト送信の手前で処理が止まっていないか、スクリプトのログやシステムログを確認する範囲になります。条件式の中で参照しているフィールドが空になっているだけで送信処理まで届かないケースもあるため、送信の直前まで処理が進んでいるかをログで確かめる作業が近道です。

    Q3. sys_ws_definitionとsys_rest_messageの違いは何ですか

    向きが逆です。sys_ws_definitionは外部からServiceNowを呼び出す受け側の定義で、画面上は「Scripted REST APIs」と表示されます。sys_rest_messageはServiceNowから外部を呼び出す送信側の定義です。名前だけを見ると似ているため、調査の途中で向きを取り違えないよう、まずどちらの向きの通信を探しているかを最初に確認しておくと迷いにくくなります。

    Q4. Transaction Logのtype=RESTには何が含まれますか

    外部からのリクエストだけでなく、ServiceNow内部の別アプリケーションからのAPI呼び出しも同じログに記録されます。発信元を区別するにはOrigin Applicationの列を使うのが基本です。特定の外部システムからの呼び出しだけを追いたい場合は、URLの列にAPI IDやパスの一部を含めて検索すると対象を絞り込みやすくなります。

    Q5. MID Serverが無い環境では、今後もECC Queueを見る必要は無いですか

    いいえ。Discoveryやオンプレミスのデータベース連携など、MID Serverを前提とする機能を導入した時点でECC Queueは再び意味を持ちます。今回の環境で使われていないというだけで、機能自体が不要という意味ではありません。導入を検討する段階になったら、まずecc_agentにMID Serverが登録されているかどうかを確認するところから始めることになります。

    まとめ

    外部連携が届かないという相談では、ECC Queueをまず開く担当者が多いはずです。しかし今回のPDIのように、MID Serverを使っていない環境ではECC Queueに答えはありません。ServiceNowから外部へのREST通信はsys_outbound_http_logに69,217件、外部からServiceNowへの受信はsyslog_transactionにtype=RESTで15,961件、それぞれ別のテーブルに記録されていました。件数だけを見ればECC Queueの約1,260件はむしろ少ないほうですが、少ないことと役に立たないことは別問題です。この環境ではたまたま連携方式が違ったというだけで、MID Serverを使う構成であれば同じECC Queueが最初に見るべき場所になります。

    連携が届かないと聞いたら、テーブルを開く前に「どの方式の連携か」を決めることが、遠回りを避ける最初の一歩です。見る場所さえ間違えなければ、原因の切り分けは数分で済みます。

    用語

    • ecc_queue … MID Serverとのメッセージをやり取りするキュー。queue列でoutput/input、state列でready/processing/processed/errorを管理する

    • ecc_agent … MID Serverの登録情報を持つテーブル

    • sys_outbound_http_log … ServiceNowから外部への全てのHTTP通信を記録するログテーブル

    • sys_rest_message … ServiceNowから外部を呼び出す送信側REST連携の定義

    • sys_ws_definition … 外部からServiceNowを呼び出す受け側API(Scripted REST APIs)の定義

    • syslog_transaction … ServiceNowが処理した全トランザクションのログ。type列で絞り込める

    自分の環境で確認するときのURL

    /ecc_queue_list.do?sysparm_query=GROUPBYstate
    /ecc_queue_list.do?sysparm_query=GROUPBYqueue
    /ecc_agent_list.do
    /sys_outbound_http_log_list.do?sysparm_query=ORDERBYDESCsys_created_on
    /sys_rest_message_list.do?sysparm_query=ORDERBYname
    /sys_ws_definition_list.do?sysparm_query=ORDERBYname
    /syslog_transaction_list.do?sysparm_query=type=REST^ORDERBYDESCsys_created_on

    参考リンク

    検証環境と未検証範囲

    件数・画面はZurich PDI(OOTB)で確認したものです。本番環境やカスタマイズ済みの環境では数値が異なります。

    実際に連携を失敗させて再現する操作は行っておらず、既存ログの集計のみを確認しています。sys_outbound_http_logの宛先ごとの内訳、MID Serverを導入した場合のecc_queueの挙動、認証エラーや証明書エラーが実際にどう記録されるかは、今回の検証範囲の外です。ecc_queueやsys_outbound_http_logの件数は常時変動するため、本文の数字は確認した時点のスナップショットとして読んでください。

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ