Class: Wavefront::Cli::Events

Inherits:
Wavefront::Cli show all
Includes:
Wavefront::Constants, Mixins
Defined in:
lib/wavefront/cli/events.rb

Overview

in a timeseries API call.

Constant Summary

Constants included from Wavefront::Constants

Wavefront::Constants::ALERT_FORMATS, Wavefront::Constants::DASH_FORMATS, Wavefront::Constants::DEFAULT_ALERT_FORMAT, Wavefront::Constants::DEFAULT_DASH_FORMAT, Wavefront::Constants::DEFAULT_FORMAT, Wavefront::Constants::DEFAULT_HOST, Wavefront::Constants::DEFAULT_INFILE_FORMAT, Wavefront::Constants::DEFAULT_OBSOLETE_METRICS, Wavefront::Constants::DEFAULT_OPTS, Wavefront::Constants::DEFAULT_PERIOD_SECONDS, Wavefront::Constants::DEFAULT_PREFIX_LENGTH, Wavefront::Constants::DEFAULT_PROXY, Wavefront::Constants::DEFAULT_PROXY_PORT, Wavefront::Constants::DEFAULT_SOURCE_FORMAT, Wavefront::Constants::DEFAULT_STRICT, Wavefront::Constants::EVENT_LEVELS, Wavefront::Constants::EVENT_STATE_DIR, Wavefront::Constants::FORMATS, Wavefront::Constants::GRANULARITIES, Wavefront::Constants::SOURCE_FORMATS

Instance Attribute Summary collapse

Attributes inherited from Wavefront::Cli

#arguments, #noop, #options

Instance Method Summary collapse

Methods included from Mixins

#call_delete, #call_get, #call_post, #hash_to_qs, #interpolate_schema, #load_file, #parse_time, #time_to_ms, #uri_concat

Methods inherited from Wavefront::Cli

#initialize

Constructor Details

This class inherits a constructor from Wavefront::Cli

Instance Attribute Details

#hostnameObject

Returns the value of attribute hostname.



30
31
32
# File 'lib/wavefront/cli/events.rb', line 30

def hostname
  @hostname
end

#hostsObject

Returns the value of attribute hosts.



30
31
32
# File 'lib/wavefront/cli/events.rb', line 30

def hosts
  @hosts
end

#state_dirObject

Returns the value of attribute state_dir.



30
31
32
# File 'lib/wavefront/cli/events.rb', line 30

def state_dir
  @state_dir
end

#t_endObject

Returns the value of attribute t_end.



30
31
32
# File 'lib/wavefront/cli/events.rb', line 30

def t_end
  @t_end
end

#t_startObject

Returns the value of attribute t_start.



30
31
32
# File 'lib/wavefront/cli/events.rb', line 30

def t_start
  @t_start
end

#wf_eventObject

Returns the value of attribute wf_event.



30
31
32
# File 'lib/wavefront/cli/events.rb', line 30

def wf_event
  @wf_event
end

Instance Method Details

#close_event(ev_name, ts) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/wavefront/cli/events.rb', line 168

def close_event(ev_name, ts)
  puts "Closing event '#{ev_name}'. [#{Time.at(ts.to_i / 1000)}]"

  begin
    wf_event.close(
      s: ts,
      n: ev_name
    )
  rescue RestClient::Unauthorized
    raise 'Not authorized to connect to Wavefront.'
  rescue => e
    puts e
    raise
  end

  # Remove the state file, if there was one
  #
  state_file = state_filename(ev_name, ts)

  return unless state_file.exist?

  puts "Removing state file #{state_file}."
  File.unlink state_file
end

#close_event_handlerObject



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/wavefront/cli/events.rb', line 148

def close_event_handler
  #
  # The user can specify all, some, or none of the information
  # needed to close an event. If we have all of it, we can jump
  # straight to the API call. Otherwise, we have to go and look
  # for a state fuile
  #
  if options[:'<timestamp>'] && options[:'<event>']
    close_event(options[:'<event>'], options[:'<timestamp>'])
  else
    ev_file = pop_event(options[:'<event>'])

    if ev_file
      close_event(ev_file[1], ev_file[0])
    else
      fail "No event '#{options[:'<event>']}' to close."
    end
  end
end

#create_eventObject



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/wavefront/cli/events.rb', line 121

def create_event
  #
  # Make the API call and pass back the response.
  #
  req_obj = {
    n: options[:'<event>'],
    d: options[:desc],
    h: hosts,
    c: options[:instant],
    l: options[:level]
  }

  req_obj[:s] = t_start if t_start
  req_obj[:e] = t_end if t_end

  begin
    response = wf_event.create(req_obj)
  rescue RestClient::Unauthorized
    raise 'Cannot connect to Wavefront API'
  rescue => e
    puts e
    raise 'Cannot create event'
  end

  response
end

#create_event_handlerObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/wavefront/cli/events.rb', line 105

