dev: add logger to putility

This commit is contained in:
KernelDeimos
2024-11-05 15:03:12 -05:00
parent fe8d6af1b5
commit b0cbcdf743
4 changed files with 207 additions and 1 deletions

View File

@@ -19,7 +19,7 @@
module.exports = {
name: 'Properties',
depends: ['Listeners'],
install_in_instance: (instance) => {
install_in_instance: (instance, { parameters }) => {
const properties = instance._get_merged_static_object('PROPERTIES');
instance.onchange = (name, callback) => {
@@ -39,6 +39,9 @@ module.exports = {
let spec = null;
if ( typeof properties[k] === 'object' ) {
spec = properties[k];
if ( spec.factory ) {
spec.value = spec.factory({ parameters });
}
} else if ( typeof properties[k] === 'function' ) {
spec = {};
spec.value = properties[k]();
@@ -59,9 +62,14 @@ module.exports = {
});
}
const old_value = instance[k];
const intermediate_value = value;
if ( spec.adapt ) {
value = spec.adapt(value);
}
state.value = value;
if ( spec.post_set ) {
spec.post_set.call(instance, value, {
intermediate_value,
old_value,
});
}
@@ -69,6 +77,13 @@ module.exports = {
});
state.value = spec.value;
if ( properties[k].construct ) {
const k_cons = typeof properties[k].construct === 'string'
? properties[k].construct
: k;
instance[k] = parameters[k_cons];
}
}
}
}

View File

@@ -0,0 +1,142 @@
const { AdvancedBase } = require("../..");
const { TLogger } = require("../traits/traits");
class ArrayLogger extends AdvancedBase {
static PROPERTIES = {
buffer: {
factory: () => []
}
}
static IMPLEMENTS = {
[TLogger]: {
log (level, message, fields, values) {
this.buffer.push({ level, message, fields, values });
}
}
}
}
class ConsoleLogger extends AdvancedBase {
static MODULES = {
util: require('util'),
}
static PROPERTIES = {
console: {
construct: true,
factory: () => console
},
format: () => ({
info: {
ansii: '\x1b[32;1m',
},
warn: {
ansii: '\x1b[33;1m',
},
error: {
ansii: '\x1b[31;1m',
err: true,
},
debug: {
ansii: '\x1b[34;1m',
},
}),
}
static IMPLEMENTS = {
[TLogger]: {
log (level, message, fields, values) {
const require = this.require;
const util = require('util');
const l = this.format[level];
let str = '';
str += `${l.ansii}[${level.toUpperCase()}]\x1b[0m `;
str += message;
// values
if (values.length) {
str += ' ';
str += values
.map(v => util.inspect(v))
.join(' ');
}
// fields
if (Object.keys(fields).length) {
str += ' ';
str += Object.entries(fields)
.map(([k, v]) => `\n ${k}=${util.inspect(v)}`)
.join(' ');
}
this.console[l.err ? 'error' : 'log'](str);
}
}
}
}
class FieldsLogger extends AdvancedBase {
static PROPERTIES = {
fields: {
construct: true,
factory: () => ({})
},
delegate: {
construct: true,
value: null
}
}
static IMPLEMENTS = {
[TLogger]: {
log (level, message, fields, values) {
return this.delegate.log(
level, message,
Object.assign({}, this.fields, fields),
values,
);
}
}
}
}
class LoggerFacade extends AdvancedBase {
static PROPERTIES = {
impl: {
value: () => {
return new ConsoleLogger();
},
adapt: v => {
return v.as(TLogger);
},
construct: true,
},
}
static IMPLEMENTS = {
[TLogger]: {
log (level, message, fields, values) {
console.log()
}
}
}
fields (fields) {
const new_delegate = new FieldsLogger({
fields,
delegate: this.impl,
});
return new LoggerFacade({
impl: new_delegate,
});
}
info (message, ...values) {
this.impl.log('info', message, {}, values);
}
}
module.exports = {
ArrayLogger,
ConsoleLogger,
FieldsLogger,
LoggerFacade,
};

View File

@@ -1,4 +1,5 @@
module.exports = {
TTopics: Symbol('TTopics'),
TDetachable: Symbol('TDetachable'),
TLogger: Symbol('TLogger'),
};

View File

@@ -0,0 +1,48 @@
const { LoggerFacade, ArrayLogger, ConsoleLogger } = require("../src/libs/log");
const { expect } = require('chai');
describe('log', () => {
it('facade logger', () => {
const array_logger = new ArrayLogger();
let logger = new LoggerFacade({
impl: array_logger,
});
logger.info('test message only');
logger.info('test message and values', 1, 2);
logger = logger.fields({ a: 1 });
logger.info('test fields', 3, 4);
const logs = array_logger.buffer;
expect(logs).to.have.length(3);
expect(logs[0].level).to.equal('info');
expect(logs[0].message).to.equal('test message only');
expect(logs[0].fields).to.eql({});
expect(logs[0].values).to.eql([]);
expect(logs[1].level).to.equal('info');
expect(logs[1].message).to.equal('test message and values');
expect(logs[1].fields).to.eql({});
expect(logs[1].values).to.eql([1, 2]);
expect(logs[2].level).to.equal('info');
expect(logs[2].message).to.equal('test fields');
expect(logs[2].fields).to.eql({ a: 1 });
expect(logs[2].values).to.eql([3, 4]);
});
it('console logger', () => {
let logger = new ConsoleLogger({
console: console,
});
logger = new LoggerFacade({
impl: logger,
});
logger.fields({
token: 'asdf',
user: 'joe',
}).info('Hello, world!', 'v1', 'v2', { a: 1 });
});
});