splunk-client 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +30 -0
- data/VERSION +1 -1
- data/lib/splunk_client/splunk_alert.rb +65 -0
- data/lib/splunk_client/splunk_alert_feed.rb +38 -0
- data/lib/splunk_client/splunk_alert_feed_entry.rb +57 -0
- data/lib/splunk_client/splunk_client.rb +12 -0
- metadata +91 -95
data/README.md
CHANGED
@@ -6,6 +6,7 @@ Ruby library for dealing with Splunk searches and results using the Splunk REST
|
|
6
6
|
|
7
7
|
* Session based authentication to Splunk REST interface
|
8
8
|
* Create and check on the status of Splunk Jobs
|
9
|
+
* Retrieve Splunk alerts
|
9
10
|
* Natural Ruby methods for interacting with search results (no need to parse XML or JSON or use Ruby Hashes)
|
10
11
|
|
11
12
|
## Installation
|
@@ -36,6 +37,29 @@ Creating and using a client is easy:
|
|
36
37
|
puts result.host + " : " + result.time
|
37
38
|
end
|
38
39
|
|
40
|
+
Working with Splunk alerts:
|
41
|
+
|
42
|
+
# Create the client
|
43
|
+
splunk = SplunkClient.new("username", "password", "hostname")
|
44
|
+
|
45
|
+
# Fetch all the open alerts
|
46
|
+
alertEntries = splunk.get_alarm_list.entries
|
47
|
+
|
48
|
+
# What's the name of this alert?
|
49
|
+
alertEntries[1].alert.title
|
50
|
+
|
51
|
+
# What time did a particular alert trigger?
|
52
|
+
alertEntries[1].alert.trigger_time_rendered
|
53
|
+
|
54
|
+
# How many times has a particular alert fired?
|
55
|
+
alertEntries[1].alert.triggered_alerts
|
56
|
+
|
57
|
+
# Fetch the raw XML results of the alert
|
58
|
+
alertEntries[1].alert.results
|
59
|
+
|
60
|
+
# Work with the results as a Ruby object
|
61
|
+
alertEntries[1].alert.parsedResults
|
62
|
+
|
39
63
|
## Tips
|
40
64
|
|
41
65
|
* Want to spawn multiple jobs without blocking on each? Use `search.complete?` to poll for job status.
|
@@ -50,6 +74,12 @@ Creating and using a client is easy:
|
|
50
74
|
|
51
75
|
## Revision History
|
52
76
|
|
77
|
+
#### 0.8
|
78
|
+
|
79
|
+
* Added preliminary GET support for alarms within the Splunk REST API
|
80
|
+
|
81
|
+
TODO: Write test-cases for alerts methods.
|
82
|
+
|
53
83
|
#### 0.7
|
54
84
|
|
55
85
|
* Added alias support for raw field
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Author:: Christopher Brito (cbrito@gmail.com)
|
2
|
+
# Original Repo:: https://github.com/cbrito/splunk-client
|
3
|
+
|
4
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_results')
|
5
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_job')
|
6
|
+
|
7
|
+
|
8
|
+
class SplunkAlert
|
9
|
+
|
10
|
+
def initialize(alertXml, clientPointer=nil)
|
11
|
+
@alertXml = alertXml
|
12
|
+
@client = clientPointer #SplunkClient object pointer for use with self.results
|
13
|
+
end
|
14
|
+
|
15
|
+
def title
|
16
|
+
@alertXml.css("title").text
|
17
|
+
end
|
18
|
+
|
19
|
+
def alertId
|
20
|
+
@alertXml.css("id").text
|
21
|
+
end
|
22
|
+
|
23
|
+
def author
|
24
|
+
@alertXml.css("author > name").text
|
25
|
+
end
|
26
|
+
|
27
|
+
def published
|
28
|
+
@alertXml.css("published").text
|
29
|
+
end
|
30
|
+
|
31
|
+
def updated
|
32
|
+
@alertXml.css("updated").text
|
33
|
+
end
|
34
|
+
|
35
|
+
def results
|
36
|
+
# Return the raw Splunk XML results associated with a given fired alert.
|
37
|
+
SplunkJob.new(self.sid, @client).results
|
38
|
+
end
|
39
|
+
|
40
|
+
def parsedResults
|
41
|
+
# Returns an array of SplunkResult objects
|
42
|
+
SplunkJob.new(self.sid, @client).parsedResults
|
43
|
+
end
|
44
|
+
|
45
|
+
# Use method_missing magic to return Splunk field names. API documentation here:
|
46
|
+
# http://docs.splunk.com/Documentation/Splunk/5.0.1/RESTAPI/RESTsearch#GET_alerts.2Ffired_alerts
|
47
|
+
#
|
48
|
+
# Ex: splunkalert.triggered_alerts => @alertXml.css("entry")[0].xpath(".//s:key[@name='triggered_alerts']").text
|
49
|
+
def method_missing(name, *args, &blk)
|
50
|
+
if args.empty? && blk.nil? && @alertXml.xpath(".//s:key[@name='#{name}']").text
|
51
|
+
@alertXml.xpath(".//s:key[@name='#{name}']").text
|
52
|
+
else
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def respond_to?(name)
|
58
|
+
begin
|
59
|
+
unless @alertXml.xpath(".//s:key[@name='#{name}']").nil? then true else super end
|
60
|
+
rescue NoMethodError
|
61
|
+
super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end #class SplunkAlert
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Author:: Christopher Brito (cbrito@gmail.com)
|
2
|
+
# Original Repo:: https://github.com/cbrito/splunk-client
|
3
|
+
|
4
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_results')
|
5
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_job')
|
6
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_alert_feed_entry')
|
7
|
+
|
8
|
+
|
9
|
+
class SplunkAlertFeed
|
10
|
+
|
11
|
+
def initialize(alertFeedXml, clientPointer=nil)
|
12
|
+
@alertFeedXml = alertFeedXml
|
13
|
+
@client = clientPointer #SplunkClient object pointer for use with self.results
|
14
|
+
end
|
15
|
+
|
16
|
+
def totalResults
|
17
|
+
@alertXml.css("*totalResults").text
|
18
|
+
end
|
19
|
+
|
20
|
+
def itemsPerPage
|
21
|
+
@alertXml.css("*itemsPerPage").text
|
22
|
+
end
|
23
|
+
|
24
|
+
def startIndex
|
25
|
+
@alertXml.css("*startIndex").text
|
26
|
+
end
|
27
|
+
|
28
|
+
def entries
|
29
|
+
alertEntries = Array.new
|
30
|
+
|
31
|
+
@alertFeedXml.css("entry").each do |entry|
|
32
|
+
alertEntries.push SplunkAlertFeedEntry.new(entry, @client)
|
33
|
+
end
|
34
|
+
|
35
|
+
return alertEntries
|
36
|
+
end
|
37
|
+
|
38
|
+
end #class SplunkAlertFeed
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Author:: Christopher Brito (cbrito@gmail.com)
|
2
|
+
# Original Repo:: https://github.com/cbrito/splunk-client
|
3
|
+
|
4
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_results')
|
5
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_job')
|
6
|
+
|
7
|
+
|
8
|
+
class SplunkAlertFeedEntry
|
9
|
+
|
10
|
+
def initialize(alertEntryXml, clientPointer=nil)
|
11
|
+
@alertEntryXml = alertEntryXml
|
12
|
+
@client = clientPointer #SplunkClient object pointer for use with self.results
|
13
|
+
end
|
14
|
+
|
15
|
+
def title
|
16
|
+
@alertEntryXml.css("title").text
|
17
|
+
end
|
18
|
+
|
19
|
+
def alertId
|
20
|
+
@alertEntryXml.css("id").text
|
21
|
+
end
|
22
|
+
|
23
|
+
def author
|
24
|
+
@alertEntryXml.css("author > name").text
|
25
|
+
end
|
26
|
+
|
27
|
+
def updated
|
28
|
+
@alertEntryXml.css("updated").text
|
29
|
+
end
|
30
|
+
|
31
|
+
def alert
|
32
|
+
# Return the raw Splunk XML results associated with a given fired alert.
|
33
|
+
@client.get_alert(URI.encode(title))
|
34
|
+
#@client.get_alert(@alertEntryXml.css("link[rel='list']")[0].attributes["href"].value)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Use method_missing magic to return Splunk field names. API documentation here:
|
38
|
+
# http://docs.splunk.com/Documentation/Splunk/5.0.1/RESTAPI/RESTsearch#GET_alerts.2Ffired_alerts
|
39
|
+
#
|
40
|
+
# Ex: splunkalert.triggered_alerts => @alertXml.css("entry")[0].xpath(".//s:key[@name='triggered_alerts']").text
|
41
|
+
def method_missing(name, *args, &blk)
|
42
|
+
if args.empty? && blk.nil? && @alertEntryXml.xpath(".//s:key[@name='#{name}']").text
|
43
|
+
@alertEntryXml.xpath(".//s:key[@name='#{name}']").text
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def respond_to?(name)
|
50
|
+
begin
|
51
|
+
unless @alertEntryXml.xpath(".//s:key[@name='#{name}']").nil? then true else super end
|
52
|
+
rescue NoMethodError
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end #class SplunkAlertFeedEntry
|
@@ -6,6 +6,8 @@ require 'cgi'
|
|
6
6
|
require 'rubygems'
|
7
7
|
require 'nokogiri'
|
8
8
|
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_job')
|
9
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_alert')
|
10
|
+
require File.expand_path File.join(File.dirname(__FILE__), 'splunk_alert_feed')
|
9
11
|
|
10
12
|
class SplunkClient
|
11
13
|
|
@@ -41,6 +43,16 @@ class SplunkClient
|
|
41
43
|
url += "&output_mode=#{mode}" unless mode.nil?
|
42
44
|
splunk_get_request(url)
|
43
45
|
end
|
46
|
+
|
47
|
+
def get_alert_list(user="nobody")
|
48
|
+
xml = splunk_get_request("/servicesNS/#{user}/search/alerts/fired_alerts")
|
49
|
+
SplunkAlertFeed.new(Nokogiri::Slop(xml), self)
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_alert(alarmName, user="nobody")
|
53
|
+
xml = splunk_get_request("/servicesNS/#{user}/search/alerts/fired_alerts/#{alarmName}")
|
54
|
+
SplunkAlert.new(Nokogiri::Slop(xml).css("entry")[0], self)
|
55
|
+
end
|
44
56
|
|
45
57
|
def control_job(sid, action)
|
46
58
|
xml = splunk_post_request("/services/search/jobs/#{sid}/control",
|
metadata
CHANGED
@@ -1,103 +1,108 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: splunk-client
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 7
|
9
|
-
- 0
|
10
|
-
version: 0.7.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Christopher Brito
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-01-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: nokogiri
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
version: "0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
32
22
|
type: :runtime
|
33
|
-
version_requirements: *id001
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: rake
|
36
23
|
prerelease: false
|
37
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
38
33
|
none: false
|
39
|
-
requirements:
|
40
|
-
- -
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
segments:
|
44
|
-
- 0
|
45
|
-
version: "0"
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
46
38
|
type: :development
|
47
|
-
version_requirements: *id002
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name: rspec
|
50
39
|
prerelease: false
|
51
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
52
49
|
none: false
|
53
|
-
requirements:
|
54
|
-
- -
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
|
57
|
-
segments:
|
58
|
-
- 0
|
59
|
-
version: "0"
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
60
54
|
type: :development
|
61
|
-
version_requirements: *id003
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: simplecov-rcov
|
64
55
|
prerelease: false
|
65
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
57
|
none: false
|
67
|
-
requirements:
|
68
|
-
- -
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: simplecov-rcov
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
74
70
|
type: :development
|
75
|
-
version_requirements: *id004
|
76
|
-
- !ruby/object:Gem::Dependency
|
77
|
-
name: json
|
78
71
|
prerelease: false
|
79
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
73
|
none: false
|
81
|
-
requirements:
|
82
|
-
- -
|
83
|
-
- !ruby/object:Gem::Version
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: json
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
88
86
|
type: :development
|
89
|
-
|
90
|
-
|
91
|
-
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: splunk-client is a simple Ruby library for interfacing with Splunk's
|
95
|
+
REST API. It supports the retrieving of results via native Ruby methods.
|
96
|
+
email:
|
92
97
|
- cbrito@gmail.com
|
93
98
|
executables: []
|
94
|
-
|
95
99
|
extensions: []
|
96
|
-
|
97
100
|
extra_rdoc_files: []
|
98
|
-
|
99
|
-
files:
|
101
|
+
files:
|
100
102
|
- lib/splunk-client.rb
|
103
|
+
- lib/splunk_client/splunk_alert.rb
|
104
|
+
- lib/splunk_client/splunk_alert_feed.rb
|
105
|
+
- lib/splunk_client/splunk_alert_feed_entry.rb
|
101
106
|
- lib/splunk_client/splunk_client.rb
|
102
107
|
- lib/splunk_client/splunk_job.rb
|
103
108
|
- lib/splunk_client/splunk_result.rb
|
@@ -112,37 +117,28 @@ files:
|
|
112
117
|
- Gemfile.lock
|
113
118
|
homepage: http://github.com/cbrito/splunk-client
|
114
119
|
licenses: []
|
115
|
-
|
116
120
|
post_install_message:
|
117
121
|
rdoc_options: []
|
118
|
-
|
119
|
-
require_paths:
|
122
|
+
require_paths:
|
120
123
|
- lib
|
121
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
125
|
none: false
|
123
|
-
requirements:
|
124
|
-
- -
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
|
127
|
-
|
128
|
-
- 0
|
129
|
-
version: "0"
|
130
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
131
|
none: false
|
132
|
-
requirements:
|
133
|
-
- -
|
134
|
-
- !ruby/object:Gem::Version
|
135
|
-
|
136
|
-
segments:
|
137
|
-
- 0
|
138
|
-
version: "0"
|
132
|
+
requirements:
|
133
|
+
- - ! '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
139
136
|
requirements: []
|
140
|
-
|
141
137
|
rubyforge_project:
|
142
|
-
rubygems_version: 1.8.
|
138
|
+
rubygems_version: 1.8.23
|
143
139
|
signing_key:
|
144
140
|
specification_version: 3
|
145
141
|
summary: Ruby Library for interfacing with Splunk's REST API
|
146
|
-
test_files:
|
142
|
+
test_files:
|
147
143
|
- spec/spec_helper.rb
|
148
144
|
- spec/splunk_client_spec.rb
|