Module: NewRelic::Agent::Datastores::Mongo::MetricTranslator

Defined in:
lib/new_relic/agent/datastores/mongo/metric_translator.rb

Constant Summary collapse

NAMES_IN_SELECTOR =
[
  :findandmodify,

  'aggregate',
  'count',
  'group',
  'mapreduce',

  :distinct,

  :createIndexes,
  :deleteIndexes,
  :reIndex,

  :collstats,
  :renameCollection,
  :drop
]
CMD_COLLECTION =
'$cmd'.freeze

Class Method Summary collapse

Class Method Details

.collection_in_selector?(payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

60
61
62
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 60

def self.collection_in_selector?(payload)
  payload[:collection] == '$cmd' && payload[:selector]
end

.collection_name_from_group_selector(payload) ⇒ Object

[View source]

168
169
170
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 168

def self.collection_name_from_group_selector(payload)
  payload[:selector]['group']['ns']
end

.collection_name_from_index(payload) ⇒ Object

[View source]

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 150

def self.collection_name_from_index(payload)
  if payload[:documents]
    if payload[:documents].is_a?(Array)
      # mongo gem versions pre 1.10.0
      document = payload[:documents].first
    else
      # mongo gem versions 1.10.0 and later
      document = payload[:documents]
    end

    if document && document[:ns]
      return document[:ns].split('.').last
    end
  end

  'system.indexes'
end

.collection_name_from_rename_selector(payload) ⇒ Object

[View source]

172
173
174
175
176
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 172

def self.collection_name_from_rename_selector(payload)
  parts = payload[:selector][:renameCollection].split('.')
  parts.shift
  parts.join('.')
end

.command_key_from_selector(payload) ⇒ Object

[View source]

83
84
85
86
87
88
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 83

def self.command_key_from_selector(payload)
  selector = payload[:selector]
  NAMES_IN_SELECTOR.find do |check_name|
    selector.key?(check_name)
  end
end

.create_index?(name, payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

126
127
128
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 126

def self.create_index?(name, payload)
  name == :insert && payload[:collection] == 'system.indexes'
end

.create_indexes?(name, _payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

122
123
124
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 122

def self.create_indexes?(name, _payload)
  name == :createIndexes
end

.drop_index?(name, payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

134
135
136
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 134

def self.drop_index?(name, payload)
  name == :deleteIndexes
end

.drop_indexes?(name, payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

130
131
132
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 130

def self.drop_indexes?(name, payload)
  name == :deleteIndexes && payload[:selector] && payload[:selector][:index] == ASTERISK
end

.find_and_modify?(name, payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

114
115
116
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 114

def self.find_and_modify?(name, payload)
  name == :findandmodify
end

.find_and_remove?(name, payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

118
119
120
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 118

def self.find_and_remove?(name, payload)
  name == :findandmodify && payload[:selector] && payload[:selector][:remove]
end

.find_one?(name, payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

110
111
112
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 110

def self.find_one?(name, payload)
  name == :find && payload[:limit] == -1
end

.get_collection_from_selector(command_key, payload) ⇒ Object

[View source]

101
102
103
104
105
106
107
108
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 101

def self.get_collection_from_selector(command_key, payload)
  if command_key
    payload[:selector][command_key]
  else
    NewRelic::Agent.increment_metric('Supportability/Mongo/UnknownCollection')
    CMD_COLLECTION
  end
end

.get_name_from_selector(command_key, payload) ⇒ Object

[View source]

90
91
92
93
94
95
96
97
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 90

def self.get_name_from_selector(command_key, payload)
  if command_key
    command_key.to_sym
  else
    NewRelic::Agent.increment_metric('Supportability/Mongo/UnknownCollection')
    payload[:selector].first.first unless command_key
  end
end

.group?(name, payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

142
143
144
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 142

def self.group?(name, payload)
  name == :group
end

.operation_and_collection_for(name, payload) ⇒ Object

[View source]

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
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 13

def self.operation_and_collection_for(name, payload)
  payload ||= {}

  if collection_in_selector?(payload)
    command_key = command_key_from_selector(payload)
    name = get_name_from_selector(command_key, payload)
    collection = get_collection_from_selector(command_key, payload)
  else
    collection = payload[:collection]
  end

  # The 1.10.0 version of the mongo driver renamed 'remove' to
  # 'delete', but for metric consistency with previous versions we
  # want to keep it as 'remove'.
  name = 'remove' if name.to_s == 'delete'

  if self.find_one?(name, payload)
    name = 'findOne'
  elsif self.find_and_remove?(name, payload)
    name = 'findAndRemove'
  elsif self.find_and_modify?(name, payload)
    name = 'findAndModify'
  elsif self.create_indexes?(name, payload)
    name = 'createIndexes'
  elsif self.create_index?(name, payload)
    name = 'createIndex'
    collection = self.collection_name_from_index(payload)
  elsif self.drop_indexes?(name, payload)
    name = 'dropIndexes'
  elsif self.drop_index?(name, payload)
    name = 'dropIndex'
  elsif self.re_index?(name, payload)
    name = 'reIndex'
  elsif self.group?(name, payload)
    name = 'group'
    collection = collection_name_from_group_selector(payload)
  elsif self.rename_collection?(name, payload)
    name = 'renameCollection'
    collection = collection_name_from_rename_selector(payload)
  end

  [name.to_s, collection]
rescue => e
  NewRelic::Agent.logger.debug('Failure during Mongo metric generation', e)
  nil
end

.re_index?(name, payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

138
139
140
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 138

def self.re_index?(name, payload)
  name == :reIndex && payload[:selector] && payload[:selector][:reIndex]
end

.rename_collection?(name, payload) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

146
147
148
# File 'lib/new_relic/agent/datastores/mongo/metric_translator.rb', line 146

def self.rename_collection?(name, payload)
  name == :renameCollection
end