@talks.converse/js-monitoring
Version:
Express monitoring middleware with Datadog and Prometheus backends, plus conditional logging.
109 lines (99 loc) • 3.65 kB
JavaScript
const StatsD = require('hot-shots');
const helper = require('./helper');
const datadogEndpointsInclude = process.env.DATADOG_ENDPOINTS_INCLUDE
const datadogEndpointExclude = process.env.DATADOG_ENDPOINTS_EXCLUDE
// Configure DogStatsD client
const dogstatsd = new StatsD({
host: process.env.DD_AGENT_HOST || '127.0.0.1',
port: process.env.DD_AGENT_PORT || 8125,
});
/**
* Main delegate called from the js-monitoring entrypoint.
* Based on configuration, it chooses to send metrics either as a histogram
* or as a combination of counter and gauge. This allows flexibility in metric
* reporting depending on cost and detail requirements.
*
* @param {string} app_name - The name of the application or metric prefix.
* @param {number} latencyMs - The latency in milliseconds to report.
* @param {Array<string>} tags - An array of tags to associate with the metric.
*/
const monitor = (app_name, latencyMs, tags) => {
// Add option to send via histogram
if (process.env.MONITORING_METRIC_TYPE === 'histogram'){
sendHistogram(`${app_name}.metrics`, latencyMs, tags);
} else {
// For cheaper price, we use count and gauge over histogram since we only need to see simple avg and max
// Notes.
// Histogram can cost 5x than counter/gauges since histogram creates:
// (avg, count, max, median, 95percentile)
sendCounter(`${app_name}.count`, 1, tags);
sendGauge(`${app_name}.latency`, latencyMs, tags);
}
};
/**
* Gracefully closes the Datadog DogStatsD client connection.
* This should be called when the application is shutting down to ensure
* all metrics are flushed properly.
*/
const closeConnection = () => {
dogstatsd.close();
};
/**
* Builds the configuration object containing compiled regex lists
* for including and excluding endpoints from monitoring.
* These regex lists are derived from environment variables and used
* to filter which endpoints should be monitored.
*
* @returns {{include: Array<RegExp>, exclude: Array<RegExp>}} Object with include and exclude regex arrays.
*/
const buildDatadogMonitoringEndpointsConfig = () => ({
include: helper.compileRegexList(datadogEndpointsInclude),
exclude: helper.compileRegexList(datadogEndpointExclude),
});
/**
* Send a counter metric (increments by the given value, default 1).
* Implemented using DogStatsD increment method.
*
* @param {string} metric - Metric name.
* @param {number} value - Value to increment the counter by.
* @param {Array} tags - Array of tags.
*/
const sendCounter = (metric, value = 1, tags = []) => {
dogstatsd.increment(metric, value, 1, tags, (err) => {
if (err) console.error('Error sending counter:', err);
});
};
/**
* Send a gauge metric (sets the absolute value).
* Implemented using DogStatsD gauge method.
*
* @param {string} metric - Metric name.
* @param {number} value - Value to set for the gauge.
* @param {Array} tags - Array of tags.
*/
const sendGauge = (metric, value, tags = []) => {
dogstatsd.gauge(metric, value, 1, tags, (err) => {
if (err) console.error('Error sending gauge:', err);
});
};
/**
* Send a histogram observation.
* Implemented using DogStatsD histogram method.
*
* @param {string} metric - Metric name.
* @param {number} value - Numeric value for the histogram.
* @param {Array} tags - Array of tags.
*/
const sendHistogram = (metric, value, tags = []) => {
dogstatsd.histogram(metric, value, 1, tags, (err) => {
if (err) console.error('Error sending histogram:', err);
});
};
module.exports = {
monitor,
sendCounter,
sendGauge,
sendHistogram,
closeConnection,
buildDatadogMonitoringEndpointsConfig
};