log.mjs

import genID from './genID.mjs'
import nowms2str from './nowms2str.mjs'
import o2j from './o2j.mjs'
import isfun from './isfun.mjs'


/**
 * log紀錄封裝器
 *
 * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/log.test.mjs Github}
 * @memberOf wsemi
 * @returns {Object} 回傳事件物件,可呼叫事件init與log。init傳入紀錄器函數,可為sync或async,紀錄器會收到一個數據物件,此需由紀錄實做儲存方式。log為外部呼叫的紀錄函數,紀錄函數會收到from(觸發來源)、level(紀錄種類)、msg(紀錄訊息),回傳係為init取得之紀錄器函數回傳,故可能為sync(一般回傳)或async(Promise)。
 * @example
 *
 * let ms = []
 * let lg = log()
 * lg.init(function(v) {
 *     console.log(v)
 *     ms.push({
 *         from: v.from,
 *         level: v.level,
 *         msg: v.msg,
 *     })
 * })
 *
 * lg.log('service:web', 'infor', 'abc')
 * lg.log('service:web', 'error', 'def')
 * lg.log('service:api', 'infor', 'xyz')
 * console.log(ms)
 * // {
 * //   id: '{random-id}',
 * //   from: 'service:web',
 * //   level: 'infor',
 * //   msg: '"abc"',
 * //   time: '2021-08-06T14:05:38+08:00'
 * // }
 * // {
 * //   id: '{random-id}',
 * //   from: 'service:web',
 * //   level: 'error',
 * //   msg: '"def"',
 * //   time: '2021-08-06T14:05:38+08:00'
 * // }
 * // {
 * //   id: '{random-id}',
 * //   from: 'service:api',
 * //   level: 'infor',
 * //   msg: '"xyz"',
 * //   time: '2021-08-06T14:05:38+08:00'
 * // }
 * // [
 * //   { from: 'service:web', level: 'infor', msg: '"abc"' },
 * //   { from: 'service:web', level: 'error', msg: '"def"' },
 * //   { from: 'service:api', level: 'infor', msg: '"xyz"' }
 * // ]
 *
 */
function log() {
    let logger = null

    function logInit(loggerFun) {

        //check
        if (!isfun(loggerFun)) {
            throw new Error('loggerFun is not a function')
        }

        //save
        logger = loggerFun //sync or async function

    }

    function logRecord(from, level, msg) {

        //check
        if (logger === null) {
            throw new Error('no logger: need to construct by init')
        }

        //time
        let time = nowms2str()

        //d
        let d = {
            id: genID(),
            from,
            level,
            msg: o2j(msg),
            time,
        }

        //logger
        return logger(d)
    }

    return {
        init: logInit,
        log: logRecord,
    }
}


export default log