Skip to content

Instantly share code, notes, and snippets.

@intech
Last active September 6, 2022 15:04
Show Gist options
  • Save intech/503facbc5320056d8f327070557fdf31 to your computer and use it in GitHub Desktop.
Save intech/503facbc5320056d8f327070557fdf31 to your computer and use it in GitHub Desktop.
Moleculer middleware tracing methods
// file: services/math.service.js
const { MoleculerError } = require("moleculer").Errors;
module.exports = {
name: "math",
actions: {
add(ctx) {
const { a, b } = this.parseParams(ctx.params);
return a + b;
},
sub(ctx) {
const { a, b } = this.parseParams(ctx.params);
return a - b;
},
mult: {
params: {
a: "number",
b: "number"
},
handler(ctx) {
const { a, b } = this.parseParams(ctx.params);
return a * b;
}
},
div: {
params: {
a: { type: "number", convert: true },
b: { type: "number", notEqual: 0, convert: true }
},
handler(ctx) {
let { a, b } = this.parseParams(ctx.params);
if (b !== 0 && !Number.isNaN(b)) return a / b;
else throw new MoleculerError("Divide by zero!", 422, null, ctx.params);
}
}
},
methods: {
parseParams: {
tracing: true,
handler({ a = 0, b = 0 }) {
return {
a: Number(a),
b: Number(b)
};
}
}
}
};
// file moleculer.config.js
const { Middlewares } = require("moleculer");
// register custom middlewares
Middlewares.tracingMethods = require("./middlewares/tracingMethods");
// ...
module.exports = {
// ...
// enabled custom middlewares
middlewares: ["tracingMethods"]
// ...
};
// file: middlewares/tracingMethods.js
const { AsyncLocalStorage } = require("async_hooks");
const { Utils } = require("moleculer");
const storage = new AsyncLocalStorage();
module.exports = {
name: "tracingMethods",
localAction(next) {
return ctx => {
if (this.isTracingEnabled()) {
const { span } = ctx;
return storage.run({ span }, () => next(ctx));
} else {
return next(ctx);
}
};
},
localEvent(next) {
return ctx => {
if (this.isTracingEnabled()) {
const { span } = ctx;
return storage.run({ span }, () => next(ctx));
} else {
return next(ctx);
}
};
},
localMethod(handler, method) {
if (this.isTracingEnabled() && method.tracing) {
return params => {
const ctx = storage.getStore() || {};
const tracer = ctx.span ? ctx.span : this.tracer;
const span = tracer.startSpan(`method '${method.name}'`, {
type: "method"
});
if(Utils.isPromise(handler)) {
return this.Promise.resolve(handler(params))
.then(res => {
span.finish();
return res;
})
.catch(e => {
span.setError(e);
throw e;
});
}
try {
const res = handler(params);
span.finish();
return res;
} catch (e) {
span.setError(e);
throw e;
}
};
} else {
return handler;
}
}
};
@intech
Copy link
Author

intech commented Aug 25, 2022

Screenshot from 2022-08-25 13-50-27

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment