mirror of
https://github.com/HeyPuter/puter.git
synced 2026-01-07 05:30:31 -06:00
dev: add logger to putility
This commit is contained in:
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
142
src/putility/src/libs/log.js
Normal file
142
src/putility/src/libs/log.js
Normal 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,
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
TTopics: Symbol('TTopics'),
|
||||
TDetachable: Symbol('TDetachable'),
|
||||
TLogger: Symbol('TLogger'),
|
||||
};
|
||||
|
||||
48
src/putility/test/log.test.js
Normal file
48
src/putility/test/log.test.js
Normal 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 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user