static getDetailedStats (req, res) {
    if (req.query.name === undefined) {
      return res.send('{}');
    }

    const nodeName = req.query.nodeName;

    const query = {
      query: {
        bool: {
          filter: [
            {
              range: { currentTime: { gte: req.query.start, lte: req.query.stop } }
            },
            {
              term: { interval: req.query.interval || 60 }
            }
          ]
        }
      }
    };

    if (nodeName !== undefined && nodeName !== 'Total' && nodeName !== 'Average') {
      query.sort = { currentTime: { order: 'desc' } };
      query.size = req.query.size || 1440;
      query.query.bool.filter.push({ term: { nodeName } });
    } else {
      query.size = 100000;
    }

    const mapping = {
      deltaBits: { _source: ['deltaBytes'], func: function (item) { return Math.floor(item.deltaBytes * 8.0); } },
      deltaTotalDropped: { _source: ['deltaDropped', 'deltaOverloadDropped'], func: function (item) { return Math.floor(item.deltaDropped + item.deltaOverloadDropped); } },
      deltaBytesPerSec: { _source: ['deltaBytes', 'deltaMS'], func: function (item) { return Math.floor(item.deltaBytes * 1000.0 / item.deltaMS); } },
      deltaBitsPerSec: { _source: ['deltaBytes', 'deltaMS'], func: function (item) { return Math.floor(item.deltaBytes * 1000.0 / item.deltaMS * 8); } },
      deltaWrittenBytesPerSec: { _source: ['deltaWrittenBytes', 'deltaMS'], func: function (item) { return Math.floor(item.deltaWrittenBytes * 1000.0 / item.deltaMS); } },
      deltaUnwrittenBytesPerSec: { _source: ['deltaUnwrittenBytes', 'deltaMS'], func: function (item) { return Math.floor(item.deltaUnwrittenBytes * 1000.0 / item.deltaMS); } },
      deltaPacketsPerSec: { _source: ['deltaPackets', 'deltaMS'], func: function (item) { return Math.floor(item.deltaPackets * 1000.0 / item.deltaMS); } },
      deltaSessionsPerSec: { _source: ['deltaSessions', 'deltaMS'], func: function (item) { return Math.floor(item.deltaSessions * 1000.0 / item.deltaMS); } },
      deltaSessionBytesPerSec: { _source: ['deltaSessionBytes', 'deltaMS'], func: function (item) { return Math.floor(item.deltaSessionBytes * 1000.0 / item.deltaMS); } },
      sessionSizePerSec: { _source: ['deltaSessionBytes', 'deltaSessions'], func: function (item) { return Math.floor(item.deltaSessionBytes / item.deltaSessions); } },
      deltaDroppedPerSec: { _source: ['deltaDropped', 'deltaMS'], func: function (item) { return Math.floor(item.deltaDropped * 1000.0 / item.deltaMS); } },
      deltaFragsDroppedPerSec: { _source: ['deltaFragsDropped', 'deltaMS'], func: function (item) { return Math.floor(item.deltaFragsDropped * 1000.0 / item.deltaMS); } },
      deltaOverloadDroppedPerSec: { _source: ['deltaOverloadDropped', 'deltaMS'], func: function (item) { return Math.floor(item.deltaOverloadDropped * 1000.0 / item.deltaMS); } },
      deltaESDroppedPerSec: { _source: ['deltaESDropped', 'deltaMS'], func: function (item) { return Math.floor(item.deltaESDropped * 1000.0 / item.deltaMS); } },
      deltaDupDroppedPerSec: { _source: ['deltaDupDropped', 'deltaMS'], func: function (item) { return Math.floor(item.deltaDupDropped * 1000.0 / item.deltaMS); } },
      deltaTotalDroppedPerSec: { _source: ['deltaDropped', 'deltaOverloadDropped', 'deltaMS'], func: function (item) { return Math.floor((item.deltaDropped + item.deltaOverloadDropped) * 1000.0 / item.deltaMS); } },
      cpu: { _source: ['cpu'], func: function (item) { return item.cpu * 0.01; } }
    };

    query._source = mapping[req.query.name] ? mapping[req.query.name]._source : [req.query.name];
    query._source.push('nodeName', 'currentTime');

    const func = mapping[req.query.name] ? mapping[req.query.name].func : function (item) { return item[req.query.name]; };

    Db.search('dstats', 'dstat', query, { filter_path: '_scroll_id,hits.total,hits.hits._source' }, (err, result) => {
      if (err || result.error) {
        console.log(`ERROR - ${req.method} /api/dstats`, query, util.inspect(err || result.error, false, 50));
      }

      let i, ilen;
      const data = {};
      const num = (req.query.stop - req.query.start) / req.query.step;

      let mult = 1;
      if (req.query.name === 'freeSpaceM' || req.query.name === 'usedSpaceM') {
        mult = 1000000;
      }

      if (Config.debug > 2) {
        console.log('/api/dstats result', util.inspect(result, false, 50));
      }

      if (result && result.hits && result.hits.hits) {
        for (i = 0, ilen = result.hits.hits.length; i < ilen; i++) {
          const fields = result.hits.hits[i]._source;
          const pos = Math.floor((fields.currentTime - req.query.start) / req.query.step);

          if (data[fields.nodeName] === undefined) {
            data[fields.nodeName] = ViewerUtils.arrayZeroFill(num);
          }
          data[fields.nodeName][pos] = mult * func(fields);
        }
      }

      if (nodeName === undefined) {
        res.send(data);
      } else {
        if (data[nodeName] === undefined) {
          data[nodeName] = ViewerUtils.arrayZeroFill(num);
        }
        if (nodeName === 'Total' || nodeName === 'Average') {
          delete data[nodeName];
          const data2 = ViewerUtils.arrayZeroFill(num);
          let cnt = 0;
          for (const key in data) {
            for (i = 0; i < num; i++) {
              data2[i] += data[key][i];
            }
            cnt++;
          }
          if (nodeName === 'Average') {
            for (i = 0; i < num; i++) {
              data2[i] /= cnt;
            }
          }
          res.send(data2);
        } else {
          res.send(data[req.query.nodeName]);
        }
      }
    });
  }
GET - /api/dstats

Fetches a list of detailed stats for different fields pertaining to a node to populate a cubism graph.
<a href="https://github.com/square/cubism">Cubism GitHub</a>
@name /dstats
@param {string} nodeName - The name of the node to get the detailed stats for.
@param {string} name - The name of the field to get the detailed stats for.
@param {number} start - The start time of data to return. Format is seconds since Unix EPOC.
@param {number} stop  - The stop time of data to return. Format is seconds since Unix EPOC.
@param {number} step - The context step of the cubism graph in milliseconds.
@param {number} interval=60 - The time interval to search for.
@param {number} size=1440 - The size of the cubism graph. Defaults to 1440.
@returns {array} List of values to populate the cubism graph.