def create_event_handler
  #
  # Wrapper around the method calls which actually create events.
  #
  output = create_event

  return if noop

  unless options[:end] || options[:instant]
    create_state_dir
    create_state_file(output) unless options[:nostate]
  end

  puts JSON.pretty_generate(JSON.parse(output)) if options[:verbose]
end

#create_state_dirObject



227
228
229
230
231
232
# File 'lib/wavefront/cli/events.rb', line 227

def create_state_dir
  FileUtils.mkdir_p(state_dir)
  unless state_dir.exist? && state_dir.directory? && state_dir.writable?
    fail 'Cannot create state directory.'
  end
end

#create_state_file(response) ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/wavefront/cli/events.rb', line 241

def create_state_file(response)
  #
  # Write a state file. We put the hosts bound to the event into
  # the file. These aren't currently used by anything in the CLI,
  # but they might be useful to someone, somewhere, someday.
  #
  ts = JSON.parse(response)['startTime']
  fname = state_filename(options[:'<event>'], ts)

  begin
    File.open(fname, 'w') { hosts.to_s }
  rescue
    JSON.pretty_generate(JSON.parse(response))
    raise 'Event was created but state file was not.'
  end

  puts "Event state recorded at #{fname}."
end

#delete_eventObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/wavefront/cli/events.rb', line 66

def delete_event
  unless options[:'<timestamp>'] && options[:'<event>']
    fail 'To delete an event you must supply its start time and name.'
  end

  begin
    wf_event.delete(startTime: options[:'<timestamp>'],
                    name: options[:'<event>']
                   )
  rescue RestClient::Unauthorized
    raise 'Cannot connect to Wavefront API.'
  rescue RestClient::ResourceNotFound
    raise 'Cannot find that event.'
  rescue => e
    puts e
    raise 'Cannot delete event.'
  end

  puts 'Deleted event.' unless noop
end

#pop_event(name = false) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/wavefront/cli/events.rb', line 211

def pop_event(name = false)
  #
  # Get the last event this script created. If you supply a name,
  # you get the last event with that name. If not, you get the
  # last event. Chances are you'll only ever have one in-play at
  # once.
  #
  # Returns an array of [timestamp, event_name]
  #
  return false unless state_dir.exist?
  list = state_dir.children
  list.select! { |f| f.basename.to_s.split('::').last == name } if name
  return false if list.length == 0
  list.sort.last.basename.to_s.split('::')
end

#prep_hosts(hosts = false) ⇒ Object



95
96
97
98
99
100
101
102
103
# File 'lib/wavefront/cli/events.rb', line 95

def prep_hosts(hosts = false)
  #
  # We allow the user to associate an event with multiple hosts,
  # or to pass in some identifer other than the hostname. If they
  # have not done this, hostname is used
  #
  hosts = hostname unless hosts
  hosts.split(',')
end

#prep_time(t) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/wavefront/cli/events.rb', line 87

def prep_time(t)
  #
  # Wavefront would like times in epoch milliseconds, so whatever
  # we have got, turn them into that.
  #
  options[t] ? time_to_ms(parse_time(options[t])) : false
end

#runObject



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
# File 'lib/wavefront/cli/events.rb', line 36

def run
  begin
    @state_dir = EVENT_STATE_DIR + Etc.getlogin
  rescue
    @state_dir = EVENT_STATE_DIR + 'notty'
  end

  @hostname = Socket.gethostname
  @hosts = prep_hosts(options[:host])
  @t_start = prep_time(:start)
  @t_end = prep_time(:end)
  @noop = options[:noop]

  @wf_event = Wavefront::Events.new(
    options[:token], options[:endpoint], options[:debug],
    { verbose: options[:verbose], noop: options[:noop]})

  if options[:create]
    create_event_handler
  elsif options[:close]
    close_event_handler
  elsif options[:show]
    show_open_events
  elsif options[:delete]
    delete_event
  else
    fail 'undefined event error.'
  end
end

#show_open_eventsObject



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/wavefront/cli/events.rb', line 193

def show_open_events
  #
  # Everything we need to know about an event is in the name of
  # its state file.
  #
  begin
    events = state_dir.children
  rescue Errno::ENOENT
    raise 'There is no event state directory on this host.'
  end

  if events.length == 0
    puts 'No open events.'
  else
    events.each { |e| puts e.basename }
  end
end

#state_filename(ev_name, ts) ⇒ Object



234
235
236
237
238
239
# File 'lib/wavefront/cli/events.rb', line 234

def state_filename(ev_name, ts)
  #
  # Consistently generate event state file names
  #
  state_dir + [ts, ev_name].join('::')
end

#validate_optsObject



260
261
262
263
264
265
266
267
# File 'lib/wavefront/cli/events.rb', line 260

def validate_opts
  #
  # the 'show' sub-command does not make an API call
  #
  return true if options[:show]
  abort 'Please supply an API token.' unless options[:token]
  abort 'Please supply an API endpoint.' unless options[:endpoint]
end