<commit_before>/* 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/. */

var EventEmitter = require('events').EventEmitter
var util = require('util')
var mozlog = require('mozlog')
var config = require('../config')
var logConfig = config.get('log')
var P = require('./promise')
var StatsDCollector = require('./metrics/statsd')

var ALWAYS_ACTIVITY_FLOW_EVENTS = {
  // These activity events are always flow events
  'account.confirmed': true,
  'account.created': true,
  'account.login': true,
  'account.verified': true
}

var ACTIVITY_FLOW_EVENTS = Object.keys(ALWAYS_ACTIVITY_FLOW_EVENTS)
  .reduce(function (events, event) {
    events[event] = true
    return events
  }, {
    // These activity events are flow events when there is a flowId
    'account.keyfetch': true,
    'account.signed': true,
    'device.created': true
  })

function unbuffer(object) {
  var keys = Object.keys(object)
  for (var i = 0; i < keys.length; i++) {
    var x = object[keys[i]]
    if (Buffer.isBuffer(x)) {
      object[keys[i]] = x.toString('hex')
    }
  }
  return object
}

function Lug(options) {
  EventEmitter.call(this)
  this.name = options.name || 'fxa-auth-server'
  mozlog.config({
    app: this.name,
    level: options.level,
    stream: options.stderr || process.stderr,
    fmt: options.fmt
  })
  this.logger = mozlog()

  this.stdout = options.stdout || process.stdout

  this.statsd = new StatsDCollector(this.logger)
  this.statsd.init()
}
util.inherits(Lug, EventEmitter)

Lug.prototype.close = function() {
  return this.statsd.close()
}

// Certain events can include contextual metrics data
// such as utm_* tracking parameters.  This helper method
// is here to work around a circular dependency between
// this module and the `metricsContext` module.
Lug.prototype.setMetricsContext = function (metricsContext) {
  this.metricsContext = metricsContext
}


// Expose the standard error/warn/info/debug/etc log methods.

Lug.prototype.trace = function (data) {
  this.logger.debug(data.op, data)
}

Lug.prototype.error = function (data) {
  // If the error object contains an email address,
  // lift it into top-level fields so that our
  // PII-scrubbing tool is able to find it.
  if (data.err && data.err.email) {
    if (!data.email) {
      data.email = data.err.email
    }
    data.err.email = null
  }
  this.logger.error(data.op, data)
}

Lug.prototype.fatal = function (data) {
  this.logger.critical(data.op, data)
}

Lug.prototype.warn = function (data) {
  this.logger.warn(data.op, data)
}

Lug.prototype.info = function (data) {
  this.logger.info(data.op, data)
}

Lug.prototype.begin = function (op, request) {
  this.logger.debug(op)
}

// Expose some statsd helpers directly on the logger object.

Lug.prototype.increment = function(event) {
  this.statsd.write({
    event: event
  })
}

Lug.prototype.stat = function (stats) {
  this.logger.info('stat', stats)
}

Lug.prototype.timing = function(name, timing, tags) {
  this.statsd.timing(name, timing, tags)
}

Lug.prototype.histogram = function(name, value, tags) {
  this.statsd.histogram(name, value, tags)
}


// Log a request summary line.
// This gets called once for each compelted request.
// See https://mana.mozilla.org/wiki/display/CLOUDSERVICES/Logging+Standard
// for a discussion of this format and why it's used.

