catalint/bluestatsd

View on GitHub
src/statsd.js

Summary

Maintainability
A
1 hr
Test Coverage
'use strict';

const StatsdClient = require('statsd-client');
const Hoek = require('hoek');
const defaults = {
    statsdClient: null,
    host: 'localhost',
    port: '8125',
    prefix: 'hapi',
    pathSeparator: '_',
    dotReplacer: '-',
    template: '{path}.{method}.{statusCode}'
};

module.exports.register = function (server, options, next) {

    const settings = Hoek.applyToDefaults(defaults, options);
    const statsdClient = options.statsdClient || new StatsdClient(settings);
    const normalizePath = (path) => {

        path =  path.substr(1); // trim starting / ,
        return path.replace(/\//g, settings.pathSeparator).replace(/\./g, settings.dotReplacer);
    };

    server.decorate('server', 'statsd', statsdClient);

    server.ext('onPreResponse', (request, reply) => {

        const startDate = new Date(request.info.received);
        const statusCode = (request.response.isBoom) ? request.response.output.statusCode : request.response.statusCode;

        let path = request._route.path;
        const specials = request.connection._router.specials;

        if (request._route === specials.notFound.route) {
            path = '/{notFound*}';
        }
        else if (request._route === specials.options.route) {
            path = '/{cors*}';
        }
        else if (request._route.path === '/' && request._route.method === 'options') {
            path = '/{cors*}';
        }

        let statName = settings.template
            .replace('{path}', normalizePath(path))
            .replace('{method}', request.method.toUpperCase())
            .replace('{statusCode}', statusCode);

        statName = (statName.indexOf('.') === 0) ? statName.substr(1) : statName;
        statsdClient.increment(statName);
        statsdClient.timing(statName, startDate);
        reply.continue();
    });

    next();
};

module.exports.register.attributes = {
    pkg: require('../package.json')
};