fluent-plugin-spectrum 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2d4288f068c625207769f4fa29e28d38f942ad83
4
- data.tar.gz: fb7cbc18c897472e626cea9320d0680cfc2de45d
3
+ metadata.gz: b6ce4a6b4bf074348bde00e83c87e8559e07549c
4
+ data.tar.gz: cf2079f18bffc80dee8fe1c547d26460ff2a862e
5
5
  SHA512:
6
- metadata.gz: 52fa80683e053aea5ae9cbc7a4575a6c7076fa72f01ebc6f650028e0ee36cc908cf6f7119c975de14f8099b4a5d50f11877ea6a726795b728dc27525851cf56c
7
- data.tar.gz: 270493f647b3fa8d156941e27772b2f9f3662b8eb91f4c256edea218e72b5c1db04e54189b474884afa15505de36136ddc534f8ed11704aab8da8908fc8ff365
6
+ metadata.gz: dde69f607871058aa60138bd5a177323a0e0fac45ff6b62c0f13ef74699a5b948974161759b1417609abf02f0e01fc16bb26c5da60971da4dcbc85e6909c83dd
7
+ data.tar.gz: 656594019157e6a2555673e9d61094d89a420533c7fca7b1c0d6b909d5e669701edd895618c0b75e47af5c2c5438504dcab801101bbb0486dde1d14578aab052
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.0.0-p451
5
+ - 2.1.0
6
+
7
+ gemfile:
8
+ - Gemfile
9
+
10
+ branches:
11
+ only:
12
+ - master
13
+
14
+ script: bundle exec rake test
data/README.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  fluent-plugin-spectrum is an input plug-in for [Fluentd](http://fluentd.org)
4
4
 
5
+ ## Status
6
+ [![Gem Version](https://badge.fury.io/rb/fluent-plugin-spectrum.png)](http://badge.fury.io/rb/fluent-plugin-spectrum)
7
+ [![Build Status](https://travis-ci.org/Bigel0w/fluent-plugin-spectrum.png?branch=master)](https://travis-ci.org/Bigel0w/fluent-plugin-spectrum)
8
+ [![Coverage Status](https://coveralls.io/repos/Bigel0w/fluent-plugin-spectrum/badge.png?branch=master)](https://coveralls.io/r/Bigel0w/fluent-plugin-spectrum?branch=master)
9
+
5
10
  ## Installation
6
11
 
7
12
  These instructions assume you already have fluentd installed.
@@ -77,9 +82,16 @@ Now startup fluentd
77
82
 
78
83
  $ sudo fluentd -c fluent.conf &
79
84
 
80
- Send a test
85
+ Verify:
86
+
87
+ You should see output like the following if you have events in spectrum and connectivity works.
88
+
89
+ FluentD Log Lines:
90
+ 2015-03-05 15:04:02 -0800 [info]: Spectrum :: Polling alerts for time period: 1425596639 - 1425596642
91
+ 2015-03-05 15:04:07 -0800 [info]: Spectrum :: returned 1 alarms for period 1425596639 - 1425596647
81
92
 
82
- TBD: Still need to create an example
93
+ Output:
94
+ 2015-03-05 15:04:00 -0800 alert.spectrum: {"event_type":"alert.spectrum","intermediary_source":"spectrumapi001.corp.yourdomain.net","ALARM_ID":"54f8e0e0-e706-12c2-0165-005056a07ac5","CREATION_DATE":"1425596640","SEVERITY":"3","ALARM_TITLE":"LOGMATCH TRAPSEND CRIT","HOSTNAME":"yourhost001.corp.yourdomain.net","IP_ADDRESS":"10.10.0.14","ORIGINATING_EVENT_ATTR":"A SEC logmatch trapsend CRIT Your Alert Message here","MODEL_STRING":"Host_Device","ACKNOWLEDGED":"false","ALARM_STATUS":"","OCCURRENCES":"1","TROUBLE_SHOOTER":"","USER_CLEARABLE":"true","TROUBLE_TICKET_ID":"","PERSISTENT":"true","GC_NAME":"Your_Global_Collection"}
83
95
 
84
96
  ## To Do
85
97
  * Add retry login. On timeout/failure retry, how often, increasing delay? (how would that affect polling time, possible duplicates?)
@@ -3,12 +3,12 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
5
  gem.name = "fluent-plugin-spectrum"
6
- gem.version = "0.0.3"
7
- gem.date = '2015-02-24'
6
+ gem.version = "0.0.5"
7
+ gem.date = '2015-03-31'
8
8
  gem.authors = ["Alex Pena"]
9
- gem.email = ["alex_pena@intuit.com"]
10
- gem.summary = %q{Fluentd input plugin for Spectrum Alerts}
11
- gem.description = %q{Fluentd plugin for Spectrum Alerts... WIP}
9
+ gem.email = ["pena.alex@gmail.com"]
10
+ gem.summary = %q{Fluentd input plugin for pulling alerts from CA Spectrum}
11
+ gem.description = %q{Fluentd plugin for pulling monitoring alerts from CA Spectrum}
12
12
  gem.homepage = 'https://github.com/Bigel0w/fluent-plugin-spectrum'
13
13
  gem.license = 'MIT'
14
14
 
@@ -1,27 +1,72 @@
1
1
  module Fluent
2
- # TODO:
3
- # Add a fields all or list option
4
- # error checking in every section
5
- # class for handling interval in loop
6
- class TimerWatcher < Coolio::TimerWatcher
7
- def initialize(interval, repeat, &callback)
8
- @callback = callback
9
- super(interval, repeat)
10
- end # def initialize
11
- def on_timer
12
- @callback.call
13
- end # def on_timer
14
- end
15
-
16
2
  class SpectrumInput < Input
17
3
  Fluent::Plugin.register_input('spectrum', self)
18
4
  config_param :tag, :string, :default => "alert.spectrum"
19
- config_param :endpoint, :string, :default => "pleasechangeme.com" #fqdn of endpoint
20
- config_param :interval, :integer, :default => '300' #Default 5 minutes
21
- config_param :user, :string, :default => "username"
22
- config_param :pass, :string, :default => "password"
23
- config_param :include_raw, :string, :default => "false" #Include original object as raw
24
- config_param :attributes, :string, :default => "ALL" # fields to include, ALL for... well, ALL.
5
+ config_param :endpoint, :string, :default => nil
6
+ config_param :username, :string, :default => nil
7
+ config_param :password, :string, :default => nil
8
+ config_param :interval, :integer, :default => 300 # shoud stay above 10, avg response is 5-7 seconds
9
+
10
+ config_param :state_file, :string, :default => nil
11
+ config_param :include_raw, :string, :default => "false"
12
+ config_param :attributes, :string, :default => "ALL"
13
+ config_param :select_limit, :time, :default => 10000
14
+
15
+ # Classes
16
+ class TimerWatcher < Coolio::TimerWatcher
17
+ def initialize(interval, repeat, &callback)
18
+ @callback = callback
19
+ super(interval, repeat)
20
+ end # def initialize
21
+
22
+ def on_timer
23
+ @callback.call
24
+ rescue
25
+ $log.error $!.to_s
26
+ $log.error_backtrace
27
+ end # def on_timer
28
+ end
29
+
30
+ class StateStore
31
+ def initialize(path)
32
+ require 'yaml'
33
+ @path = path
34
+ if File.exists?(@path)
35
+ @data = YAML.load_file(@path)
36
+ if @data == false || @data == []
37
+ # this happens if an users created an empty file accidentally
38
+ @data = {}
39
+ elsif !@data.is_a?(Hash)
40
+ raise "state_file on #{@path.inspect} is invalid"
41
+ end
42
+ else
43
+ @data = {}
44
+ end
45
+ end
46
+
47
+ def last_records
48
+ @data['last_records'] ||= {}
49
+ end
50
+
51
+ def update!
52
+ File.open(@path, 'w') {|f|
53
+ f.write YAML.dump(@data)
54
+ }
55
+ end
56
+ end
57
+
58
+ class MemoryStateStore
59
+ def initialize
60
+ @data = {}
61
+ end
62
+
63
+ def last_records
64
+ @data['last_records'] ||= {}
65
+ end
66
+
67
+ def update!
68
+ end
69
+ end
25
70
 
26
71
  # function to UTF8 encode
27
72
  def to_utf8(str)
@@ -45,6 +90,11 @@ module Fluent
45
90
  def configure(conf)
46
91
  super
47
92
  @conf = conf
93
+
94
+ unless @state_file
95
+ $log.warn "'state_file PATH' parameter is not set to a valid source."
96
+ $log.warn "this parameter is highly recommended to save the last known good timestamp to resume event consuming"
97
+ end
48
98
  # map of Spectrum attribute codes to names
49
99
  @spectrum_access_code={
50
100
  "0x11f9c" => "ALARM_ID",
@@ -64,7 +114,6 @@ module Fluent
64
114
  "0x12942" => "PERSISTENT",
65
115
  "0x12adb" => "GC_NAME",
66
116
  "0x57f0105" => "Custom_Project",
67
- "0x11f4d" => "ACKNOWLEDGED",
68
117
  #{}"0x11f51" => "CLEARED_BY_USER_NAME",
69
118
  #{}"0x11f52" => "EVENT_ID_LIST",
70
119
  #{}"0x11f53" => "MODEL_HANDLE",
@@ -95,78 +144,124 @@ module Fluent
95
144
  @spectrum_access_code.each do |key, array|
96
145
  @attr_of_interest += " <rs:requested-attribute id=\"#{key}\"/>"
97
146
  end
147
+
98
148
  # Setup URL Resource
99
- @url = 'http://' + @endpoint.to_s + '/spectrum/restful/alarms'
100
- def spectrumEnd
101
- RestClient::Resource.new(@url,@user,@pass)
149
+ def resource
150
+ @url = 'http://' + @endpoint.to_s + '/spectrum/restful/alarms'
151
+ RestClient::Resource.new(@url, :user => @username, :password => @password, :open_timeout => 3, :timeout => (@interval * 2))
102
152
  end
153
+
154
+ ### need to add this but first figure out how to pass a one time override for timeout since get takes a longtime to return
155
+ #test = resource.get
156
+ #if test.code.to_s == 200
157
+ # $log.info "Spectrum :: Config testing #{@endpoint} succeeded with #{test.code.to_s} response code"
158
+ #else
159
+ # raise Fluent::ConfigError, "http test failed"
160
+ #end
103
161
  end # def configure
104
162
 
105
- def start
106
- super
163
+ def start
164
+ @stop_flag = false
165
+ @state_store = @state_file.nil? ? MemoryStateStore.new : StateStore.new(@state_file)
107
166
  @loop = Coolio::Loop.new
108
- timer_trigger = TimerWatcher.new(@interval, true, &method(:input))
109
- timer_trigger.attach(@loop)
167
+ @loop.attach(TimerWatcher.new(@interval, true, &method(:on_timer)))
110
168
  @thread = Thread.new(&method(:run))
111
- $log.info "Spectrum :: starting poller, endpoint #{@endpoint} interval #{@interval}"
112
169
  end # def start
113
170
 
114
171
  def shutdown
115
- super
172
+ #@loop.watchers.each {|w| w.detach}
173
+ @stop_flag = true
116
174
  @loop.stop
117
175
  @thread.join
118
- rescue
119
- $log.error "Spectrum :: unexpected error", :error=>$!.to_s
120
- $log.error_backtrace
121
176
  end # def shutdown
122
177
 
123
178
  def run
124
179
  @loop.run
125
180
  rescue
126
- $log.error "Spectrum :: unexpected error", :error=>$!.to_s
127
- $log.error_backtrace
181
+ $log.error "unexpected error", :error=>$!.to_s
182
+ $log.error_backtrace
128
183
  end # def run
129
184
 
130
- def input
131
- alertStartTime = Engine.now.to_i - @interval.to_i
132
- $log.info "Spectrum :: Polling alerts for time period: #{alertStartTime.to_i} - #{Engine.now.to_i}"
133
-
134
- # Format XML for spectrum post
135
- @xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
136
- <rs:alarm-request throttlesize=\"10000\"
137
- xmlns:rs=\"http://www.ca.com/spectrum/restful/schema/request\"
138
- xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
139
- xsi:schemaLocation=\"http://www.ca.com/spectrum/restful/schema/request ../../../xsd/Request.xsd \">
140
- <rs:attribute-filter>
141
- <search-criteria xmlns=\"http://www.ca.com/spectrum/restful/schema/filter\">
142
- <filtered-models>
143
- <greater-than>
144
- <attribute id=\"0x11f4e\">
145
- <value> #{alertStartTime} </value>
146
- </attribute>
147
- </greater-than>
148
- </filtered-models>
149
- </search-criteria>
150
- </rs:attribute-filter>
151
- #{@attr_of_interest}
152
- </rs:alarm-request>"
153
-
154
- # Post to Spectrum and parse results
155
- responsePost=spectrumEnd.post @xml,:content_type => 'application/xml',:accept => 'application/json'
156
- body = JSON.parse(responsePost.body)
157
-
158
- # Processing for multiple alerts returned
159
- if body['ns1.alarm-response-list']['@total-alarms'].to_i > 1
160
- $log.info "Spectrum :: returned #{body['ns1.alarm-response-list']['@total-alarms'].to_i} alarms for period #{alertStartTime.to_i} - #{Engine.now.to_i}"
161
- # iterate through each alarm
162
- body['ns1.alarm-response-list']['ns1.alarm-responses']['ns1.alarm'].each do |alarm|
185
+ def on_timer
186
+ if not @stop_flag
187
+ pollingStart = Engine.now.to_i
188
+ if @state_store.last_records.has_key?("spectrum")
189
+ alertStartTime = @state_store.last_records['spectrum']
190
+ #$log.info "Spectrum :: Got time record from state_store - #{alertStartTime}"
191
+ else
192
+ alertStartTime = (pollingStart.to_i - @interval.to_i)
193
+ #$log.info "Spectrum :: Got time record from initial config - #{alertStartTime}"
194
+ end
195
+ pollingEnd = ''
196
+ pollingDuration = ''
197
+ #$log.info "Spectrum :: Polling alerts for time period < #{alertStartTime.to_i}"
198
+
199
+ # Format XML for spectrum post
200
+ @xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
201
+ <rs:alarm-request throttlesize=\"#{select_limit}\"
202
+ xmlns:rs=\"http://www.ca.com/spectrum/restful/schema/request\"
203
+ xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
204
+ xsi:schemaLocation=\"http://www.ca.com/spectrum/restful/schema/request ../../../xsd/Request.xsd \">
205
+ <rs:attribute-filter>
206
+ <search-criteria xmlns=\"http://www.ca.com/spectrum/restful/schema/filter\">
207
+ <filtered-models>
208
+ <greater-than>
209
+ <attribute id=\"0x11f4e\">
210
+ <value> #{alertStartTime} </value>
211
+ </attribute>
212
+ </greater-than>
213
+ </filtered-models>
214
+ </search-criteria>
215
+ </rs:attribute-filter>
216
+ #{@attr_of_interest}
217
+ </rs:alarm-request>"
218
+
219
+ # Post to Spectrum and parse results
220
+ begin
221
+ res=resource.post @xml,:content_type => 'application/xml',:accept => 'application/json'
222
+ #$log.info "Response code #{res.code.to_s}"
223
+ body = JSON.parse(res.body)
224
+ pollingEnd = Engine.now.to_i
225
+ @state_store.last_records['spectrum'] = pollingEnd
226
+ pollingDuration = pollingEnd - pollingStart
227
+ end
228
+
229
+ # Processing for multiple alerts returned
230
+ if body['ns1.alarm-response-list']['@total-alarms'].to_i > 1
231
+ $log.info "Spectrum :: returned #{body['ns1.alarm-response-list']['@total-alarms'].to_i} alarms for period < #{alertStartTime.to_i} took #{pollingDuration.to_i} seconds, ended at #{pollingEnd}"
232
+ # iterate through each alarm
233
+ body['ns1.alarm-response-list']['ns1.alarm-responses']['ns1.alarm'].each do |alarm|
234
+ # Create initial structure
235
+ record_hash = Hash.new # temp hash to hold attributes of alarm
236
+ raw_array = Array.new # temp hash to hold attributes of alarm for raw
237
+ record_hash['event_type'] = @tag.to_s
238
+ record_hash['intermediary_source'] = @endpoint.to_s
239
+ record_hash['recieved_time_input'] = pollingEnd.to_s
240
+ # iterate though alarm attributes
241
+ alarm['ns1.attribute'].each do |attribute|
242
+ key,value = parseAttributes(attribute)
243
+ record_hash[key] = value
244
+ if @include_raw.to_s == "true"
245
+ raw_array << { "#{key}" => "#{value}" }
246
+ end
247
+ end
248
+ # append raw object
249
+ if @include_raw.to_s == "true"
250
+ record_hash[:raw] = raw_array
251
+ end
252
+ Engine.emit(@tag, record_hash['CREATION_DATE'].to_i,record_hash)
253
+ end
254
+ # Processing for single alarm returned
255
+ elsif body['ns1.alarm-response-list']['@total-alarms'].to_i == 1
256
+ $log.info "Spectrum :: returned #{body['ns1.alarm-response-list']['@total-alarms'].to_i} alarms for period < #{alertStartTime.to_i} took #{pollingDuration.to_i} seconds, ended at #{pollingEnd}"
163
257
  # Create initial structure
164
258
  record_hash = Hash.new # temp hash to hold attributes of alarm
165
259
  raw_array = Array.new # temp hash to hold attributes of alarm for raw
166
260
  record_hash['event_type'] = @tag.to_s
167
261
  record_hash['intermediary_source'] = @endpoint.to_s
168
- # iterate though alarm attributes
169
- alarm['ns1.attribute'].each do |attribute|
262
+ record_hash['recieved_time_input'] = pollingEnd.to_s
263
+ # iterate though alarm attributes and add to temp hash
264
+ body['ns1.alarm-response-list']['ns1.alarm-responses']['ns1.alarm']['ns1.attribute'].each do |attribute|
170
265
  key,value = parseAttributes(attribute)
171
266
  record_hash[key] = value
172
267
  if @include_raw.to_s == "true"
@@ -178,33 +273,14 @@ module Fluent
178
273
  record_hash[:raw] = raw_array
179
274
  end
180
275
  Engine.emit(@tag, record_hash['CREATION_DATE'].to_i,record_hash)
276
+ # No alarms returned
277
+ else
278
+ $log.info "Spectrum :: returned #{body['ns1.alarm-response-list']['@total-alarms'].to_i} alarms for period < #{alertStartTime.to_i} took #{pollingDuration.to_i} seconds, ended at #{pollingEnd}"
181
279
  end
182
- # Processing for single alarm returned
183
- elsif body['ns1.alarm-response-list']['@total-alarms'].to_i == 1
184
- $log.info "Spectrum :: returned #{body['ns1.alarm-response-list']['@total-alarms'].to_i} alarms for period #{alertStartTime.to_i} - #{Engine.now.to_i}"
185
- # Create initial structure
186
- record_hash = Hash.new # temp hash to hold attributes of alarm
187
- raw_array = Array.new # temp hash to hold attributes of alarm for raw
188
- record_hash['event_type'] = @tag.to_s
189
- record_hash['intermediary_source'] = @endpoint.to_s
190
- # iterate though alarm attributes and add to temp hash
191
- body['ns1.alarm-response-list']['ns1.alarm-responses']['ns1.alarm']['ns1.attribute'].each do |attribute|
192
- key,value = parseAttributes(attribute)
193
- record_hash[key] = value
194
- if @include_raw.to_s == "true"
195
- raw_array << { "#{key}" => "#{value}" }
196
- end
197
- end
198
- # append raw object
199
- if @include_raw.to_s == "true"
200
- record_hash[:raw] = raw_array
201
- end
202
- Engine.emit(@tag, record_hash['CREATION_DATE'].to_i,record_hash)
203
- # No alarms returned
204
- else
205
- $log.info "Spectrum :: returned #{body['ns1.alarm-response-list']['@total-alarms'].to_i} alarms for period #{alertStartTime.to_i} - #{Engine.now.to_i}"
206
- end
207
-
280
+ @state_store.update!
281
+ #return
282
+ #exit
283
+ end
208
284
  end # def input
209
285
  end # class SpectrumInput
210
286
  end # module Fluent
@@ -0,0 +1,193 @@
1
+ module Fluent
2
+ class SpectrumOut < Output
3
+ # First, register the plugin. NAME is the name of this plugin
4
+ # and identifies the plugin in the configuration file.
5
+ Fluent::Plugin.register_output('spectrum', self)
6
+
7
+ config_param :tag, :string, default:'alert.spectrum.out'
8
+ #config_param :tag, :string, :default => "alert.spectrum"
9
+ config_param :endpoint, :string, :default => "pleasechangeme.com" #fqdn of endpoint
10
+ config_param :interval, :integer, :default => '300' #Default 5 minutes
11
+ config_param :user, :string, :default => "username"
12
+ config_param :pass, :string, :default => "password"
13
+ config_param :include_raw, :string, :default => "false" #Include original object as raw
14
+ config_param :attributes, :string, :default => "ALL" # fields to include, ALL for... well, ALL.
15
+
16
+ def parseAttributes(alarmAttribute)
17
+ key = @spectrum_access_code[alarmAttribute['@id'].to_s].to_s
18
+ value = ((to_utf8(alarmAttribute['$'].to_s)).strip).gsub(/\r?\n/, " ")
19
+ return key,value
20
+ end
21
+
22
+ def initialize
23
+ require 'rest-client'
24
+ require 'json'
25
+ require 'pp'
26
+ require 'cgi'
27
+ super
28
+ end # def initialize
29
+
30
+
31
+ # This method is called before starting.
32
+ def configure(conf)
33
+ super
34
+ # Read property file and create a hash
35
+ @rename_rules = []
36
+ conf_rename_rules = conf.keys.select { |k| k =~ /^rename_rule(\d+)$/ }
37
+ conf_rename_rules.sort_by { |r| r.sub('rename_rule', '').to_i }.each do |r|
38
+ key_regexp, new_key = parse_rename_rule conf[r]
39
+
40
+ if key_regexp.nil? || new_key.nil?
41
+ raise Fluent::ConfigError, "Failed to parse: #{r} #{conf[r]}"
42
+ end
43
+
44
+ if @rename_rules.map { |r| r[:key_regexp] }.include? /#{key_regexp}/
45
+ raise Fluent::ConfigError, "Duplicated rules for key #{key_regexp}: #{@rename_rules}"
46
+ end
47
+
48
+ #@rename_rules << { key_regexp: /#{key_regexp}/, new_key: new_key }
49
+ @rename_rules << { key_regexp: key_regexp, new_key: new_key }
50
+ $log.info "Added rename key rule: #{r} #{@rename_rules.last}"
51
+ end
52
+
53
+ raise Fluent::ConfigError, "No rename rules are given" if @rename_rules.empty?
54
+ @conf = conf
55
+ # map of Spectrum attribute codes to names
56
+ @spectrum_access_code={
57
+ "0x11f9c" => "ALARM_ID",
58
+ "0x11f4e" => "CREATION_DATE",
59
+ "0x11f56" => "SEVERITY",
60
+ "0x12b4c" => "ALARM_TITLE",
61
+ "0x1006e" => "HOSTNAME",
62
+ "0x12d7f" => "IP_ADDRESS",
63
+ "0x1296e" => "ORIGINATING_EVENT_ATTR",
64
+ "0x10000" => "MODEL_STRING",
65
+ "0x11f4d" => "ACKNOWLEDGED",
66
+ "0x11f4f" => "ALARM_STATUS",
67
+ "0x11fc5" => "OCCURRENCES",
68
+ "0x11f57" => "TROUBLE_SHOOTER",
69
+ "0x11f9b" => "USER_CLEARABLE",
70
+ "0x12022" => "TROUBLE_TICKET_ID",
71
+ "0x12942" => "PERSISTENT",
72
+ "0x12adb" => "GC_NAME",
73
+ "0x57f0105" => "Custom_Project",
74
+ "0x11f4d" => "ACKNOWLEDGED",
75
+ "0xffff00ed" => "application_name",
76
+ "0xffff00f1" => "business_unit_l1",
77
+ "0xffff00f2" => "business_unit_l2",
78
+ "0xffff00f3" => "business_unit_l3",
79
+ "0xffff00f4" => "business_unit_l4",
80
+ "0xffff00f0" => "cmdb_ci_sysid",
81
+
82
+ #{}"0x11f51" => "CLEARED_BY_USER_NAME",
83
+ #{}"0x11f52" => "EVENT_ID_LIST",
84
+ #{}"0x11f53" => "MODEL_HANDLE",
85
+ #{}"0x11f54" => "PRIMARY_ALARM",
86
+ #{}"0x11fc4" => "ALARM_SOURCE",
87
+ #{}"0x11fc6" => "TROUBLE_SHOOTER_MH",
88
+ #{}"0x12a6c" => "TROUBLE_SHOOTER_EMAIL",
89
+ #{}"0x1290d" => "IMPACT_SEVERITY",
90
+ #{}"0x1290e" => "IMPACT_SCOPE",
91
+ #{}"0x1298a" => "IMPACT_TYPE_LIST",
92
+ #{}"0x12948" => "DIAGNOSIS_LOG",
93
+ #{}"0x129aa" => "MODEL_ID",
94
+ #{}"0x129ab" => "MODEL_TYPE_ID",
95
+ #{}"0x129af" => "CLEAR_DATE",
96
+ #{}"0x12a04" => "SYMPTOM_LIST_ATTR",
97
+ #{}"0x12a6f" => "EVENT_SYMPTOM_LIST_ATTR",
98
+ #{}"0x12a05" => "CAUSE_LIST_ATTR",
99
+ #{}"0x12a06" => "SYMPTOM_COUNT_ATTR",
100
+ #{}"0x12a70" => "EVENT_SYMPTOM_COUNT_ATTR",
101
+ #{}"0x12a07" => "CAUSE_COUNT_ATTR",
102
+ #{}"0x12a63" => "WEB_CONTEXT_URL",
103
+ #{}"0x12a6b" => "COMBINED_IMPACT_TYPE_LIST",
104
+ #{}"0x11f50" => "CAUSE_CODE",
105
+ #{}"0x10009" => "SECURITY_STRING"
106
+ }
107
+ # Create XML chunk for attributes we care about
108
+ @attr_of_interest=""
109
+ @spectrum_access_code.each do |key, array|
110
+ @attr_of_interest += " <rs:requested-attribute id=\"#{key}\"/>"
111
+ end
112
+
113
+
114
+ # Setup URL Resource
115
+ @url = 'http://' + @endpoint.to_s + '/spectrum/restful/alarms/'
116
+ end
117
+
118
+ def parse_rename_rule rule
119
+ if rule.match /^([^\s]+)\s+(.+)$/
120
+ return $~.captures
121
+ end
122
+ end
123
+
124
+ # This method is called when starting.
125
+ def start
126
+ super
127
+ end
128
+
129
+ # This method is called when shutting down.
130
+ def shutdown
131
+ super
132
+ end
133
+
134
+ # This method is called when an event reaches Fluentd.
135
+ # 'es' is a Fluent::EventStream object that includes multiple events.
136
+ # You can use 'es.each {|time,record["event"]| ... }' to retrieve events.
137
+ # 'chain' is an object that manages transactions. Call 'chain.next' at
138
+ # appropriate points and rollback if it raises an exception.
139
+ #
140
+ # NOTE! This method is called by Fluentd's main thread so you should not write slow routine here. It causes Fluentd's performance degression.
141
+ def emit(tag, es, chain)
142
+ chain.next
143
+ es.each {|time,record|
144
+ $stderr.puts "OK!"
145
+ ## Check if the incoming event already has an event id (alarm id) and a corresponding tag of spectrum
146
+ if (record["event"].has_key?("source_event_id") && record["event"].has_key?("event_type"))
147
+ # If the value on event_type is spectrum, then it means that ti is already from spectrum and needs an update
148
+ if (record["event"].has_value?("alert.spectrum"))
149
+
150
+ # Create an empty hash
151
+ alertUpdateHash=Hash.new
152
+
153
+ # Parse thro the array hash that contains name value pairs for hash mapping and add new records to a new hash
154
+ @rename_rules.each { |rule|
155
+ pp rule[:new_key]
156
+ alertUpdateHash[rule[:key_regexp]]=record["event"][rule[:new_key]]
157
+ }
158
+ # construct the url and iterate to construct the uri
159
+ @urlrest = @url + record["event"]["source_event_id"]
160
+ alertUpdateHash.each do |attr, val|
161
+ if (val.nil? || val.empty?)
162
+ next
163
+ else
164
+ if (@urlrest =~ /#{record["event"]["source_event_id"]}\s*$/)
165
+ @urlrest = @urlrest + "?attr=" + attr + "&val=" + CGI.escape(val.to_s)
166
+ else
167
+ @urlrest = @urlrest + "&attr=" + attr + "&val=" + CGI.escape(val.to_s)
168
+ end
169
+ end
170
+ end
171
+
172
+ $log.info "Rest url " + @urlrest
173
+ #RestClient::Resource.new(@user,@pass)
174
+ begin
175
+ responsePostAffEnt=RestClient::Resource.new(@urlrest,@user,@pass).put(@urlrest,:content_type => 'application/json')
176
+ rescue Exception => e
177
+ $log.error "Error in restful put call."
178
+ log.error e.backtrace.inspect
179
+ $log.error responsePostAffEnt
180
+ end
181
+
182
+ else
183
+
184
+ # For now just throw to stdout
185
+ $log.info record["event"]
186
+
187
+ end
188
+
189
+ end
190
+ }
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,35 @@
1
+ <source>
2
+ type spectrum
3
+ endpoint spectrum.changeme.com
4
+ user changeme
5
+ pass changeme
6
+ tag alert.spectrum
7
+ interval 60
8
+ include_raw true
9
+ </source>
10
+
11
+ <match alert.spectrum>
12
+ type rename_key
13
+ deep_rename false
14
+ remove_tag_prefix alert.spectrum
15
+ append_tag alert
16
+ rename_rule1 HOSTNAME source_hostname
17
+ rename_rule2 IP_ADDRESS source_ip
18
+ rename_rule3 ALARM_TITLE event_name
19
+ rename_rule4 SEVERITY criticality
20
+ rename_rule5 CREATION_DATE creation_time
21
+ rename_rule6 ORIGINATING_EVENT_ATTR alert_description
22
+ rename_rule7 MODEL_STRING source_type
23
+ rename_rule8 ALARM_ID source_event_id
24
+ rename_rule9 GC_NAME environment
25
+ </match>
26
+
27
+ <match alert>
28
+ type key_picker
29
+ keys event_type,intermediary_source,source_event_id,creation_time,criticality,event_name,source_hostname,source_ip,alert_description,source_type,environment,raw
30
+ add_tag_prefix processed.
31
+ </match>
32
+
33
+ <match processed.alert>
34
+ type stdout
35
+ </match>
@@ -1,8 +1,13 @@
1
1
  <source>
2
- type spectrum
3
- tag alert.spectrum
2
+ type spectrum
3
+ endpoint spectrum.changeme.com
4
+ user changeme
5
+ pass changeme
6
+ tag alert.spectrum
7
+ interval 60
8
+ include_raw false
4
9
  </source>
5
10
 
6
- <match alert.spectrum*>
7
- type stdout
8
- </match>
11
+ <match alert.spectrum>
12
+ type stdout
13
+ </match>
@@ -6,9 +6,6 @@ class SpectrumInputTest < Test::Unit::TestCase
6
6
  end
7
7
 
8
8
  CONFIG = %[
9
- host 0
10
- port 1062
11
- tag alert.spectrum
12
9
  ]
13
10
 
14
11
  def create_driver(conf=CONFIG)
@@ -17,8 +14,11 @@ class SpectrumInputTest < Test::Unit::TestCase
17
14
 
18
15
  def test_configure
19
16
  d = create_driver('')
20
- assert_equal "0".to_i, d.instance.host
21
- assert_equal "1062".to_i, d.instance.port
17
+ #assert_equal "pleasechangeme.com", d.instance.endpoint
18
+ #assert_equal "username", d.instance.user
19
+ #assert_equal "password", d.instance.pass
20
+ assert_equal "300".to_i, d.instance.interval
21
+ assert_equal "false", d.instance.include_raw
22
22
  assert_equal 'alert.spectrum', d.instance.tag
23
23
  end
24
24
  end
metadata CHANGED
@@ -1,107 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-spectrum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Pena
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-24 00:00:00.000000000 Z
11
+ date: 2015-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.9'
20
- - - '>='
20
+ - - ">="
21
21
  - !ruby/object:Gem::Version
22
22
  version: 0.9.6
23
23
  type: :development
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0.9'
30
- - - '>='
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 0.9.6
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: fluentd
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ~>
37
+ - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0.10'
40
- - - '>='
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: 0.10.52
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ~>
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
49
  version: '0.10'
50
- - - '>='
50
+ - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 0.10.52
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: json
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - ~>
57
+ - - "~>"
58
58
  - !ruby/object:Gem::Version
59
59
  version: '1.1'
60
- - - '>='
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: 1.8.2
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ~>
67
+ - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '1.1'
70
- - - '>='
70
+ - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: 1.8.2
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: rest-client
75
75
  requirement: !ruby/object:Gem::Requirement
76
76
  requirements:
77
- - - ~>
77
+ - - "~>"
78
78
  - !ruby/object:Gem::Version
79
79
  version: '1.7'
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.7.3
83
83
  type: :runtime
84
84
  prerelease: false
85
85
  version_requirements: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ~>
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '1.7'
90
- - - '>='
90
+ - - ">="
91
91
  - !ruby/object:Gem::Version
92
92
  version: 1.7.3
93
- description: Fluentd plugin for Spectrum Alerts... WIP
93
+ description: Fluentd plugin for pulling monitoring alerts from CA Spectrum
94
94
  email:
95
- - alex_pena@intuit.com
95
+ - pena.alex@gmail.com
96
96
  executables: []
97
97
  extensions: []
98
98
  extra_rdoc_files: []
99
99
  files:
100
+ - ".gitignore"
101
+ - ".travis.yml"
100
102
  - Gemfile
101
103
  - README.md
102
104
  - Rakefile
103
105
  - fluent-plugin-spectrum.gemspec
104
106
  - lib/fluent/plugin/in_spectrum.rb
107
+ - lib/fluent/plugin/out_spectrum.rb
108
+ - sample/spectrum.conf.advanced_sample
105
109
  - sample/spectrum.conf.sample
106
110
  - test/helper.rb
107
111
  - test/plugin/test_in_spectrum.rb
@@ -115,20 +119,20 @@ require_paths:
115
119
  - lib
116
120
  required_ruby_version: !ruby/object:Gem::Requirement
117
121
  requirements:
118
- - - '>='
122
+ - - ">="
119
123
  - !ruby/object:Gem::Version
120
124
  version: '0'
121
125
  required_rubygems_version: !ruby/object:Gem::Requirement
122
126
  requirements:
123
- - - '>='
127
+ - - ">="
124
128
  - !ruby/object:Gem::Version
125
129
  version: '0'
126
130
  requirements: []
127
131
  rubyforge_project:
128
- rubygems_version: 2.3.0
132
+ rubygems_version: 2.4.5
129
133
  signing_key:
130
134
  specification_version: 4
131
- summary: Fluentd input plugin for Spectrum Alerts
135
+ summary: Fluentd input plugin for pulling alerts from CA Spectrum
132
136
  test_files:
133
137
  - test/helper.rb
134
138
  - test/plugin/test_in_spectrum.rb