0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ServiceNow】ロガークラスを作る【Server-Side】

Posted at

初めに

数年ぶりに記事投稿
最近、社内SEに転職し、ゆる~くServiceNowを触っております。
ServiceNowではコンテキスト系のログ出力があまり充実していないみたいなので出来るだけ簡単にそういった情報も出せるようなロガークラスをChatgptにも聞きながら考えたいと思います。

PDI環境

試したPDI環境はこんな感じです。
Version: Zurich
image.png

Studioからアプリケーションを作成

最初にloggerお試し用のアプリケーションを作成します。
image.png

Scopeはどっちでもいいですが、全アプリ共通に使うならGlobalでもいいかもしれないです。
image.png

ロールもデフォルトのままにしておきます。
image.png

アプリが作成されたら、Create FileでScriptIncludeを作成します。
image.png

image.png

シンプルなLogger作成

ひとまず、適当なNameをつけ、Accessible fromはAll Application scopesにしておきます。
image.png

まずはシンプルなロガーとしてこんな感じの作ってみました。

// ************************************************************
// Constant Variables
// ************************************************************
const Constants = Class.create();
Constants.DEFAULT_PREFIX = "MY_COMMON_LOGGER";
Constants.LOG_LEVEL_INFO = "INFO";
Constants.LOG_LEVEL_WARN = "WARN";
Constants.LOG_LEVEL_ERROR = "ERROR";
Constants.LOG_LEVEL_DEBUG = "DEBUG";

var CommonMyLogger = Class.create();
CommonMyLogger.prototype = {	
	/**
	 * オブジェクト生成時に呼ばれるクラス(コンストラクタ).
	 * @function initialize
	 * @param {Array} prefix - prefix log.
	 * @returns {None} return no values.
	 */
    initialize: function(prefix) {
		// 任意のプレフィックス
        this._prefix = prefix ?? Constants.DEFAULT_PREFIX;
    },

	// ************************************************************
	// Private Functions
	// ************************************************************
	/**
	 * ログ出力を整形する為の関数
	 * @function _formatMsg
	 * @param {string} level - Log level.
	 * @param {string} mgs - log message.
	 * @returns {string} formatted log message.
	 */
	_formatMsg: function(level, msg) {
        return "PREFIX = " + this._prefix + " [" + level + "] " + msg;
    },

	// ************************************************************
	// Public Functions
	// ************************************************************
	info: function(msg) {
        gs.info(this._formatMsg(Constants.LOG_LEVEL_INFO, msg));
    },

    warn: function(msg) {
        gs.warn(this._formatMsg(Constants.LOG_LEVEL_WARN, msg));
    },

    error: function(msg) {
        gs.error(this._formatMsg(Constants.LOG_LEVEL_ERROR, msg));
    },

    debug: function(msg) {
        gs.debug(this._formatMsg(Constants.LOG_LEVEL_DEBUG, msg));
    },

    type: 'CommonMyLogger'
};

呼び出し用のテーブルとUIアクションやビジネスルールを作成します。
※テーブルは適当にTaskでも継承しておきます。

UIアクションからはこのように呼び出して確認します。

const log = new x_1603370_logtes_0.CommonMyLogger();
log.info("ログのテストをしています...");

const log2 = new x_1603370_logtes_0.CommonMyLogger("TestCommonMyLoggerUiAction");
log2.info("ログのテストをしています...");

ちょっと雑ですがPREFIXで調べればロガークラスを使用している部分だけフィルタリングできますし、利用箇所で代入したprefix値のみで絞り込むこともできます。
image.png

もう少し詳細なLogger作成

もう少し色々出力したい時用にコンテキスト情報の取得処理を入れたりしています。

