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

ServiceNowのSLAが付かない・すぐ止まる原因は? Start/Stop条件の競合を実機で再現する


    月次のSLA達成率を集計しようとしたら、メールや連携経由で起票した一群のインシデントにSLAが1件も付いていない。そう気づく運用リーダーは少なくありません。contract_slaの定義はすでに14件そろっているのに、なぜこの一群だけ対象外になるのでしょうか。原因の一つはStart条件とStop条件の競合ですが、実際にメールでインシデントを起票して確認すると、担当グループが空のままというもう一つの理由も見えてきます。Zurich PDIで実機検証しました。

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

    SLA Definitionのstart_condition / stop_conditionとは:SLAの時計(task_sla)を生み出すひな型がSLA Definition(contract_sla)です。どんなタスクに時計を付け始めるかをstart_conditionで、どこで止めて確定するかをstop_conditionで、それぞれ独立したフィルタ条件として設定します。

    月次のSLA達成率に、この一群だけ数字が出てこない

    運用リーダーがSLA達成率を月次で報告するとき、集計はcontract_slaに紐づくtask_slaの件数がベースになります。ある月、メールの問い合わせ窓口や外部連携から起票された一群のインシデントだけ、達成率の分母にも分子にも一件も現れないことに気づきます。SLA Definitionは14件も有効になっているのに、なぜこの一群だけが集計から漏れるのでしょうか。

    最初に疑うのは、SLA Definitionの設定ミスです。Start条件とStop条件が競合していて、SLAがそもそも作られていないのではないか。この疑いは半分正しく、半分足りません。以降ではまずStart条件とStop条件の競合そのものを実機で再現し、そのうえで実際にメールでインシデントを起票して確認すると見えてくる、もう一つの理由を追っていきます。

    Stop条件が起票の瞬間から真だと、SLAは黙って何も残さない

    運用リーダーがまず疑うとしたら、この競合です。同じZurich PDIの中で3パターンのSLA Definitionを動かすと、task_sla(SLAの実測レコード)が作られたのは2パターンだけでした。残る1パターンは、状態をどう更新してもtask_slaが一度も生まれません。

    • Start条件とStop条件が別の式なら、起票直後にtask_slaがIn progressで作られます

    • Stop条件が起票の瞬間から真だと、task_slaは作られません。ただし後の更新でStop条件だけ偽に戻れば、遅れて動き出します

    • Start条件とStop条件をまったく同じ式にすると、task_slaは二度と作られません


    画像

    上の図は、taskがinsert・updateされるたびにSLAエンジンが行っている判定です。Start条件を満たしても、その同じ評価でStop条件まで満たしていると、task_slaは作られずに終わります。痕跡はゼロです。作られなかった記録は他のどこにも残らないため、後から追いかけることができません。

    運用リーダーはSLAを「設定した通りに画面へ出る」ものだと期待している

    SLA Definitionをアクティブにしてタスクの条件を合わせれば、対象のタスクには自動でSLAの時計が付く。多くの運用リーダーはこの前提でSLAを運用しています。無理もありません。付かなかった場合はエラーか警告が画面のどこかに出るはずだ、という期待も併せ持っています。

    この期待には、もう1つの見落としが隠れています。SLAの判定は「今のタスクの状態」ではなく「その瞬間の評価」で決まるという点です。起票した0.1秒後に条件が変わっても、SLAエンジンが見ているのは挿入されたその瞬間のスナップショットです。ここがずれていると、後から一覧を見ても「なぜ付かなかったか」の手がかりが画面上に残りません。

    SLA DefinitionはIncidentの外側で動く独立した監視ルール

    SLA Definition(contract_sla)は、Incidentのビジネスルールやワークフローの一部として組み込まれているわけではありません。sys_db_objectで調べると、contract_slaのsuper_classは「Application File」でした。更新セットで移送される設定メタデータという位置づけで、Incidentテーブル自体には一切手を加えません。

    実際に条件を評価して時計を生み出しているのは、taskテーブルに定義された「Run SLAs」という別のビジネスルールです。afterタイミングで動くため、タスクの登録・更新トランザクションの中でStart条件とStop条件を毎回チェックします。Incident側のClient ScriptやUI Policyとは完全に別系統の仕組みで、フォームの見た目を一切変えないまま裏側だけで判定が完結します。

    Start・Stop・Pause・Resetという4条件がSLAの一生を決める

    contract_slaのフィールド定義を見ると、SLAの状態遷移を決める条件は4種類に分かれていました。

    start_conditionとstop_conditionが時計の始まりと終わりを決める

    start_conditionは「このSLAをどのタスクに付け始めるか」、stop_conditionは「どこで時計を止めて確定するか」を担います。この2つは完全に独立したフィルタ条件です。片方が真でも、もう片方の判定には影響しません。今回の検証で問題になったのは、この独立性そのものでした。2つの条件は別の式になっている前提で設計されているらしく、同じ式にしてしまうと想定していない結果を招きます。

    pause_conditionとreset_conditionは時計の途中経過を管理する

    pause_conditionは一時停止、reset_conditionはやり直しを担当します。On Holdの間だけ時計を止めるような設定は、このpause_conditionに書きます。今回の3パターンはどれもpause_conditionを空のままにしており、一時停止の挙動は検証範囲に含めていません。

    公式ドキュメントがStart条件とStop条件をどう説明しているか

    sys_documentation(フィールドの公式説明)を見ると、start_conditionとstop_conditionの役割がそれぞれ明記されていました。

    start_conditionの説明は次のとおりです。

    A task matching this condition will pull in this SLA and begin running it. A running SLA no longer matching this condition will be cancelled.
    (訳: この条件に一致するタスクはこのSLAを引き込み、動かし始めます。稼働中のSLAがこの条件に一致しなくなると、キャンセルされます)
    引用元: /sys_documentation_list.do?sysparm_query=name=contract_sla^element=start_condition

    stop_conditionの説明は次のとおりです。

    Determines when this SLA needs to be stopped and measured (generally when a task has been 'Resolved')
    (訳: このSLAをいつ停止して測定を確定するかを決めます。多くの場合はタスクが「Resolved」になったときです)
    引用元: /sys_documentation_list.do?sysparm_query=name=contract_sla^element=stop_condition


    画像

    上の画面はOOTBの「Priority 1 resolution (1 hour)」定義です。Start conditionのタブ見出しの下には注記が1行あります。「The conditions under which the new SLA will be attached and canceled」という文言です。start_conditionが単なる開始条件でなく、キャンセル判定も兼ねていることは、この注記からも読み取れます。

    SLA機能そのものについては、v_plugin(プラグインの公式説明)にこう書かれていました。

    SLA Definitions provide conditions to start, pause, stop, cancel and reset Task SLAs against any Task type.
    (訳: SLA Definitionは、あらゆるTask型に対してTask SLAを開始・一時停止・停止・キャンセル・リセットする条件を提供します)
    引用元: /v_plugin_list.do?sysparm_query=id=com.snc.sla

    startからresetまで5種類の条件が並列に扱われている点が印象的でした。stopとcancelは別の概念として明記されており、「Stop条件が最初から真で時計が動かない」という今回の現象は、この5分類のどこにも当てはまらない、いわば谷間の挙動だとわかります。

    OOTBの契約SLAは、担当グループが要る定義と要らない定義に分かれる

    運用リーダーの疑問に戻ります。報告から漏れていた一群の正体を探るため、contract_sla(SLA Definition)でIncident向けに有効な定義を全部洗い出しました。

    sys_script_includeのSLAConditionBaseは、start_conditionとstop_conditionを実際に評価しているスクリプトです。SLAを付け始めるかどうかを判定するattachという関数は、まずstart_conditionに一致するかを見ます。一致した場合でも、同じ評価でstop_condition(completeという別関数が判定)が真であれば、attachはfalseを返す作りでした。冒頭で再現した「Stop条件が起票の瞬間から真だと時計が作られない」という挙動は、この分岐がそのまま原因です。

    start_timeの決まり方も、TaskSLAというスクリプトに明記されていました。retroactive(開始時刻を遡らせる設定)を使わない既定の構成では、start_timeにはタスクの作成時刻ではなくsys_updated_on(タスクが最後に更新された時刻)がそのまま代入されます。前段で「Stateを更新した時刻がstart_timeになった」と実測した挙動は、このロジックが根拠です。この評価はtaskテーブルの「Run SLAs」ビジネスルール(afterタイミング、実行順101)が、タスクのinsert・updateのたびに呼び出しています。

    契約SLA本体の内訳も確認しておきます。Incidentに対して有効な定義は14件あり、内訳はSLA型11件・OLA型2件・Underpinning contract型1件でした。


    画像

    targetはcontract_slaの実在フィールドで、sys_documentationの公式説明は次のとおりです。

    The service level target this SLA is defined to measure
    (訳: このSLAが測定の対象として定義している、サービスレベルの目標)
    引用元: /sys_documentation_list.do?sysparm_query=name=contract_sla^element=target


    画像

    targetにはResponseかResolutionのどちらかが入ります。一覧表を並べると、Response側の5件(Priority 1〜5)は、すべてstart_conditionに「Assignment group is not empty」を含んでいました。Resolution側のPriority定義4件(P1〜P4)には、この条件が入っていません。そしてPriority 5だけは、Response定義こそあるものの、Resolution定義そのものが存在しない状態です。ATFの2件は自動テスト専用で、short_descriptionが固定文字列で始まるタスクしか対象にしません。

    実機で3パターンのSLA Definitionを動かして切り分ける

    Start条件とStop条件の競合を、まず作為的な条件で再現します。correlation_idという、通常のインシデント起票では値が入らないフィールドを使って、3件のテスト用インシデントとSLA Definitionを対応づけました。既存のデモデータや稼働中のSLAには一切触れない形で、3パターンを独立に再現できます。


    画像

    3件のテストチケットのうち、task_slaが存在するのは2件だけでした。3件目(StartとStopを同じ式にしたパターン)は、この一覧に一度も現れません。

    正常パターン:Start≠StopならSLAは起票直後に動く

    1件目は、start_conditionをcorrelation_id一致、stop_conditionをState = Resolvedという別々の式にしました。起票した直後にtask_slaを確認すると、stageはIn progressです。start_timeは登録時刻とほぼ同時刻でした。その後、Resolution codeを付けてStateをResolvedに更新すると、stageはCompletedへ変わります。end_timeが記録され、has_breachedはfalseのままでした。business elapsed percentageは4.83%で、想定どおりに時計が進んだ、比較対象となる正常系です。

    Stop条件が起票の瞬間から真だと、task_slaは生まれない

    2件目は、start_conditionをcorrelation_id一致、stop_conditionを「correlation_id一致かつState=New」という式にしました。インシデントはState=Newで作られるため、起票した瞬間にStart条件とStop条件が両方とも真になります。

    作成直後にtask_slaを数えると0件でした。15秒待ちました。数え直しても0件のままです。taskテーブルには「Run SLAs」という同期的なビジネスルールのほかに、非推奨の非同期ルールも存在しますが、後から拾い直すキューではないため、待っても結果は変わりませんでした。Incidentのフォームにも、SLAが付かなかったことを示す表示は一切出ません。

    このインシデントのStateをIn Progressへ更新すると、状況が変わりました。Stop条件の一部だった「State=New」が偽になり、Start条件だけが真の状態になったことで、その更新をきっかけにtask_slaが作られたのです。ただしstart_timeは、起票した時刻ではなく、Stateを更新した時刻でした。起票から更新までの間にあった時間は、SLAの計測にはまったく含まれません。

    StartとStopを同じ式にすると、SLAは二度と作られない

    3件目は、start_conditionとstop_conditionの両方に、まったく同じcorrelation_id一致の式を設定しました。この2つは常に同じ真偽値を取るため、Start条件が真になる瞬間には必ずStop条件も真です。


    画像


    画像

    タブを切り替えて見比べると、Start conditionとStop conditionに同じ1行がそれぞれ独立して設定されているだけで、画面上はどちらも正常な設定に見えます。保存時のエラーもありません。


    画像

    このパターンでは、Stateやその他の項目をどう更新しても、task_slaは一度も作られませんでした。ゼロ件のままです。2件目と違って「Stop側の条件だけを外す」更新が原理的に存在しないため、この定義が今の条件のままである限り、SLAが動く経路そのものがありません。

    この2つの失敗パターンが実務で起きる具体的な場面

    冒頭の運用リーダーの一群が、この2パターンのどちらかに当てはまっている可能性はあります。2件目のパターンは、Stop条件を「初期状態のどこかを含む複合条件」にしたときに起こります。たとえば「Assigned toが空でない、またはState=New」のような条件が一例です。担当者未割当のまま起票された瞬間から、Stop条件の一部がすでに真になっています。担当者が付くまで、SLAはずっと記録されない状態です。

    3件目のパターンは、既存のSLA Definitionを複製して作るときに起きやすくなります。Stop条件のタブを編集するつもりが、実際にはStart条件のフィルタをコピーしたまま保存してしまうことがあります。見た目には正しく設定されているのに、そのSLA Definitionだけが恒久的に機能しません。対象範囲が広いSLA Definitionでこれが起きると、影響を受けるタスクの数がそのまま被害の大きさになります。

    疑うときの確認順は次のとおりです。

    1. 対象タスクのcorrelation_idや番号でtask_slaを直接検索する。1件も出なければ、そもそも付いていない

    2. SLA DefinitionのStart conditionとStop conditionを開き、タスクが作られた瞬間の項目の値(今の値ではない)を当てはめて評価する

    3. StartとStopの条件式に、重なっている項目や値がないかを確認する

    retroactive_startで開始時刻を遡らせる余地もある(未検証)

    contract_slaにはretroactive_startという項目もあります。sys_documentationの説明は次のとおりです。

    SLA start time will be retroactive to an earlier time such as the task create date
    (訳: SLAの開始時刻は、タスクの作成日時のような、より早い時刻まで遡ります)
    引用元: /sys_documentation_list.do?sysparm_query=name=contract_sla^element=retroactive

    理屈のうえでは、2件目のように後から遅れて動き出したSLAでも、retroactive_startを有効にしてSet start toをCreatedにしておけば、開始時刻を起票時刻まで遡らせられる余地があります。今回の3パターンはどれもretroactive_startを使っていないため、この効果そのものはこの記事では検証していません。

    メールで起票すると、このSLAはどう動くか

    報告対象から漏れていた一群を再現するため、実際にメールでインシデントを起票して確認します。sys_emailに模擬メールを挿入し、標準のInbound Email Action「Create Incident」で起票させました(宛先・差出人はexample.comの架空アドレス)。メールの内容からpriorityがどう決まるかという仕組みそのものは別記事の範囲なので、ここでは起票結果とSLAの反応だけを追います。


    画像

    上の図は、ここまでのOOTB定義一覧と実測を1つの流れにまとめたものです。assignment_groupが空のまま評価に進む点は、パターンA・Bのどちらでも共通しています。分かれ道はtargetです。

    パターンA:Importanceヘッダーの無い通常メール

    ふつうの問い合わせメールを処理すると、インシデントはPriority 5-Planningで起票され、Assignment groupは空のままでした。このインシデントでtask_slaを検索します。


    画像

    task_slaは0件です。Priority 5にはResolution定義がそもそも存在しません。唯一あるResponse定義(40時間)も、Assignment group is not emptyを要求するため、空のままでは成立しません。このインシデントには、SLAの時計が一つも動いていない状態です。

    パターンB:Importanceヘッダーにhighを指定したメール

    同じ手順で、Importanceヘッダーにhighを指定したメールも処理しました。インシデントはPriority 1-Criticalで起票され、Assignment groupはこちらも空のままでした。


    画像

    今度はPriority 1 resolution (1 hour)が1件だけ付きました。ただしBusiness elapsed percentageはすでに100%です。start_timeが起票時刻のままで、1時間の猶予はとっくに過ぎています。Priority 1 response(15分)は、Assignment group is not emptyを満たせないため、今回も付きませんでした。理由はパターンAと同じです。


    画像

    2パターンの結果は、上の表のとおりです。Resolution側はpriorityさえ一致すれば動き、Response側はAssignment groupが空である限りどのpriorityでも動かないという、はっきりした線引きが見えます。

    メールにも応答SLAを利かせたいなら、担当グループを起票時に自動で埋める設定を足す

    この挙動はOOTBの設計として理屈が通っています。Response SLAは「担当チームが応答するまでの時間」を測る仕組みなので、担当が決まっていないタスクを対象外にする作りは妥当です。そのうえで、判定は場面ごとに分かれます。理由は明快です。

    • Priority 1〜4のResolution SLA:OOTBのままでよい。Assignment group条件が無く、メール起点でもpriorityさえ合えば実測どおりに動きます

    • Priority 1〜5のResponse SLA:応答時間を月次報告の指標にしたいなら設定を追加する。start_conditionにAssignment group is not emptyが入っており、メール起点では常に空のため、追加設定なしには動きません

    • Priority 5のResolution SLA:運用で決めておく。OOTBに定義が存在しないため、Planningレベルを月次SLA報告の対象に含めるかどうかは運用ポリシー次第です

    Response SLAをメール起点のインシデントにも効かせたい場合の設計案は次のとおりです。

    • 画面: Assignment Rules(テーブルはsysrule_assignment、/sysrule_assignment_list.do)

    • Table: Incident

    • Conditions: Contact typeがEmail

    • Group: 受付窓口として運用したい担当グループ(他のSLA・OLAのstart_conditionが参照していないグループを選ぶと、意図しないOLAの発動と混同しません)

    • 効く理屈: Assignment Rulesはレコードの挿入時に値を設定する仕組みで、SLAを評価する「Run SLAs」ビジネスルール(afterタイミング、実行順101)より先に値が確定します。そのため、SLAが評価される時点までにAssignment group is not emptyという条件を満たせるようになります

    この設計案は、本記事の検証環境では未実施です(詳細は末尾の検証範囲を参照)。実装する場合は、設定後にメールを1件処理させ、対象PriorityのResponse SLAが実際に付くことを確認してください。

    OOTBのまま運用する場合も、次の3点は運用ルールとして決めておくと迷いません。

    1. Priority 5(Planning)を月次SLA報告の対象に含めるかどうかを明文化する。含めないなら、報告の集計クエリからPriority 5を最初から除外しておく

    2. Response SLAを指標に使うなら、メール起点のインシデントは集計の母数から除外するか、担当グループを割り当てるタイミングを運用手順に明記する

    3. contract_slaを複製・追加するときは、targetがResponseかResolutionかに応じて、Assignment group条件を引き継ぐかどうかを毎回確認する

    実機で気づいたこと

    SLA Definitionのフォームには、青い案内が常に表示されます。文言は「An SLA starting now will breach on 2026-08-15 08:13:09 (Actual elapsed time: 1 Hour)」です。最初はこれを「このSLAは正しく機能する」という確認メッセージだと思っていました。誤解でした。3件目の永久に動かないパターンのフォームを開いても、まったく同じ案内が出ます。この表示はDurationとScheduleだけから算出した見込み時刻でした。Start条件とStop条件が競合していないかどうかとは、まったく無関係の数字です。

    enable_loggingという項目が、今回作成した3件でも初期値のまま未チェックでした。OOTBの定義を見ても、大半がこの項目をオフにしています。SLAがなぜ付かなかったのかを調べる手がかりを増やす設定が、既定では最初からオフになっているという点は、実務で調査するときに覚えておく価値があります。

    correlation_idを検証用のキーに選んだのも、実機を触っていて気づいた点です。OOTBのSLA Definitionの中には、テスト用にshort_descriptionの前方一致を条件にしているものがすでに存在しました。同じ手法を使うと、うっかり本物のデモデータや他の検証記事のインシデントと条件が重なる恐れがあります。correlation_idはどのOOTB設定からも参照されていなかったため、他のテストと干渉しない置き場所として使えました。

    「Response」と「Resolution」も、名前に含まれる言葉だと思い込んでいました。実際にはtargetという独立したフィールドの値で、一覧のカラムとしてそのまま並びます。命名規則ではなく構造の一部だと分かったことで、見え方が変わりました。なぜPriority 1〜4のResolutionだけがAssignment group条件を持たないのかが、targetという1つの軸ですっきり説明できます。

    パターンBのPriority 1 resolutionを確認した時点で、Business elapsed percentageはすでに100%でした。1時間の期間に対して確認まで半日以上が経っていたので当然ではありますが、Response SLAが最初から付いていれば、もっと早い段階でこの兆候に気づけたはずです。


    画像

    3パターンの条件と結果は、上の表のとおりです。Start条件とStop条件が独立している限り、SLAは正常に動きます。どちらかが重なった瞬間から、挙動が変わります。

    用語(実行順)

    • contract_sla(SLA Definition) … SLAのひな型。タスクの型ごとに開始・一時停止・停止の条件と期間を定義する

    • task_sla(Task SLA) … 1タスク・1定義ごとに生成される、実測の時計そのもの

    • start_condition … このSLAをどのタスクに付け始めるかを決める条件

    • stop_condition … このSLAをいつ止めて確定するかを決める条件

    • target … contract_slaが測定の対象として定義するもの。ResponseかResolutionが入る実在フィールド

    • Assignment Rules(sysrule_assignment) … レコード挿入時に条件に応じてAssignment groupなどを自動で設定する仕組み

    • stage … task_slaの状態。In progress・Paused・Achieved・Breached・Completed・Cancelledの6値

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

    • /contract_sla_list.do?sysparm_query=collection=incident^active=true … incidentに適用中のSLA Definition一覧

    • /task_sla_list.do?sysparm_query=task.correlation_idSTARTSWITH<接頭辞> … 特定タスクに紐づくSLA実測レコード

    • /task_sla_list.do?sysparm_query=task=<incidentのsys_id> … 特定の1件のインシデントに付いたSLA実測レコード

    • /sys_documentation_list.do?sysparm_query=name=contract_sla^hintISNOTEMPTY … contract_slaの各フィールドの公式説明

    • /sysrule_assignment_list.do?sysparm_query=table=incident^active=true … incident向けのAssignment Rule一覧

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

    この記事で引用した説明文は、ServiceNowが製品に同梱しているフィールドとプラグインのドキュメントです。次のURLを自分のインスタンスで開くと、同じ記述がフォームやプラグイン一覧の中に見つかります。

    • start_condition / stop_conditionの公式説明(引用元):/sys_documentation_list.do?sysparm_query=name=contract_sla^element=start_condition^ORname=contract_sla^element=stop_condition

    • retroactive(開始時刻を遡らせる項目)の公式説明(引用元):/sys_documentation_list.do?sysparm_query=name=contract_sla^element=retroactive

    • target(Response/Resolutionを示す項目)の公式説明(引用元):/sys_documentation_list.do?sysparm_query=name=contract_sla^element=target

    • SLA機能の公式説明(引用元):/v_plugin_list.do?sysparm_query=id=com.snc.sla

    参考リンク

    検証範囲とおことわり

    数値と挙動はZurich PDI(OOTB)で2026-08-15に確認したものです。テストはcorrelation_idで既存データと隔離した3件のインシデントとSLA Definitionのみを対象にしており、本番相当のデータやカスタマイズ済みの環境では条件の重なり方が異なります。

    検証はTypeが「SLA」で、Schedule未設定(24時間365日)の定義に限定しました。OLAやUnderpinning contractでの挙動そのものは実行していません(start_conditionを読んだ範囲の記述にとどまります)。業務カレンダーを指定したSchedule付きの定義、pause_conditionとreset_conditionの実際の動き、複数のSLAが同じタスクに並走するケースも、今回の検証範囲の外です。作成した3件のSLA Definitionは、検証後にActiveをfalseへ戻しました。既存のSLA運用には影響しない状態にしています。テスト用に作成したインシデント(INC0010462〜INC0010464)は、データとして残しています。

    メールで起票した2パターン(INC0010470とINC0010471)は、別記事(メール起票時のpriority決定)の検証で作成済みだったインシデントです。SLAの反応だけを、本記事で追加確認する形で流用しました。この追加検証では、PDIへの新規レコード作成は行っていません。SLAConditionBase・TaskSLAという2つのsys_script_includeは、読み取りのみで内容を確認しました。Assignment Rulesを使う設計案(担当グループを自動で埋める設定)は、コードを読んで導いた提案であり、本記事の検証環境では作成・実行していません。実装する場合は、設定後に自分の環境で動作を確認してください。

    関連記事

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

    あなたへのおすすめ