Lug.prototype.summary = function (request, response) {
  if (request.method === 'options') { return }
  var payload = request.payload || {}
  var query = request.query || {}
  var line = {
    op: 'request.summary',
    code: (response.isBoom) ? response.output.statusCode : response.statusCode,
    errno: response.errno || 0,
    rid: request.id,
    path: request.path,
    lang: request.app.acceptLanguage,
    agent: request.headers['user-agent'],
    remoteAddressChain: request.app.remoteAddressChain,
    accountRecreated: request.app.accountRecreated,
    t: Date.now() - request.info.received
  }
  line.uid = (request.auth && request.auth.credentials) ?
    request.auth.credentials.uid :
    payload.uid || query.uid || response.uid || '00'<commit_msg>fix(logs): look in response.source for uid<commit_after>/* 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/. */

var EventEmitter = require('events').EventEmitter
var util = require('util')
var mozlog = require('mozlog')
var config = require('../config')
var logConfig = config.get('log')
var P = require('./promise')
var StatsDCollector = require('./metrics/statsd')

var ALWAYS_ACTIVITY_FLOW_EVENTS = {
  // These activity events are always flow events
  'account.confirmed': true,
  'account.created': true,
  'account.login': true,
  'account.verified': true
}

var ACTIVITY_FLOW_EVENTS = Object.keys(ALWAYS_ACTIVITY_FLOW_EVENTS)
  .reduce(function (events, event) {
    events[event] = true
    return events
  }, {
    // These activity events are flow events when there is a flowId
    'account.keyfetch': true,
    'account.signed': true,
    'device.created': true
  })

function unbuffer(object) {
  var keys = Object.keys(object)
  for (var i = 0; i < keys.length; i++) {
    var x = object[keys[i]]
    if (Buffer.isBuffer(x)) {
      object[keys[i]] = x.toString('hex')
    }
  }
  return object
}

function Lug(options) {
  EventEmitter.call(this)
  this.name = options.name || 'fxa-auth-server'
  mozlog.config({
    app: this.name,
    level: options.level,
    stream: options.stderr || process.stderr,
    fmt: options.fmt
  })
  this.logger = mozlog()

  this.stdout = options.stdout || process.stdout

  this.statsd = new StatsDCollector(this.logger)
  this.statsd.init()
}
util.inherits(Lug, EventEmitter)

Lug.prototype.close = function() {
  return this.statsd.close()
}

// Certain events can include contextual metrics data
// such as utm_* tracking parameters.  This helper method
// is here to work around a circular dependency between
// this module and the `metricsContext` module.
Lug.prototype.setMetricsContext = function (metricsContext) {
  this.metricsContext = metricsContext
}


// Expose the standard error/warn/info/debug/etc log methods.

Lug.prototype.trace = function (data) {
  this.logger.debug(data.op, data)
}

Lug.prototype.error = function (data) {
  // If the error object contains an email address,
  // lift it into top-level fields so that our
  // PII-scrubbing tool is able to find it.
  if (data.err && data.err.email) {
    if (!data.email) {
      data.email = data.err.email
    }
    data.err.email = null
  }
  this.logger.error(data.op, data)
}

Lug.prototype.fatal = function (data) {
  this.logger.critical(data.op, data)
}

Lug.prototype.warn = function (data) {
  this.logger.warn(data.op, data)
}

Lug.prototype.info = function (data) {
  this.logger.info(data.op, data)
}

Lug.prototype.begin = function (op, request) {
  this.logger.debug(op)
}

// Expose some statsd helpers directly on the logger object.

Lug.prototype.increment = function(event) {
  this.statsd.write({
    event: event
  })
}

Lug.prototype.stat = function (stats) {
  this.logger.info('stat', stats)
}

Lug.prototype.timing = function(name, timing, tags) {
  this.statsd.timing(name, timing, tags)
}

Lug.prototype.histogram = function(name, value, tags) {
  this.statsd.histogram(name, value, tags)
}


// Log a request summary line.
// This gets called once for each compelted request.
// See https://mana.mozilla.org/wiki/display/CLOUDSERVICES/Logging+Standard
// for a discussion of this format and why it's used.

Lug.prototype.summary = function (request, response) {
  if (request.method === 'options') { return }
  var payload = request.payload || {}
  var query = request.query || {}
  var line = {
    op: 'request.summary',
    code: (response.isBoom) ? response.output.statusCode : response.statusCode,
    errno: response.errno || 0,
    rid: request.id,
    path: request.path,
    lang: request.app.acceptLanguage,
    agent: request.headers['user-agent'],
    remoteAddressChain: request.app.remoteAddressChain,
    accountRecreated: request.app.accountRecreated,
    t: Date.now() - request.info.received
  }
  line.uid = (request.auth && request.auth.credentials) ?
    request.auth.credentials.uid :
    payload.uid || query.uid || response.uid ||
    (response.source && response.source.uid) || '00'
{'fraction_non_alphanumeric': 0.134293408266011, 'fraction_numerical': 0.0018733169418100925, 'mean_word_length': 3.5339702760084926, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2579255', 'n_tokens_mistral': 2815, 'n_tokens_neox': 2772, 'n_words': 728}