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

gs(GlideSystem):ログ・プロパティ・空判定のヘルパー


    開発ハンズオンシリーズの7回目です。①のGlideRecordで検索と更新を、③のドット・ウォークで参照先の値を辿るところまで動かしてきました。ここまでのコードを思い返すと、結果を出すたびに毎回 gs.info(...) と書いていましたね。今回の主役は、その gs そのものです。

    gs は GlideSystem(グライドシステム)のインスタンスで、スクリプトのどこからでも呼び出せる共通ヘルパーです。ログを出したり、システムの設定値を読んだり、値が空かどうかを判定したり。GlideRecord が「テーブルを触る道具」だとすれば、gs は「スクリプト全体を下支えする便利箱」といった立ち位置になります。派手さはありませんが、実際のコードでは GlideRecord と同じくらいの頻度で顔を出します。

    今回も場所は Scripts - Background のまま。gs のよく使う顔を、3つに分けて動かしてみましょう。ログ出力・設定値の取得・空判定。この3役割を1枚の図にすると、こんな並びです。


    画像

    図の左から、ログ(info / warn / error)、設定値(getProperty)、判定(nil)。どれも「スクリプトを書いていると必ず欲しくなる小道具」ばかりです。ひとつずつ、実機で結果を見ながら手になじませましょう。

    この記事は、ServiceNow の PDI(Personal Developer Instance、無料の個人検証環境)Zurich リリース・OOTB(初期設定)で実機実行した記録です。コードの出力はすべて Scripts - Background で流した結果で、プロパティ値は REST でも二重確認しました(確認日 2026-07-19)。本番環境では実行しないでください。なお本文のプロパティ値は OOTB の既定値で、インスタンスによって変わり得ます。

    gs はどこから呼べるのか

    gs のありがたさは、「どこで書いても、そのまま使える」点にあります。Scripts - Background はもちろん、Business Rule でも Script Include でも、Flow のスクリプトステップでも、gs.info(...) や gs.getProperty(...) はそのまま通ります。GlideRecord のように new で作る手間すら要りません。サーバサイドのスクリプトなら、最初から gs という名前で待っていてくれます。

    なぜそんなに気軽に呼べるのでしょうか。gs はインスタンス全体にかかわる共通の窓口として、実行環境があらかじめ用意してくれているからです。ログの出し先も、プロパティの保管場所も、判定のロジックも、gs の内側に畳み込まれています。書く側は中の仕組みを知らなくても、gs.info('...') と一行書けば結果が出る。この手軽さのおかげで、処理の本筋に集中できます。

    実務で効いてくるのは、この共通性です。今日 Scripts - Background で覚えた gs.getProperty の書き方は、明日 Business Rule に書いても寸分違わず動きます。場所ごとに書き方を覚え直す必要がありません。だから gs の顔をいくつか押さえておくと、その知識はスクリプトのあらゆる場所へ効いてきますよ。まずは今日の3つから始めましょう。

    gs は GlideRecord のとなりで働く

    このシリーズの主役は、ずっと GlideRecord でした。テーブルを検索し、値を読み、書き込む。その中心の道具がある一方で、gs はとなりで細々とした世話を焼いてくれる存在です。役割がはっきり分かれているので、両者はよく組んで登場します。

    たとえば GlideRecord で取ってきたレコードの値を、gs.info でログに出して確かめる。プロパティで決めたしきい値を gs.getProperty で読み、件数と比べて分岐する。読み込んだ値が空かどうかを gs.nil で確かめてから、次の処理へ進む。GlideRecord が主役なら、gs は頼れる名脇役です。今日はその脇役の仕事ぶりを、じっくり眺めてみましょう。

    システムプロパティを読む:getProperty

    最初は設定値の取得です。ServiceNow には「システムプロパティ」という、インスタンス全体の設定をキーと値で持つ仕組みがあります。製品名や日付の書式といった、環境ごとに決まっている値がここに入っています。その値をコードから読むのが gs.getProperty です。

    gs.info('製品名   glide.product.name       : ' + gs.getProperty('glide.product.name'));
    gs.info('説明     glide.product.description : ' + gs.getProperty('glide.product.description'));
    gs.info('日付書式 glide.sys.date_format     : ' + gs.getProperty('glide.sys.date_format'));

    このコードを Scripts - Background に貼り付けて、「Run script」を押してみてください。3つの設定値が並んで出てきます。


    画像

    glide.product.name は ServiceNow、glide.product.description は Service Management でした。どちらも製品まわりの設定値ですね。

    日付書式の glide.sys.date_format は yyyy-MM-dd。どれも glide. で始まるキーです。ServiceNow の内部設定は、こうした「ドット区切りのキー」で整理されていて、getProperty にキー名を渡すと、対応する値が文字列で返ってきます。

    もうひとつ、プロパティは値をすべて文字列として返す点も覚えておくと安心です。glide. で始まるキーは数百種類あり、数値や true/false に見える設定も、getProperty の戻り値はあくまで文字列で届きます。数として扱いたいときは、受け取ってから自分で変換する。この一手間を知っておくと、「数字のはずなのに比較がうまくいかない」といった小さなつまずきを避けられますよ。

    この読み方が効くのは、環境ごとに変わる値をコードに直書きせずに済むからです。たとえば日付の書式を扱う処理を書くとき、yyyy-MM-dd と決め打ちで埋め込んでしまうと、書式の違うインスタンスでは崩れます。gs.getProperty('glide.sys.date_format') で読めば、そのインスタンスの設定にいつも従えます。設定は設定の場所に、コードはコードに。この切り分けが、あとで効いてきますよ。

    無いプロパティは既定値でしのぐ

    では、指定したキーのプロパティが存在しなかったら、どうなるのでしょうか。試しに、ありもしないキーを2通りの書き方で読んでみます。

    gs.info('存在しない          : [' + gs.getProperty('my.not.exist.prop') + ']');
    gs.info('既定値つき          : ' + gs.getProperty('my.not.exist.prop', '(既定値)'));


    画像

    上の行は [null] と出ました。角かっこで囲ったので分かりやすいですが、未設定のプロパティを読むと null が返ります。下の行は (既定値)。第2引数に渡した文字列が、そのまま返ってきています。getProperty は「キーが無ければ第2引数を返す」という、フォールバックの仕組みを持っているわけです。

    この第2引数が、地味ながら実務で効きます。プロパティは管理者が後から追加する運用も多く、コードを書いた時点ではまだ存在しないこともあります。既定値を添えておけば、キーが未設定でもスクリプトは null に振り回されず、想定した値で動き続けます。「無ければこれを使う」を一行で書けるので、null チェックのための if を別に用意する手間も省けますね。安全側に倒しておく、ちょっとした保険です。

    ログの3段階:info / warn / error

    次はログです。ここまで gs.info ばかり使ってきましたが、gs のログには重要度の違う3段階が用意されています。情報の info、警告の warn、異常の error。順に出してみましょう。

    gs.info('これは INFO レベルのメッセージ');
    gs.warn('これは WARN レベルのメッセージ');
    gs.error('これは ERROR レベルのメッセージ');


    画像

    3行とも出力されましたが、実測でひとつ気づいた点があります。正直に書いておきますね。gs.error の行だけ、末尾に : no thrown error という文字が付きました。info と warn はメッセージがそのまま出ています。これは例外オブジェクトを渡さずに error を呼んだときの Scripts - Background の挙動で、「投げられた例外は無いよ」という補足が添えられたものです。メッセージ本体が化けたわけではないので、驚かなくて大丈夫です。

    3段階を使い分ける意味は、後からログを読むときに出てきます。gs のログは System Log(syslog テーブル)に、重要度のラベル付きで残ります。ふだんの足跡は info、気にとめてほしい事象は warn、止まってしまった異常は error。そう出し分けておくと、あとで「エラーだけ拾いたい」ときに重要度で絞り込めます。処理が長くなるほど、この足跡が後日の自分を助けてくれます。全部 info で流すより、少し手をかける値打ちがありますよ。

    出したログをどこで見るのか、も押さえておきましょう。Scripts - Background なら実行直後の画面下にそのまま並びますが、時間をおいて振り返るときは System Log の一覧が頼りになります。All メニューから「System Log」を開くと、Level(重要度)や Created(作成時刻)で並べ替えたり絞り込んだりできます。自分の出したメッセージがちゃんと残っているかを、あとから目で確かめられる。この安心感が、ログを仕込む習慣を後押ししてくれますよ。

    空かどうかを1つで:gs.nil

    最後は判定です。スクリプトを書いていると、「この値、入ってる? 空?」を確かめたい場面が何度も来ます。空文字だったり null だったり、空にもいくつか形がありますが、それを1つでまとめて判定できるのが gs.nil です。

    gs.info("gs.nil('')      : " + gs.nil(''));
    gs.info("gs.nil('hello') : " + gs.nil('hello'));
    gs.info("gs.nil(null)    : " + gs.nil(null));


    画像

    結果は上から true / false / true。空文字は中身が無いので true、hello は中身があるので false、null も空とみなして true。gs.nil は「空文字でも null でも、とにかく中身が無ければ true」を返してくれます。両方を別々に確かめなくていい、というのがありがたいところですね。

    実務では、未入力チェックをこれ一本で書けるのが効きます。たとえば必須のはずの項目を読んで、if (gs.nil(x)) と書けば、「x が未入力なら」を素直に表せます。x == '' || x == null と条件を並べる必要はありません。書き方が短くなると、読む人にも意図がすっと伝わる。「空だったら弾く」という、よくある処理がきれいに収まります。

    「空」にいくつも形があるのは、JavaScript の値の作りに由来します。まだ何も入っていない null、文字は文字でも長さゼロの空文字、値が定まっていない undefined。人からするとどれも「空っぽ」ですが、コードで律儀に区別すると条件が長くなりがちです。gs.nil は、その細かな違いをまとめて面倒みてくれる。だから未入力チェックのような場面で、素直に頼れるわけですね。

    つまずきやすいところ

    gs まわりで最初にとまどう点を、先回りで挙げておきます。どれも一度は通る道なので、知っておくと落ち着いて対処できます。

    • プロパティ名のスペルミス:getProperty はキーが少しでも違えば null を返します。エラーで止まらないぶん、値が空のときはまずキー名を疑いましょう。既定値を第2引数に添えておくと、取り違えにも早く気づけます。

    • error を軽い気持ちで使う:gs.error はログに「異常」として残ります。ふだんの経過を出したいだけなら info で十分です。重要度は、後で読む人への合図だと思って選ぶとよいですね。

    • nil の判定範囲を思い違える:gs.nil が空とみなすのは、空文字や null のような「中身なし」です。数値の 0 や false のような、値としては入っているものまで空扱いにはしません。0 を弾きたいなら、別の条件を足す必要があります。

    どれも、エラーで派手に止まってくれないのが共通点です。null が返っても、error のログが残っても、スクリプト自体はそのまま先へ進みます。だからこそ「出力がなんだかおかしい」と感じたら、まず gs の使い方を一度見直してみると、原因の切り分けが早まりますよ。

    ヘルパー早見表

    今回登場した gs のメソッドを、ひとまず一覧にしておきます。まずはこの顔ぶれを手になじませれば、しばらく困りません。


    画像

    どれも呼び出しは一行で済むものばかりです。引数の形、つまりキー名やメッセージ、判定したい値さえ押さえておけば、あとは必要な場面で取り出すだけで動きます。名前と役割がひもづくと、コードを読むときも「ここでログ、ここで設定値」と、意図がすっと頭に入ってきますね。丸暗記しようとせず、この表を手元に置いて、書きながら確かめるくらいの気持ちで十分ですよ。

    今回の実測まとめ

    そして、実機で流したときの結果を1枚にまとめた表がこちらです。本文で触れた値と、そのまま突き合わせられます。


    画像

    表の値は、すべて筆者の PDI(Zurich / OOTB)の Scripts - Background で流した結果です。プロパティの3つは REST(sys_properties)でも同じ値を読み直して確認しました。手元の環境で同じコードを流せば、プロパティ値以外はほぼ同じ結果が出るはずです。プロパティ値だけは、あなたのインスタンスの設定しだいで変わります。

    数字を二度確かめているのには理由があります。画面に出た文字だけを信じると、見間違いや貼り間違いに気づけません。プロパティの値は sys_properties テーブルにも同じものが入っているので、REST でそちらを読み、突き合わせています。ふたつの入口から同じ値が返れば、記事に載せる数字として安心して出せますね。

    実務での使いどころ

    gs の3つは、実際のスクリプトでどう効いてくるのでしょうか。日々出会う形を、いくつか並べてみます。

    まずプロパティ。環境ごとに変わる値、たとえば通知の宛先メールや外部システムの接続先といった設定は、コードに直書きせず、システムプロパティに外出しするのが定石です。gs.getProperty で読むようにしておけば、検証環境と本番環境で同じコードを使い回せます。設定を変えたいときも、プロパティの値を書き換えるだけ。コードには手を触れずに済むので、変更の影響範囲が小さくとどまります。

    次にログ。処理の要所で gs.info を仕込んでおくと、あとから「どのレコードを、どの順で触ったか」を追いかけられます。夜間バッチのように人が見ていない処理ほど、この足跡が値打ちを持ちます。異常時だけ gs.warn や gs.error を出しておけば、System Log を重要度で絞り込んで、問題の箇所へ最短でたどり着けますね。

    最後に判定。入力チェックや分岐の入り口で gs.nil を使うと、条件がすっきり読めます。参照フィールドが未設定のとき、③のドット・ウォークでは空文字が返ってきましたね。ああいう「空のこともある値」を扱うとき、gs.nil はそのまま受け止めてくれます。前回までの知識と、今回の gs が、こうしてつながります。

    3つに共通するのは、「本筋のコードを、余計なもので汚さない」という発想です。設定はプロパティへ、経過はログへ、空判定は gs.nil へ。それぞれ専用の受け持ちに預けておくと、GlideRecord の処理そのものは読みやすいまま保てます。小さな道具ですが、コードの見通しを守る働きは案外あなどれません。

    まとめ

    今回は gs の3つの顔を動かしました。設定値を読む getProperty(第2引数に既定値を渡せる)、重要度で使い分けるログ info / warn / error、空文字も null もまとめて判定する gs.nil。どれも派手さはありませんが、GlideRecord のコードを書くとき、すぐ隣で支えてくれる小道具ばかりです。

    一度手を動かすと、次にスクリプトを書くとき、自然と gs に手が伸びるようになります。「この設定値、プロパティに無いかな」「ここでログを1行残しておこう」「空だったら弾こう」。そんな判断が、コードを書きながら湧いてきます。ぜひ自分の PDI で、今日の4つのコードをそのまま流してみてください。

    次回からは、いよいよ実務レシピ編に入ります。①から⑦まで積み上げてきた GlideRecord・GlideAggregate・ドット・ウォーク、そして今回の gs を組み合わせて、そのままコピペで使える実務スニペット集をお届けする予定です。「現場でよくある処理」を、すぐ貼って動かせる形で束ねます。手を動かす楽しさは、そのままに。

    その他、実機で確認した記録

    用語

    • gs(GlideSystem) … ログ・プロパティ・判定などをまとめて提供する共通ヘルパー

    • getProperty … システムプロパティ(設定値)をキー名で読む。第2引数に既定値を渡せる

    • システムプロパティ … インスタンス全体の設定をキーと値で持つ仕組み(sys_properties)

    • gs.info / warn / error … 重要度の違う3段階のログ出力(情報 / 警告 / 異常)

    • System Log(syslog) … ログが重要度つきで残るテーブル

    • gs.nil … 空文字や null などの「中身なし」を1つで判定する(空なら true)

    実行に使ったスクリプト

    本文のコードは、そのまま Scripts - Background に貼れば動きます(実行は必ず PDI で)。出力はすべて筆者の PDI(dev / Zurich / OOTB)で流した実画面です。プロパティの3値は REST(sys_properties)でも読み直して突き合わせました。

    調べるときの入口URL(先頭に自分のインスタンスを付ける)

    • /sys.scripts.do … Scripts - Background(今回コードを流した画面)

    • /sys_properties_list.do?sysparm_query=nameSTARTSWITHglide.product … 今回読んだ製品系プロパティの一覧

    • /syslog_list.do?sysparm_query=ORDERBYDESCsys_created_on … System Log(gs.info / warn / error の出力を辿れる)

    実測の要点(再掲)

    • glide.product.name = ServiceNow / glide.product.description = Service Management / glide.sys.date_format = yyyy-MM-dd

    • 未設定プロパティ = null(既定値つきなら第2引数の「(既定値)」が返る)

    • ログ3段階 … gs.error の出力末尾に「: no thrown error」(例外未指定時の Scripts - Background 挙動)

    • gs.nil('') = true / gs.nil('hello') = false / gs.nil(null) = true

    検証範囲とおことわり

    • 実行は PDI(Zurich / OOTB)の Scripts - Background・scope=global のみ。本番やスコープドアプリでの挙動差は範囲外です。

    • プロパティ値(product.name など)は OOTB の既定値です。インスタンスの設定により変わり得ます。

    • gs.error の「: no thrown error」は、例外オブジェクトを渡さなかったときの Scripts - Background の表示です。error に例外を渡した場合の出力は、この記事の範囲外とします。

    • gs.getUser や gs.nowDateTime のような、セッションや現在時刻に依存するものは、再現性のため本記事では扱いません。

    参考リンク

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

    あなたへのおすすめ