// ************************************************************
// Constant Variables
// ************************************************************
const Constants = Class.create();
Constants.DEFAULT_PREFIX = "MY_COMMON_LOGGER";
Constants.LOG_LEVEL_INFO = "INFO";
Constants.LOG_LEVEL_WARN = "WARN";
Constants.LOG_LEVEL_ERROR = "ERROR";
Constants.LOG_LEVEL_DEBUG = "DEBUG";

var CommonMyLogger = Class.create();
CommonMyLogger.prototype = {	
	/**
	 * オブジェクト生成時に呼ばれるクラス(コンストラクタ).
	 * @function initialize
	 * @param {Array} prefix - prefix log.
	 * @returns {None} return no values.
	 */
    initialize: function(prefix) {
		// 任意のプレフィックス
        this._prefix = prefix ?? Constants.DEFAULT_PREFIX;
    },

	// ************************************************************
	// Private Functions
	// ************************************************************
    // 呼び出し元のコンテキストを自動で検出
    _getContext: function() {
        var ctx = {};

        try {
            ctx.user = gs.getUserName();
            ctx.table = (typeof current !== 'undefined' && current) ? current.getTableName() : "";
            ctx.sys_id = (typeof current !== 'undefined' && current) ? current.getUniqueValue() : "";
            ctx.scope = gs.getCurrentScopeName();
            ctx.script = gs.getStackTrace().split('\n')[1] || "";
        } catch (e) {
            // コンテキスト取得でエラーが起きてもログは続行
        }

        return ctx;
    },

    // メッセージ整形
    _formatMsg: function(level, msg, ...args) {
        var ctx = this._getContext();

        var argStr = "";
        if (args && args.length > 0) {
            try {
                argStr = " ARGS=" + JSON.stringify(args);
            } catch (e) {}
        }

        return [
            "[" + this._prefix + "]",
            "[EXEC_ID=" + gs.generateGUID() + "]",
            "[" + level + "]",
            "[USER=" + ctx.user + "]",
            "[TABLE=" + ctx.table + "]",
            "[SYS_ID=" + ctx.sys_id + "]",
            "[SCOPE=" + ctx.scope + "]",
            msg,
            argStr
        ].join(" ");
    },

	// ************************************************************
	// Public Functions
	// ************************************************************
	info: function(msg, ...args) {
        gs.info(this._formatMsg(Constants.LOG_LEVEL_INFO, msg, ...args));
    },

    warn: function(msg, ...args) {
        gs.warn(this._formatMsg(Constants.LOG_LEVEL_WARN, msg, ...args));
    },

    error: function(msg, ...args) {
        gs.error(this._formatMsg(Constants.LOG_LEVEL_ERROR, msg, ...args));
    },

    debug: function(msg, ...args) {
        gs.debug(this._formatMsg(Constants.LOG_LEVEL_DEBUG, msg, ...args));
    },

    type: 'CommonMyLogger'
};

UIアクション側でこんな感じで呼び出したら

var log = new x_1603370_logtes_0.CommonMyLogger("MyUIAction");

log.debug("START", { x: 1, y: 2 });
log.info("処理中...");
log.warn("注意が必要です");
log.error("エラー発生", current);

結果こんな感じになります。
image.png

こんな感じでいっぱい出るようになるはずですが、これくらいしかテストしていないのでエラーとかが出ても悪しからず。。。
[MyUIAction] [EXEC_ID=32ec5fbc83a1f690678dfbb6feaad39b] [INFO] [USER=admin] [TABLE=x_1603370_logtes_0_logtesttable] [SYS_ID=eaec5fbc83a1f690678dfbb6feaad367] [SCOPE=x_1603370_logtes_0] 処理中...

専用のログテーブルへの書き出しとかセッションごとのIDを自動で付与するとかオブジェクトのjson自動整形等、やろうと思えばもっと色々出来ると思いますが今回はここまで。
何かしらの参考になれば幸いです。

参考URL

以下のURLを参考にしました。有益なサイト達に感謝します。
Script Includeに定数を持たせる

Just another Log Helper

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?