horus-agent
v1.2.0
Published
Autoinstrumentation for metrics and traces, used in the Horus infrastructure.
Downloads
11
Maintainers
Readme
Purpose
This npm package allows you to quickly and seamlessly add instrumentation to the backend of your application. It will automatically generate and export metrics and traces. It is used in the Horus infrastructure.
Set Up
Set Up Generation of Metrics & Traces
In your root service, do the following:
- Install the package using
npm
.
npm install horus-agent
- Import agents from
horus-agent
at the top of code file.
const { MetricsAgent, TracingAgent} = require("horus-agent")
- Set up tracing by invoking the
TracingAgent
function and pass it the name you would like it to be identified by. This should be invoked directly beneath your imported agents and before any other services. Most people give it the name of the service/part of the app they are tracing.
// imported agents...
TracingAgent("checkout-service")
// all other services...
- Beneath the initialization of
express
but above all of your routing, passstartLatency
andcountRequests
fromMetricsAgent
to the server.
const express = require('express');
const app = express();
app.use(
MetricsAgent.startLatency,
MetricsAgent.countRequests
)
// routes...
- Beneath all the routes on the same page, pass
countErrors
andendLatency
fromMetricsAgent
to the server.
// routes...
app.use(
MetricsAgent.countErrors,
MetricsAgent.endLatency
)
- In every route (or every route that you'd like to monitor), pass in
next
as a parameter and invokenext()
at the very end.
// example route
app.get('/dashboard', async (req, res, next) => {
const movies = await getUrlContents('http://localhost:4000/movies', nodeFetch);
res.type('json');
res.send(JSON.stringify({ dashboard: movies }));
next(); // next() is the last line of the route
})
- In order for errors to be detected by
MetricsAgent
, you must explicitly throw an error within a middleware or in a route handler. This is because when there is an error in Express, by default it will give a status code that matches the error, but it will not throw an error unless you explictly tell it to.
You can throw an error in a route:
app.get('/dashboard', async (req, res, next) => {
const movies = await axios.get('http://localhost/information');
if (movies.body.length === 0) {
return next (new Error('500')); // custom error to be thrown if information is empty
}
res.type('json');
res.send(JSON.stringify({ dashboard: movies }));
next(); // next() is the last line of the route
})
Or you can use a custom catch all middleware, placed beneath all other route handlers in the file:
// all other route handlers
app.use(function(req, res, next) {
if (!req.route) { // if the route does not exist (can add to this if/else conditional)
return next (new Error('404')); // throw a 404 error
}
next(); // send the req to the next middleware
})
// app.listen....
You're done!
Traces in Other Services
If you would like to see detailed spans/traces throughout every service of your application, add a TracingAgent to the top of the backend file for each service. Having the MetricsAgent in your root service alone is sufficient for metrics generation and capturing. Do not add a MetricsAgent to other services in the same application.
At the top of the backend file for another service:
const { TracingAgent } = require("horus-agent")
TracingAgent("inventory-service")
Set Up Exporting of Metrics & Traces
Change the endpoint
in config.json
to point to the host of your choice.
If you are hosting Horus via Docker on your local machine, you can keep the endpoint at localhost
(default). Otherwise, if you are hosting Horus via Docker on a VPS (e.g. DigitalOcean or AWS), replace it with the IP address or domain name.