gcl
Version:
码农村nodejs类库,完成解决回调陷阱,配置框架,IOC框架,统一多DB访问框架,可扩展日志框架和io/db/net/thread/pool 克隆表达式,加解密算法等等一系列基础类库和算法的实现
309 lines (299 loc) • 9.59 kB
JavaScript
import V from '../common/tool';
import N from '../db/ni';
import F from 'fs';
import I from './tool';
import P from 'path';
import E from 'events';
export const LogType = {
/// <summary>
/// 最终的需要显示的正确结果
///</summary>
RELEASE: 0,
/// <summary>
/// 程序错误
///</summary>
ERROR: 1,
/// <summary>
/// 可能引发错误的警告
///</summary>
WARN: 2,
/// <summary>
/// 程序日志信息(默认信息)
///</summary>
INFO: 3,
/// <summary>
/// 程序调试信息
///</summary>
DEBUG: 4,
/// <summary>
/// 测试信息说明
///</summary>
TEST: 5,
/// <summary>
/// 全部的,一般作为默认参数使用
/// </summary>
All: 255
};
export const LogRecord = class {
constructor(logtype = LogType.INFO, needDateTime = true, needDiscript = true, needSeparator = false) {
const { _, __ } = pri(this, { separator: '==================================================================\r\n', params: [], recordTime: new Date(), data: "", num: 0, source: "" });
_.needDateTime = 'true' == ('' + needDateTime).toLowerCase();
_.needDiscript = 'true' == ('' + needDiscript).toLowerCase();
_.needSeparator = 'true' == ('' + needSeparator).toLowerCase();
}
get params() {
const { _, __ } = pri(this);
return __.params;
}
set params(data = []) {
const { _, __ } = pri(this);
__.params = Array.prototype.slice.apply(data, [0, data.length]);
}
get recordTime() {
const { _, __ } = pri(this);
return __.recordTime;
}
get data() {
const { _, __ } = pri(this);
return __.data;
}
set data(val = '') {
const { _, __ } = pri(this);
__.data = val;
}
get num() {
const { _, __ } = pri(this);
return __.num;
}
set num(val = 0) {
const { _, __ } = pri(this);
__.num = val;
}
get source() {
const { _, __ } = pri(this);
return __.source;
}
set source(val = '') {
const { _, __ } = pri(this);
__.source = val;
}
clone() {
const { _, __ } = pri(this);
const ret = new LogRecord(_.logtype, _.needDateTime, _.needDiscript, _.needSeparator);
ret.source = _.source;
ret.num = _.num;
ret.data = _.data
ret.params = _.params;
return ret;
}
toString(record) {
const { _, __ } = pri(this);
let rec = record || _;
return [
rec.needSeparator ? __.separator :
' ',
rec.needDateTime ? rec.recordTime.toString('yyyy-MM-dd HH:mm:ss:S ') : '',
rec.needDiscript ? LogType.map[rec.logtype] + " " : '',
rec.num > 0 ? rec.num + " " : '',
rec.data ? rec.data + " " : '',
rec.params ? rec.params.join(' ') : '',
rec.needSeparator ? `\r\n${__.separator}\r\n` : '\r\n',
].join('');
}
};
export const Logger = class {
constructor(logrecord = new LogRecord()) {
const { _, __ } = pri(this, { record: logrecord, event: new E.EventEmitter(), enable: true });
}
get enable() {
const { _, __ } = pri(this);
return __.enable;
}
set enable(data = true) {
const { _, __ } = pri(this);
__.enable = data;
}
setLisener(lisener) {
const { _, __ } = pri(this);
__.event.on('log', record => V.tryC(() => lisener.log(record)));
__.event.on('close', () => V.tryC(() => lisener.close()));
}
dispose() {
const { _, __ } = pri(this);
__.event.emit('close');
__.event.removeAllListeners();
}
log(logtype, data, params, num) {
const { _, __ } = pri(this);
if (_.enable) {
let record = __.record.clone();
record.logtype = logtype;
record.data = data + '';
record.params = params;
record.num = num;
__.event.emit('log', record);
}
}
error(...args) {
args.unshift(LogType.ERROR);
this.log.apply(this, args);
}
warn(...args) {
args.unshift(LogType.WARN);
this.log.apply(this, args);
}
release(...args) {
args.unshift(LogType.RELEASE);
this.log.apply(this, args);
}
info(...args) {
args.unshift(LogType.INFO);
this.log.apply(this, args);
}
debug(...args) {
args.unshift(LogType.DEBUG);
this.log.apply(this, args);
}
test(...args) {
args.unshift(LogType.TEST);
this.log.apply(this, args);
}
};
export const LogLisener = class {
constructor(triggers = [], formatter, resources = [], isAnd = true) {
const [...tri] = triggers, [...res] = resources;
const { _, __ } = pri(this, { triggers: tri, formatter: formatter, resources: res, isAnd: isAnd });
if (__.triggers.length == 0) throw new Error('triggers数组不能为空');
if (!__.formatter) throw new Error('formatter不能为空');
if (__.resources.length == 0) throw new Error('resources数组不能为空');
}
log(record) {
const { _, __ } = pri(this);
let isLog = __.isAnd;
__.triggers.forEach((v) => {
if (__.isAnd)
isLog &= v.test(record);
else
isLog |= v.test(record);
//if ((__.isAnd ? isLog > 0 : isLog == 0)) return false;
});
if (isLog > 0) {
let content = __.formatter.toString(record);
V.each(__.resources, v => { v.write(content); return false; });
}
}
close() {
const { _, __ } = pri(this);
V.each(__.resources, v => { if (v.close) v.close(); return false; });
}
};
export const ATrigger = class {
constructor() {}
test(record) { return true; }
}
export const AFormatter = class {
constructor() {}
toString(data) {
return data ? data.toString() : super.toString();
}
};
export const AResource = class {
constructor() {}
write(data) {}
close() {}
}
export const RegexTrigger = class extends ATrigger {
constructor(reg) {
super();
const { _, __ } = pri(this);
__.reg = new RegExp(reg);
}
test(record) {
const { _, __ } = pri(this);
return record.data.match(__.reg) != null || record.params.join(' ').match(__.reg) != null;
}
};
export const LogTypeTrigger = class extends ATrigger {
constructor(min = 0, max = LogType.INFO) {
super();
pri(this, { min, max });
}
test(record) {
const { _, __ } = pri(this);
return record.logtype >= __.min && record.logtype <= __.max;
}
};
/**
* 文件源服务
* @param {路径定义 会传入name参数} path
* @param {传入Date.toString参数生成文件名} nameformat
* @param {两次记录的等待时间} waittime
*/
export const FileResource = class extends AResource {
constructor(path = `.${V.environment.splitChar}log${name}.log`, nameformat = 'yyyyMMddHH', waittime = 20000) {
super();
pri(this, { path: path, nameformat: nameformat, sb: V.sb(), waittime, hasCreate: false });
}
write(data) {
const { _, __ } = pri(this);
if (data) {
if (__.sb.length == 0) {
__.sb.append(data);
V.once(() => V.tryC(() => {
const name = V.format(__.path, { name: new Date().toString(__.nameformat) });
if (!__.hasCreate) {
__.hasCreate = true;
var path = __.path.split(V.environment.splitChar);
path.forEach((k, i) => path[i] = k.indexOf('.') < 1 ? k : null);
I.createDir(path.join(V.environment.splitChar)).then(() => {
F.appendFile(name, __.sb.clear(), () => {});
});
} else
F.appendFile(name, __.sb.clear(), () => {});
}), __.waittime);
} else {
__.sb.append(data);
}
}
};
};
/**
* 文件夹源服务
* @param {文件夹定义 会传入dic参数} dic
* @param {路径定义 会传入name参数} path
* @param {传入Date.toString参数生成文件名} nameformat
* @param {两次记录的等待时间} waittime
*/
export const DicResource = class extends FileResource {
constructor(dic = '', path, nameformat, waittime) {
super(dic + path, nameformat, waittime);
}
};
/**
* 用于使用ni方法调用中间操作对象发送日志信息
* @param {模板名} templatename
* @param {方法名} methodname
* @param {中介者对象} middler
*/
export const NiResource = class extends AResource {
constructor(templatename, methodname, middler) {
super();
pri(this, { NiTemplateManager: new N.NiTemplateManager(middler), templatename, methodname });
}
write(data) {
const { _, __ } = pri(this);
if (data) {
V.tryC(() => __.NiTemplateManager.execute(__.templatename, __.methodname, { data }));
}
};
};
export default { LogType, LogRecord, Logger, LogLisener, ATrigger, AFormatter, AResource, RegexTrigger, LogTypeTrigger, FileResource, DicResource, NiResource };
const pri = V.pris();
LogType.map = (() => {
let ret = {};
for (let k in LogType) {
const v = LogType[k];
ret[v] = k;
}
return ret;
})();