All files / src metrics.coffee

21.43% Statements 3/14
0% Branches 0/7
0% Functions 0/2
21.43% Lines 3/14
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 1241x 1x                                                                                                                       1x                                                                                                                            
Transaction = require('./model/transactions').Transaction
logger = require 'winston'
 
# Calculates transaction metrics
#
# @startDate {Date} a timestamp representing the start of the range to calculate
#                   metrics from (required)
# @startDate {Date} a timestamp representing the end of the range to calculate
#                   metrics to (required)
# @transactionFilter {Object} a mongodb filter object to further restrict the
#                             transactions collection (nullable)
# @channelIDs {Array} an array of channel IDs as `ObjectID`s to filter by, if
#                     not set all channels will be considered (nullable)
# @timeSeries {String} one of 'minute', 'hour', 'day', 'week', 'month', 'year'.
#                      If set the metrics will be grouped into a periods of the
#                      stated duration, otherwise, metrics for the entire period
#                      will be returned (nullable)
# @groupByChannel {Boolean} if true the metrics will be grouped by each
#                           particular channel that returns results (nullable)
# @returns {Promise} that resolves to an array of metric objects for each
#                    grouping (timeseries and/or channel) depending on the
#                    parameters that are set
# e.g. metrics.calculateMetrics new Date("2014-07-15T00:00:00.000Z"),
# new Date("2014-07-19T00:00:00.000Z"), null, null, 'day', true
# [
#   {
#     _id: {
#       channelID: 111111111111111111111111,
#       day: 18,
#       week: 28,
#       month: 7,
#       year: 2014
#     },
#     total: 1,
#     avgResp: 100,
#     minResp: 100,
#     maxResp: 100,
#     failed: 0,
#     successful: 0,
#     processing: 1,
#     completed: 0,
#     completedWErrors: 0
#   }, {
#     _id:
#       {
#         channelID: 222222222222222222222222,
#         day: 18,
#         week: 28,
#         month: 7,
#         year: 2014 },
#     total: 1,
#     avgResp: 200,
#     minResp: 200,
#     maxResp: 200,
#     failed: 0,
#     successful: 0,
#     processing: 0,
#     completed: 1,
#     completedWErrors: 0
#   }
# ]
exports.calculateMetrics = (startDate, endDate, transactionFilter, channelIDs, timeSeries, groupByChannels) ->
  if not (startDate instanceof Date) or not (endDate instanceof Date)
    return new Promise (resolve, reject) ->
      reject new Error 'startDate and endDate must be provided and be of type Date'
 
  match =
    "request.timestamp":
      $lt: endDate
      $gt: startDate
  if transactionFilter
    Object.assign match, transactionFilter
 
  if channelIDs
    match.channelID =
      $in: channelIDs
 
  group =
    _id: {}
    total: $sum: 1
    avgResp: $avg: $subtract: [ "$response.timestamp", "$request.timestamp" ]
    minResp: $min: $subtract: [ "$response.timestamp", "$request.timestamp" ]
    maxResp: $max: $subtract: [ "$response.timestamp", "$request.timestamp" ]
    failed: $sum: $cond: [ $eq: [ "$status", "Failed" ], 1, 0 ]
    successful: $sum: $cond: [ $eq: [ "$status", "Successful" ], 1, 0 ]
    processing: $sum: $cond: [ $eq: [ "$status", "Processing" ], 1, 0 ]
    completed: $sum: $cond: [ $eq: [ "$status", "Completed" ], 1, 0 ]
    completedWErrors: $sum: $cond: [ $eq: [ "$status", "Completed with error(s)" ], 1, 0 ]
  if groupByChannels
    group._id.channelID = '$channelID'
 
  if timeSeries
    switch timeSeries
      when "minute"
        group._id.minute = $minute: "$request.timestamp"
        group._id.hour = $hour: "$request.timestamp"
        group._id.day = $dayOfMonth: "$request.timestamp"
        group._id.week = $week: "$request.timestamp"
        group._id.month = $month: "$request.timestamp"
        group._id.year = $year: "$request.timestamp"
      when "hour"
        group._id.hour = $hour: "$request.timestamp"
        group._id.week = $week: "$request.timestamp"
        group._id.day = $dayOfMonth: "$request.timestamp"
        group._id.month = $month: "$request.timestamp"
        group._id.year = $year: "$request.timestamp"
      when "day"
        group._id.day = $dayOfMonth: "$request.timestamp"
        group._id.week = $week: "$request.timestamp"
        group._id.month = $month: "$request.timestamp"
        group._id.year = $year: "$request.timestamp"
      when "week"
        group._id.week = $week: "$request.timestamp"
        group._id.month = $month: "$request.timestamp"
        group._id.year = $year: "$request.timestamp"
      when "month"
        group._id.month = $month: "$request.timestamp"
        group._id.year = $year: "$request.timestamp"
      when "year"
        group._id.year = $year: "$request.timestamp"
 
  pipeline = [ { $match: match }, { $group: group } ]
  return Transaction.aggregate(pipeline).exec()