メインコンテンツへスキップ
見出し画像

ServiceNowのFlowは動いたのか? 実行ログで止まった場所をたどる


    Flow Designerで作ったフローが、動いた気配もなく反応も無い。そんなとき、何を疑えばよいのでしょうか。ServiceNowはフローを実行するたびにsys_flow_contextへ記録を残します。ここを見れば、動いたかどうかだけでなく、途中で止まっているならどのアクションで止まっているかまで追えます。Zurich PDIで実際に1件のレコードを更新してフローを発火させ、記録がどう残るかを確認しました。

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

    追いかける対象はこういう形をしている

    調査に入る前に、追う相手を見ておきます。OOTB の Change - Normal - Assess を Workflow Studio で開いた画面です。


    画像

    いちばん上が TRIGGER です。起動条件がそのまま1行の文で書かれています。

    Change Request Created or Updated where (Model is Normal, and State is Assess, and On hold is false)

    この条件に合うレコードが保存された瞬間だけ、下の ACTIONS が動きます。裏を返せば、条件に合わなければ何も起きず、記録も残りません。

    ACTIONS は番号付きで縦に並びます。1 が並列実行の宣言、2→3 が Apply Change Approval Policy。その結果が Skipped なら Update Change Request Record へ進みます。6 で Evaluate Change Model、Rejected なら Send Email。分岐と待機を含めて11ステップあります。

    自動化が動かないという相談は、この縦の並びのどこで止まったかを突き止める作業になります。画面では全部つながって見えますが、実行時にどこまで進んだかはここには出ません。それを記録しているのが sys_flow_context です。

    自動化が動かないとき、何が分からないのか

    Flow を作って有効にしたのに、期待した動きにならない。このとき困るのはどこまで進んだのかが見えないことです。

    知りたいのは3つです。そもそも起動したのか。起動したとしてどのステップまで進んだのか。そして止まったのはなぜか。

    コードなら例外が出ます。ノーコードで組んだ処理は、失敗しても画面上が静かなことがある。だから実行の記録を読む方法が要ります。

    Flow まわりのテーブルは役割で3層に分かれる

    継承元を見ると、テーブルの性格がきれいに3つに分かれていました。

    定義は sys_hub_flow(画面上は Flow)。Flow Base を継承しています。作った Flow そのもので、更新セットで運ぶ対象です。

    部品は sys_hub_action_instance(Action Instance)。Component を継承していて、Flow の中に置かれたアクション1つ分にあたります。sys_hub_trigger_instance(Trigger Instance)が起動条件を持ちます。

    実行記録は sys_flow_context(Flow engine context)と sys_flow_log(Flow engine log entry)。どちらも継承なしの基底テーブルでした。その環境で実際に動いた記録なので、移送する性質のものではありません。

    sys_flow_runtime_value(Flow Runtime Values)も基底で、実行時の値を保持します。

    定義は運べて、実行記録は運べない。 この分かれ方は、SLAの定義と実績、Import Set の設定と結果と同じ構造です。ServiceNow 全体で一貫した設計になっています。

    公式が書いている実行記録の項目

    sys_flow_context の項目に説明が付いていました。実行1回分のヘッダにあたるレコードです。

    design_source:

    The designer/builder that was the source of this execution

    この実行の出どころとなったデザイナー/ビルダー、という説明です。Flow Designer で作ったものか、他の仕組みから来たものかを区別できます。ノーコードの入口が複数あることを前提にした項目です。

    source_record は「The source script of this execution」。実行のもとになったものを指します。

    reporting:

    Turns ON/OFF the reporting during the flow execution

    実行中のレポーティングを入切する設定です。記録を細かく残すかどうかを、実行ごとに変えられることになります。ログが薄いときは、ここが切られている可能性を疑えます。

    定義側にも実行に効く項目がある

    sys_hub_flow.pre_compiled:

    System will attempt to compile flow without a need of a run of the flow.

    実行しなくてもコンパイルを試みるという設定です。初回実行時のコンパイル待ちを避けるための仕組みだと読めます。

    「1回目だけ遅い」という現象に関係する項目なので、性能の相談を受けたときに見る場所になります。

    Flow Designer は拡張の集まりでもある

    プラグインの一覧を見ると、Flow Designer が土台と拡張に分かれていることが分かります。

    Flow Designer Action Step - Service Catalog の説明は「Action Step - Service Catalog」。Flow Designer support for the Service Catalog は「This plugin adds support for flow designer in Service Catalog」でした。

    カタログ向けの部品が別プラグインで足されているという構造です。同様に Connect 向け、コレクター向けの拡張がありました。

    だから「このアクションが選択肢に出ない」という問い合わせは、対応するプラグインが入っていない可能性を先に疑うことになります。実行ログを読む前に確認する場所です。

    結論:止まっているかどうかは3つのテーブルで分かる

    • 実行そのものの記録はsys_flow_contextです。1回の実行につき1レコードで、stateが今どこにいるか(実行中・待機・完了・失敗など)を表します。

    • 止まっている場所を知りたいなら、まずstateを見ます。 COMPLETEなら正常終了、WAITINGなら承認や条件待ちで一時停止、ERRORなら失敗です。エラーの文言はsys_flow_log、各アクションの入出力はsys_flow_runtime_valueという別テーブルに分かれています。

    • 実際に既存のChange Requestを1件更新してフローを発火させたところ、記録は1件では終わりませんでした。 狙ったフローとは別に、もう1つのフローが別経路で動いていました。詳しくは後述します。


    画像

    実行1件ごとの記録はsys_flow_contextに残る

    フローが1回実行されるたびに、sys_flow_contextへ1レコードが作られます。フィールドは34あり、そのうち押さえておきたいのは次の5つです。

    • flow … 実行されたフローの名前

    • state … 今どこにいるか

    • source_table … 何がきっかけで動いたか(トリガとなったレコードのテーブル名)

    • source_record … 具体的にどのレコードが引き金になったか(トリガとなったレコードのsys_id)

    • run_time … 実行にかかった時間(ミリ秒)

    このほかexecution_idという実行を一意に識別するIDや、実行元のアプリケーションを示すapplicationもありますが、日常の調査で最初に見るのは上の5つで十分です。

    stateの選択肢は10個ありました。日常的に目にするのはWAITING(待機)・COMPLETE(完了)・ERROR(失敗)・CANCELLED(キャンセル)・IN_PROGRESS(実行中)の5つです。残りはQUEUED・CONTINUE_SYNC・PRESUMED_INTERRUPTED・PAUSED・PAUSED_IN_DEBUGで、デバッグや内部制御向けの値が並びます。

    source_tableとsource_recordが特に便利です。トリガとなったレコードが分かっていれば、この2つで一覧を絞り込むだけで、無数の実行の中から目的の1件だけを取り出せます。


    画像

    トリガとなったレコードさえ分かれば、実行が数千件あっても迷わず1件にたどり着けます。逆に言えば、source_tableとsource_recordが分からないうちは、新しい順に並べて目視で探すしかありません。

    実行の中身はsys_flow_runtime_value、エラーの文言はsys_flow_log

    sys_flow_contextが「1回の実行」の記録だとすると、その中身を1段階細かく見るテーブルが2つあります。


    画像

    sys_flow_runtime_valueは、各アクションに渡された入力値と、そこから返ってきた出力値をcontextごとに保持する場所です。「このアクションで何が渡っていたか」を追いたいときに開きます。sys_flow_logは、アクション内のスクリプトが出したログをレベル付きで記録するテーブルです。エラーの具体的な文言を探すならここです。

    どちらもcontext列でsys_flow_contextとつながっているので、実行1件を起点に「入出力を見るならruntime_value、エラー文を見るならlog」と使い分けます。

    トリガの対象テーブルはtrigger_instanceには無い

    フローがどのテーブルを監視しているかを調べようとして、sys_hub_trigger_instanceを開くと、思ったものが見つかりません。このテーブルの実フィールドは18個ありますが、「table」という名前のフィールドは存在しないのです。

    実際の対象テーブルと条件式は、sys_variable_valueという別テーブルに、トリガのレコードを指す形で1行ずつ格納されています。列のラベルはTable・Condition・Run Triggerで、値を追っていくとようやく監視対象のテーブル名にたどり着きます。

    読み取り専用のAPIだけでこれを追うのは遠回りです。実務では、Flow DesignerでフローのTriggerカードを開くほうが速く、しかも条件式まで人が読める形で表示されます。この記事の後半で、その画面を実際に見せます。

    実際に1回動かして、記録がどう出るかを見る

    ここからが本題です。既存のChange Requestを1件だけ更新して、Flow Designerで組まれたフローを実際に動かします。

    対象に選んだフロー

    対象は1つに絞りました。Normal Change(標準の変更管理プロセス)には、状態が進むたびに動くフローが複数あります。今回は、状態が「Assess(評価)」になったときに動くChange - Normal - Assessを対象にしました。トリガの対象テーブルはchange_request、条件は「Model が Normal、State が Assess、On hold が false」です。

    Normal Changeは、New(起票)から始まります。そこからAssess(評価)・Authorize(承認)・Scheduled(実施予定)・Implement(実施)・Review(振り返り)の順に状態が進みます。状態が切り替わるタイミングごとに専用のフローが割り当てられていて、Change - Normal - AssessはAssessの入口にあたる1本です。他の状態にも同じ作りでChange - Normal - Authorizeのようなフローが控えています。

    アクションの並びを事前に確認すると、次の7ステップでした。

    1. Apply Change Approval Policy(承認ポリシーを適用)

    2. Update Record(レコード更新)

    3. Evaluate Change Model(変更モデルの評価)

    4. Send Email(メール送信)

    5. Wait For Condition(条件が満たされるまで待機)

    6. Disregard Change Request Approvals(承認を無視する分岐)

    7. Evaluate Change Model(再評価)

    5番目に待機アクションがあります。承認が解決するまでここで止まる作りだと、動かす前から読み取れました。

    New状態のChangeをAssessへ更新する

    対象に選んだのは、状態が「New」のままだったChange Request 1件です。管理画面からstateをNew(-5)からAssess(-4)に変えるだけの操作ですが、実際にやってみると1回では通りませんでした。

    最初の更新は、Business Rule「Change Model: Check State Transition」に止められました。NewからAssessへの遷移自体は正規のルートですが、Assess段階に入るには担当グループ(assignment_group)が必要という作りだったためです。担当グループを追加して再実行すると、今度は別のBusiness Ruleが止めました。Assessに入ると自動生成される変更タスクの担当者が空のままで、担当グループのメンバーになっていなかったためです。担当グループと、そのグループに所属する担当者の両方を設定して、ようやく更新が通りました。

    このBusiness Ruleの連鎖は、フローの実行ログとは別の話です。フローが動く前の、レコード更新そのものの関門でした。同じ操作を自分のPDIで試す場合、担当グループと担当者を先に埋めておくと引っかかりません。

    更新した直後、実行コンテキストが2つ増えた

    更新が通った直後にsys_flow_contextを新しい順で開くと、同じ時刻に2件の実行が並んでいました。


    画像

    1つは狙いどおりのChange - Normal - Assessで、source_tableはchange_request、source_recordは今回更新したレコードでした。もう1つはChange - Conflict Detectionという別のフローで、source_tableはchg_mgt_workerという聞き慣れないテーブルです。1回のフィールド更新が、更新を直接検知したトリガと、それとは別に作られたワーカーレコードを起点にしたトリガの、2つの経路でフローを動かしていたことになります。

    このフローはどこで止まっているのか

    狙ったChange - Normal - Assessの実行コンテキストを開くと、stateはWaitingのままでした。関連リストの「Flow engine log entries」は空です。


    画像

    エラーは出ていません。ログも無い。事前に確認したアクションの並びを思い出すと、5番目にWait For Conditionがありました。実際にフローの画面を開くと、該当のアクションがそのまま見えます。

    このフォームには「Open in Operations View」というリンクも並んでいます。開くと、実行中のフローを俯瞰できる運用者向けの画面が別タブで立ち上がる仕組みです。WAITINGのまま長時間残る実行を追いたいときは、フォームのstateだけでなくこちらも合わせて開くと、進み具合を掴みやすくなります。


    画像

    フローは例外で止まったのではなく、設計どおりにWait For Change Request Conditionで待っている最中でした。では何を待っているのか。対象のChange Requestを開くと、進捗バーのAssessが緑になり、「Change is waiting for approval」という帯が出ています。


    画像

    承認の一覧を、このChange Requestに絞り込んで開くと、2件が待っていました。


    画像

    2人の承認者、どちらもRequestedのままです。フローの5番目のアクションは、この2件の承認が解決する(承認または却下される)まで先に進みません。「動いた気配が無い」と感じたフローの正体はエラーではありませんでした。人の判断待ちで一時停止しているフローだった、ということになります。承認そのものはこの記事のための操作の対象外としたので、今回はここまでの記録にとどめます。

    失敗したフローはどう見えるか

    sys_flow_contextをstate=ERRORで絞り込むと、今回のPDIでは1件もヒットしませんでした。状態をグループ化して見ても、内訳はCancelled・Complete・Waitingの3つだけで、Errorのグループ自体が存在しません。Cancelledは5件あり、実行中に人がキャンセル操作をした場合や、対象レコードが削除された場合などに付く値です。今回発火させたChange - Normal - Assessの実行を開いても、error_stateとerror_messageはどちらも空でした。エラーの器は用意されていても、中身が無ければ空欄のままという当たり前の事実を、実際に自分の実行で確かめられたことになります。


    画像

    一方でsys_flow_logには、VA Telemetry Daily Rollupという毎日動くフローが、level=Errorのログを何日分も残していました。


    画像

    メッセージにはJavaScriptの構文エラーがそのまま出力されています。ところが、このログを出したフロー自体のsys_flow_contextを確認すると、stateはCOMPLETEでした。スクリプトの中で発生した例外がログに記録されるだけで、フロー全体を失敗として扱うとは限らない、ということです。「エラーのログが1件でもあれば実行全体が失敗している」とは考えないほうがよいという、実測に基づく注意点です。

    実機で気づいたこと

    動いたフローの数は2つ。1回のフィールド更新が2つのフローを動かしていたのは、事前には想定していませんでした。狙ったChange - Normal - Assessだけでなく、chg_mgt_workerという中間テーブルを経由したChange - Conflict Detectionまで同時に走っていました。トリガの条件を1つ確認しただけでは、実際に何が動くかを見落とすことがある、という気づきです。

    Business Ruleに2回止められた経験も、記録に残す価値があると思います。フローそのものは正しく組まれていても、その手前にあるレコード更新の条件を満たさなければ、フローの実行にすらたどり着けません。フローが動かないと感じたとき、原因がフロー側では無く、更新しようとしたレコードの必須項目にあるという可能性は見落としがちです。

    state=ERRORが1件も無かったのは、意外というより拍子抜けでした。失敗の見本を探していたのに、代わりに見つかったのは「ログにはエラーが残るのに実行全体はCOMPLETEのまま」という、少しねじれた実例です。エラーという言葉から連想する状態と、テーブル上のstateが指す状態は、必ずしも一致しません。

    sys_flow_contextの関連リスト「Flow engine log entries」が空のまま何も表示されないのを見たときは、一瞬「壊れているのでは」と疑いました。ですが承認待ちで止まっているだけの実行にログが無いのは当然で、エラーが起きて初めてログが増える、という順序を思い出せば納得できます。空欄を異常のサインだと決めつけないほうがよいと感じました。

    実務では何に使えるか:動いていないと言われたときの確認順

    「フローが動いていない」と相談を受けたとき、自分なら次の順番で見ます。

    1. トリガとなるはずのレコードを操作し直し、そのテーブルとsys_idをsource_table・source_recordで絞り込んでsys_flow_contextを見る

    2. 該当の実行が1件も無ければ、トリガの条件(table+condition)に一致していない可能性を疑う。Flow Designerでトリガカードを開き、条件式を確認する

    3. 実行が見つかればstateを見る。WAITINGなら、そのフローのアクション一覧を開いて何を待っているアクションかを確認する

    4. state=ERRORならsys_flow_logでエラーの文言を探し、sys_flow_runtime_valueでどのアクションまで値が渡っていたかを確認する

    5. state=COMPLETEなのに期待した結果が出ていないなら、フロー自体は正常終了しているので、後続のアクションが書き込む先の条件式や参照先を疑う

    6. WAITINGのまま数分以上動かないなら、「Open in Operations View」から運用者向けの画面を開き、フロー全体の進み具合を俯瞰する

    1回の更新が複数のフローを動かすこともあるので、目的のフロー名で一覧を絞り込んでから読むと迷いにくくなります。

    つまずきやすい点

    • sys_flow_contextを件数の多さに任せて新しい順に眺めるだけだと、目的の実行を見失います。source_tableとsource_recordで先に絞り込みます。

    • WAITINGを見て「止まっている=失敗」と判断しないほうが安全です。今回のように、承認待ちで正常に一時停止しているだけのことがあります。

    • レコードの状態を直接書き換えようとすると、フローとは無関係のBusiness Ruleに止められることがあります。エラーメッセージに出てくるルール名を手がかりに、フローより手前の関門を先に確認します。

    • sys_hub_trigger_instanceを開いても対象テーブルの列は出てきません。Flow Designerのトリガカードを開くほうが早く確実です。

    • Business Ruleに1回止められて設定を直しても、続けて別のBusiness Ruleに止められることがあります。今回も担当グループを足した直後、今度は担当者の所属で止まりました。1回通らなかったからといって、フロー側の問題だと決めつけないほうがよいです。

    よくある質問

    Q1. sys_flow_contextに実行が1件も無い場合、フローは動いていないと判断してよいですか

    トリガの条件に一致していない可能性が高いです。テーブルは合っていても、条件式(Model・State・On holdなど)のどれか1つが外れているだけで実行そのものが作られません。Flow Designerでトリガカードを開き、条件式を1つずつ確認します。

    Q2. WAITINGのまま長時間残っている実行は異常ですか

    必ずしもそうとは言えません。今回のように、承認や条件待ちで正常に一時停止している場合があります。フローのアクション一覧を見て、待機系のアクション(Wait For ConditionやAsk for Approvalなど)がどこにあるかを先に確認します。

    Q3. sys_flow_logに何も残っていないのに、期待どおり動いていない気がします。どこを見ますか

    sys_flow_context自体のstateを見ます。COMPLETEであればフローは正常終了しているので、原因はフローの外(後続処理が参照する条件やデータ側)にある可能性を疑います。ログは主にスクリプト内で例外が発生したときに増える情報です。

    Q4. 1回のレコード更新で複数のフローが動くことはありますか

    あります。今回の検証では、1回のChange Request更新で2つのフローが同時に動いていました。直接のトリガによるフローと、中間テーブル(chg_mgt_worker)を経由した別のフローです。想定していたフロー名で一覧を絞り込み、他に何が動いたかも合わせて確認するとよいです。

    Q5. 本番環境でも同じ手順で調査できますか

    基本の考え方は同じです。ただし本番環境は実行件数が桁違いに多くなるので、source_tableとsource_recordによる絞り込みを先に行わないと、対象の実行を探すだけで時間がかかります。

    まとめ

    フローが動いたかどうかは、sys_flow_contextをsource_tableとsource_recordで絞り込めば分かります。止まっている場合はstateを見て、WAITINGなら承認や条件待ちの可能性を、ERRORならsys_flow_logでエラーの文言を確認します。今回は既存のChange Requestを1件更新してChange - Normal - Assessフローを動かしました。承認待ちのWait For Conditionアクションで止まっている様子を、実行コンテキスト・フローのキャンバス・承認一覧の3画面から追いました。同じ更新がもう1つ別のフローも動かしていたことも、実際に動かしてみて初めて分かった事実です。

    用語

    • sys_flow_context … フローが1回実行されるたびに作られる記録。stateで今どこにいるかが分かる

    • sys_flow_runtime_value … 各アクションの入力・出力の実値を保持するテーブル

    • sys_flow_log … スクリプトアクションが出したログをレベル付きで記録するテーブル

    • sys_hub_trigger_instance … フローのトリガ定義。対象テーブルと条件式は別テーブル(sys_variable_value)に格納される

    • Wait For Condition … 指定した条件が満たされるまでフローの実行を一時停止するアクション

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

    自分のインスタンス名を先頭に付けると、同じ画面が開けます。

    実行コンテキスト一覧(新しい順) : sys_flow_context_list.do?sysparm_query=ORDERBYDESCsys_created_on
    特定レコードの実行だけに絞り込み  : sys_flow_context_list.do?sysparm_query=source_table=<テーブル名>^source_record=<sys_id>
    実行コンテキストをStateで集計    : sys_flow_context_list.do?sysparm_query=GROUPBYstate
    エラーレベルのログだけ表示       : sys_flow_log_list.do?sysparm_query=level=2^ORDERBYDESCsys_created_on
    承認の一覧を対象レコードで絞り込み: sysapproval_approver_list.do?sysparm_query=source_table=<テーブル名>^document_id=<sys_id>

    引用した公式説明を自分で開く

    この記事で引用した説明文は、ServiceNow が製品に同梱しているフィールド/プロパティのドキュメントです。次のURLを自分のインスタンスで開けば、引用元の原文にあたれます。

    • フィールドの公式説明(引用元):/sys_documentation_list.do?sysparm_query=nameINsys_flow_context,source_record,source_table^hintISNOTEMPTY

    • プラグインの公式説明(引用元):/v_plugin_list.do?sysparm_query=descriptionISNOTEMPTY

    関連記事

    参考リンク

    検証環境と未検証範囲

    件数と実行結果はこの環境の実測です。フィールドとプラグインの公式説明は、製品が持つドキュメント(sys_documentation と v_plugin)から 2026-08-11 に引用しました。

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

    state=ERROR(実行コンテキスト単位の失敗)の実例は、今回のPDIでは見つかりませんでした。意図的にエラーを発生させる操作は行っていません。Wait For Conditionアクションが承認以外にどんな条件で使われるか、stage_stateテーブルとsys_flow_contextの具体的な紐付け方、VA Telemetry Daily Rollupのエラーの原因そのものは、今回の検証範囲の外です。承認レコードを実際に承認・却下してフローが先に進む様子は、この記事のための更新を1件に限定する方針のため確認していません。件数は常に変動するスナップショットとして読んでください。

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

    あなたへのおすすめ