Skip to content
Snippets Groups Projects
metrics.js 3.33 KiB
Newer Older
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 * The metrics module is designed to report interesting events to a file.
 * Metrics files from different production servers can then be aggregated
 * and post processed to get an idea of the degree and ways that browserid is
 * being used by the world, to facilitate capacity planning and changes
 * to the software.
 *
 * NOTE: This is *not* a generic logging mechanism for low level events
 * interesting only to debug or assess the health of a server.
 *
 * DOUBLE NOTE: Sensitive information shouldn't be
 * reported through this mechanism, and it isn't necesary to do so given
 * we're after general trends, not specifics.
 */

const
winston = require("winston"),
configuration = require("./configuration"),
fs = require('fs'),
urlparse = require('urlparse');
// existsSync moved from path in 0.6.x to fs in 0.8.x
if (typeof fs.existsSync === 'function') {
  var existsSync = fs.existsSync;
} else {
  var existsSync = path.existsSync;
}

// go through the configuration and determine log location
// for now we only log to one place
// FIXME: separate logs depending on purpose?

var log_path = path.join(configuration.get('var_path'), 'log');
// simple inline function for creation of dirs
function mkdir_p(p) {
function setupLogger() {
  // don't create the logger if it already exists
  if (LOGGER) return;

  if (!log_path)
    return console.log("no log path! Not logging!");
  var filename = path.join(log_path, configuration.get('process_type') + "-metrics.json");
  if (process.env.METRICS_LOG_FILE) {
    filename = process.env.METRICS_LOG_FILE;
  }
      transports: [new (winston.transports.File)({filename: filename})],
      timestamp: function () { return new Date().toISOString() },
    });
}

// entry is an object that will get JSON'ified
exports.report = function(type, entry) {
  // setup the logger if need be
  // allow convenient reporting of atoms by converting
  // atoms into objects
  if (entry === null || typeof entry !== 'object') entry = { msg: entry };
  if (entry.type) throw "reported metrics may not have a `type` property, that's reserved";
  entry.type = type;

  // timestamp
  if (entry.at) throw "reported metrics may not have an `at` property, that's reserved";
  entry.at = new Date().toUTCString();
  // if no logger, go to console (FIXME: do we really want to log to console?)
// utility function to log a bunch of stuff at user entry point
  var ipAddress = req.connection.remoteAddress;
  if (req.headers['x-real-ip']) ipAddress = req.headers['x-real-ip'];

  var referer = null;
  try {
    // don't log more than we need
    referer = urlparse(req.headers['referer']).originOnly().toString();
  } catch(e) {
    // ignore malformed referrers.  just log null
  }

    // IP address (this probably needs to be replaced with the X-forwarded-for value