Logger Middleware
The Logger Middleware is built-in middleware that gives you capability to add observability to your application by logging:
- the intent (
query
,command
orevent
) before and once handled (or errored) - the result(s) of the handler(s)
- the Stamps
How to use it
As for any Middleware, you can use it by adding it to the bus
instance.
const queryBus = createQueryBus<QueryHandlerRegistry>();queryBus.useLoggerMiddleware({logger, adapter});
Remember built-in middlewares are intent aware, therefore you can customize the behavior per intent using the key
intents
.
Of course, the key is in the adapter
that you can provide to the createLoggerMiddleware
function.
This adapter must respect the LoggerAdapter
interface.
Logger must respect LoggerInterface which is
log(...args: unknow[]): void
anderror(...args: unknow[]): void
Here is an example:
export const adapter: LoggerAdapter = { processing: (identity, message, results, stamps) => logger.log( `[Envelope<${identity?.body?.id}>](Processing)`, JSON.stringify({ message, results, stamps, }), ), processed: (identity, message, results, stamps) => { const timings = stamps.filter((stamp) => stamp.type === 'missive:timings')?.[0] as TimingsStamp | undefined; logger.log( `[Envelope<${identity?.body?.id}>](Processed${timings?.body?.total ? ` in ${(timings.body.total / 1000000).toFixed(4)} ms` : ''})`, JSON.stringify({ message, results, stamps, }), ); }, error: (identity, message, results, stamps) => { const timings = stamps.filter((stamp) => stamp.type === 'missive:timings')?.[0] as TimingsStamp | undefined; logger.error( `[Envelope<${identity?.body?.id}>](Errored${timings?.body?.total ? ` in ${(timings.body.total / 1000000).toFixed(4)} ms` : ''}`, JSON.stringify({ message, results, stamps, }), ) }};
Explanation
Internally, the Logger Middleware is going to call that adapter 2 times:
processing
: when the message is receivedprocessed
: when the message is handlederror
: when the message is in error
The parameters for each of those functions are:
identity
: A Stamp that contains theid
of the Envelopemessage
: The intent that has been dispatchedresults
: The result(s) of the handler(s)stamps
: The rest of the Stamps. (yes Identify and Results are extracted stamps from the Envelope)
Added Stamps
The Logger Middleware is going to add:
-
type TimingsStamp = Stamp<{ total: number }, 'missive:timings'>
When the message is handled or errored with the total time elapsed in nanoseconds.
Going further
Missive.js. MIT License.
Powered by Astro Starlight.
Inspired by Symfony Messenger