Closed pendenaor closed 6 years ago
Howdy!
Your logger looks just fine. 👍 It is not necessary to create every bit as a stamp. However, if you want to make the logger as a reusable stamp then you can do the same way as ArgOverProp
is implemented.
Ruffly ArgOverProp
is done this way:
const ArgOverProp = stampit.statics({
argOverProp(...args) {
return this.deepConf({ArgOverProp: [...args]});
}
})
.init(function (options, {stamp}) {
const {ArgOverProp} = stamp.compose.deepConfiguration;
for (let assignableArgName of ArgOverProp) {
this[assignableArgName] = options[assignableArgName];
}
});
Your logger could look like this (not necessary exactly like this):
import {argOverProp} from '@stamp/arg-over-prop';
const Logger = stampit(
argOverProp('prefix'),
{
methods: {
log(...args){ console.log(this.prefix, ...args); },
error(...args){ console.error(this.prefix, ...args); },
warn(...args){ console.warn(this.prefix, ...args); }
}
}
);
const HasLogger = stampit.statics({
hasLogger(name) {
return this.conf({HasLogger: {name}});
}
})
.init(_, {stamp}) {
const {HasLogger} = stamp.compose.configuration;
if (HasLogger) {
this.logger = Logger({prefix: HasLogger.name});
}
});
And usage:
const CustomerRestApi = stampit(
WithGetOperation,
HasLogger.hasLogger('CustomerRestApi'),
{
methods: {
all() {
this.logger.log('get all customers');
return this.get({params: {page: 1, limit: 15}});
}
}
);
I always prefer readability. So, the code above, I hope, is readable to you and any stampit newbie. (Sorry for semicolons.)
PS: a tip. The stampit
and the stampit.compose
you imported above are the same exact function. :) See source code.
Nice design, thanks for sharing some stampit enlightment!
Sorry for re-opening this issue, are we agree that the HasLogger
stamp cannot be composed with several stamps with their own prefixed log?
Below a sample to show what i mean :
import stampit from '@stamp/it';
import {argOverProp} from '@stamp/arg-over-prop';
const Logger = stampit(argOverProp('prefix'), {
methods: {
log(...args){ console.log(this.prefix, ...args); },
error(...args){ console.error(this.prefix, ...args); },
warn(...args){ console.warn(this.prefix, ...args); }
}
}
);
const HasLogger = stampit.statics({
hasLogger(name) {
return this.conf({HasLogger: {name}});
}
})
.init(function (_, {stamp}) {
const {HasLogger} = stamp.compose.configuration;
if (HasLogger) {
this.logger = Logger({prefix: HasLogger.name});
}
});
const Stamp1 = stampit(HasLogger.hasLogger('Stamp1'), {
methods: {
fn1: function fn1(...args) {
this.logger.log('fn1')
}
}
})
const Stamp2 = stampit(Stamp1, HasLogger.hasLogger('Stamp2'), {
methods: {
fn2: function fn1(...args) {
this.logger.log('fn2')
this.fn1()
}
}
})
const Stamp3 = stampit(Stamp2, HasLogger.hasLogger('Stamp3'), {
methods: {
fn3: function fn1(...args) {
this.logger.log('fn3')
this.fn2()
}
}
})
const s3 = Stamp3();
s3.fn3()
// Results
// Stamp3 fn3
// Stamp3 fn2 => Should be Stamp2 fn2
// Stamp3 fn1 => Should be Stamp1 fn1
Can i correct this behavior within HasLogger
?
Sorry for the late reply. Vacation ongoing.
I'll rewrite your code using classes:
class HasLogger {
constructor({ prefix }) {
this.logger = Logger({ prefix });
}
}
class Stamp1 extends Logger {
static prefix = 'Stamp1'
constructor({ prefix }) {
super({ prefix: prefix || Stamp1.prefix });
}
}
class Stamp2 extends Stamp1 {
static prefix = 'Stamp2'
constructor({ prefix }) {
super({ prefix: prefix || Stamp2.prefix });
}
}
class Stamp3 extends Stamp2 {
static prefix = 'Stamp3'
constructor({ prefix }) {
super({ prefix: prefix || Stamp3.prefix });
}
}
const s3 = new Stamp3();
s3.logger // WHAT YOU WILL HAVE HERE IS THE SAME AS IF THOSE WERE STAMPS
See code comment above.
You have the single object instance (s3
) and want the this.logger
to reference three different things (three loggers).
You better create a logger per each stamp. Something like that:
const Stamp1 = stampit({
init() {
this.loggerStamp1 = Logger({prefix: 'Stamp1'});
},
methods: {
fn1(...args) {
this.loggerStamp1.log('fn1')
}
}
})
Also, run this with you code: console.log(Stamp3.compose)
. It will print the metadata for the s3
object instance,
Ok, make me feel a little stupid 🙄 Thanks for your time.
I'm implementing service between a view and a Rest API.
Beside, i'm completly new to stamp programming and i'm in search of some advices about this sort of code:
Am i in the right directions?
Especially, the createLogger thing seems ugly!
How to inject a prefixed logger into each stamp ? How to extend that to warn, error, ... methods ?