npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

remitrace

v0.0.1

Published

Adds tracing in the form of persistent IDs to nested remit requests.

Downloads

1

Readme

remitrace

Utilises the tracing metadata available in remit >=2.2.0 to push captured messages to a queue (or to custom loggers) for storage and correlation.

yarn add remitrace
const { remitrace } = require('remitrace')
const remit = require('remit')()
remitrace(remit)

See remitrace-mongo for a practical example of its use.


It's a nice, simple function:

remitrace(remit, options)

  • remit A running remit instance of version >=2.2.0
  • options An optional object containing a few options for remitrace:
    • queueName The RabbitMQ topic that remitrace will emit to. Defaults to 'remitrace'.
    • customLoggers Any custom actions to be done with traces can be specified as functions in an array here which are passed the event of the action to be traced. Defaults to []. [console.log] is a nice way to see the traces being logged.
    • ignoredPaths Event names to ignore when tracing messages. Must be an array of regexes. Defaults to [/^queueName$/] where queueName is the option above.

Tracing with remitrace

remitrace on its own only allows the easy capture of the data needed to trace your calls. There is, however, a usable MongoDB-backed example over at [remitrace-mongo]. For clarity, I'll explain how it works here too.

remit >=2.2.0 provides some new metadata intended for tracing inside each event in a new metadata object.

  • originId The ID of the initial request or emission that started the entire chain of calls. Every call in a chain will have the same ID here.
  • bubbleId The "bubble" (see more below) that the action happened in.
  • fromBubbleId The "bubble" (see more below) that the action was triggered from.
  • instanceId A unique ID for each and every action.
  • flowType Either 'entry' to show it's an entrypoint to a bubble, 'exit' to show it's an exit from a bubble or blank to show it is neither.

These five properties can be used to create a picture of not only how particular calls are triggered, but the effect that a single call can have on an entire system, accessible from any point.

What's a bubble?

A bubble, in this context, is represented as all remit-related actions performed within a handler for an endpoint or listener.

A bubble is created whenever a request or emission is received by an endpoint or listener. This is an 'entry' (as dictated by the flowType metadata). 'exit's are the requests or emissions themselves.

How does the information correlate?

We'll assume for this section that all traces are stored as-is within a simple document store such as MongoDB.

First off, you can easily find all messages created from a single originId by just querying for exactly that:

{
  "originId": "01C31N0NMCMS5KX8E4GJ6BV0G2"
}

With that, you could list every single action that happened because of that origin message.

You can also, however, get a little better.

A more common practice would be to seek out the cause of a particular event. A listener is receiving an emission, let's say, but you don't know why or where from. Following it through a complex production system would be horrendous, but with remitrace it's easily possible.

As above, an instanceId is a unique ID given to every action. Using this along with flowType's entries and exits, we can easily find the direct route from cause to effect.

Find the trace of the instanceId you wish to track. If it's an entry point, you must find the exit that lead to it. If it's not an entry, find the entry. An example in code:

async function findCause (query, traces = []) {
  // handle the initial sending of an instanceId
  if (typeof query === 'string') {
    query = { 'event.metadata.instanceId': query }
  }

  // find a trace and return early if it's the end of the line
  const nextTrace = await myCol.findOne(query)
  if (!nextTrace) return traces
  traces.push(nextTrace)
  if (!nextTrace.event.metadata.bubbleId) return traces

  // sort out what to search for next
  const nextQuery = nextTrace.event.metadata.flowType === 'entry' ? {
    'event.metadata.flowType': 'exit',
    'event.metadata.bubbleId': nextTrace.event.metadata.fromBubbleId,
    'event.eventId': nextTrace.event.eventId
  } : {
    'event.metadata.flowType': 'entry',
    'event.metadata.bubbleId': nextTrace.event.metadata.bubbleId
  }

  // go search for it
  return findCause(nextQuery, traces)
}

const traces = await findCause('01C31NWW065X38YPBGJTZXAHVV')

The result of this would be a list of traces which lead to the specified action.