fluent-plugin-appdynamics 0.0.1
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.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/README +49 -0
- data/README.md +49 -0
- data/create_fluentd_str +300 -0
- data/fluent-plugin-appdynamics.gemspec +24 -0
- data/lib/fluent/plugin/controller.rb +123 -0
- data/lib/fluent/plugin/in_appdynamics.rb +89 -0
- data/notes +14 -0
- data/sample/snmp.conf.sample +11 -0
- data/test/helper.rb +30 -0
- data/test/plugin/test_in_appdynamics.rb +26 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 21706d2b89c503d439df1b753e14de857a4b6e0c
|
4
|
+
data.tar.gz: 6f31ebc6f128e3da59ffdfcfb6e2595996e9fb3d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7b026e27460b97cd2e574ca9102b9dacfc427ec0225052808bbf73e5b720d77b32428f11967d5f05d795793ab761eb054b3dec746c5350214c617af6ddafd44f
|
7
|
+
data.tar.gz: 8d7b247968ccfd7ac693a45366417767e3d2fea0450f1cb26826e0d70e6ba3bb62b6f5ade84a990405a23a53f29ec618a62078585b6b334f2c271a9a354ccf83
|
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Fluent::Plugin::appdynamics
|
2
|
+
|
3
|
+
fluent-plugin-appdynamics is an input plug-in for [Fluentd](http://fluentd.org)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
These instructions assume you already have fluentd installed.
|
8
|
+
If you don't, please run through [quick start for fluentd] (https://github.com/fluent/fluentd#quick-start)
|
9
|
+
|
10
|
+
Now after you have fluentd installed you can follow either of the steps below:
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'fluent-plugin-appdynamics'
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install fluent-plugin-appdynamics
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
Add the following into your fluentd config.
|
22
|
+
|
23
|
+
<source>
|
24
|
+
type appdynamics # required, chossing the input plugin.
|
25
|
+
endpoint # Optional.
|
26
|
+
projectId # Needed for Ironio
|
27
|
+
token # Needed for Ironio
|
28
|
+
endpointQueue # Needed for Ironio
|
29
|
+
endpointType # Example ironio, kinesis
|
30
|
+
oauthId # authorization key
|
31
|
+
interval # frequency to pull data
|
32
|
+
readOnly # True or false to control deletion of message after it is read
|
33
|
+
</source>
|
34
|
+
|
35
|
+
<match alert.appdynamics>
|
36
|
+
type stdout
|
37
|
+
</match>
|
38
|
+
|
39
|
+
Now startup fluentd
|
40
|
+
|
41
|
+
$ sudo fluentd -c fluent.conf &
|
42
|
+
|
43
|
+
Send a test trap using net-snmp tools
|
44
|
+
|
45
|
+
$ cd test; rvmsudo ./ironmq.rb
|
46
|
+
|
47
|
+
## To Do
|
48
|
+
1. Change the logic to do a get all call so we process a bunch of alerts at a time.
|
49
|
+
2. Make delete configurable
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Fluent::Plugin::appdynamics
|
2
|
+
|
3
|
+
fluent-plugin-appdynamics is an input plug-in for [Fluentd](http://fluentd.org)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
These instructions assume you already have fluentd installed.
|
8
|
+
If you don't, please run through [quick start for fluentd] (https://github.com/fluent/fluentd#quick-start)
|
9
|
+
|
10
|
+
Now after you have fluentd installed you can follow either of the steps below:
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'fluent-plugin-appdynamics'
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install fluent-plugin-appdynamics
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
Add the following into your fluentd config.
|
22
|
+
|
23
|
+
<source>
|
24
|
+
type appdynamics # required, chossing the input plugin.
|
25
|
+
endpoint # Optional.
|
26
|
+
projectId # Needed for Ironio
|
27
|
+
token # Needed for Ironio
|
28
|
+
endpointQueue # Needed for Ironio
|
29
|
+
endpointType # Example ironio, kinesis
|
30
|
+
oauthId # authorization key
|
31
|
+
interval # frequency to pull data
|
32
|
+
readOnly # True or false to control deletion of message after it is read
|
33
|
+
</source>
|
34
|
+
|
35
|
+
<match alert.appdynamics>
|
36
|
+
type stdout
|
37
|
+
</match>
|
38
|
+
|
39
|
+
Now startup fluentd
|
40
|
+
|
41
|
+
$ sudo fluentd -c fluent.conf &
|
42
|
+
|
43
|
+
Send a test trap using net-snmp tools
|
44
|
+
|
45
|
+
$ cd test; rvmsudo ./ironmq.rb
|
46
|
+
|
47
|
+
## To Do
|
48
|
+
1. Change the logic to do a get all call so we process a bunch of alerts at a time.
|
49
|
+
2. Make delete configurable
|
data/create_fluentd_str
ADDED
@@ -0,0 +1,300 @@
|
|
1
|
+
|
2
|
+
plugin=$1
|
3
|
+
USAGE="USAGE: $0 plugin"
|
4
|
+
if [ -z "$plugin" ]; then
|
5
|
+
echo $USAGE
|
6
|
+
exit
|
7
|
+
fi
|
8
|
+
|
9
|
+
mkdir -p lib/fluent/plugin sample test/plugin
|
10
|
+
|
11
|
+
currdate=`date +"%Y-%m-%d"`
|
12
|
+
|
13
|
+
cat >README <<EOF
|
14
|
+
# Fluent::Plugin::$plugin
|
15
|
+
|
16
|
+
fluent-plugin-$plugin is an input plug-in for [Fluentd](http://fluentd.org)
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
These instructions assume you already have fluentd installed.
|
21
|
+
If you don't, please run through [quick start for fluentd] (https://github.com/fluent/fluentd#quick-start)
|
22
|
+
|
23
|
+
Now after you have fluentd installed you can follow either of the steps below:
|
24
|
+
|
25
|
+
Add this line to your application's Gemfile:
|
26
|
+
|
27
|
+
gem 'fluent-plugin-$plugin'
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
$ gem install fluent-plugin-$plugin
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
Add the following into your fluentd config.
|
35
|
+
|
36
|
+
<source>
|
37
|
+
type $plugin # required, chossing the input plugin.
|
38
|
+
endpoint # Optional.
|
39
|
+
projectId # Needed for Ironio
|
40
|
+
token # Needed for Ironio
|
41
|
+
endpointQueue # Needed for Ironio
|
42
|
+
endpointType # Example ironio, kinesis
|
43
|
+
oauthId # authorization key
|
44
|
+
interval # frequency to pull data
|
45
|
+
readOnly # True or false to control deletion of message after it is read
|
46
|
+
</source>
|
47
|
+
|
48
|
+
<match alert.$plugin>
|
49
|
+
type stdout
|
50
|
+
</match>
|
51
|
+
|
52
|
+
Now startup fluentd
|
53
|
+
|
54
|
+
$ sudo fluentd -c fluent.conf &
|
55
|
+
|
56
|
+
Send a test trap using net-snmp tools
|
57
|
+
|
58
|
+
$ cd test; rvmsudo ./ironmq.rb
|
59
|
+
|
60
|
+
## To Do
|
61
|
+
1. Change the logic to do a get all call so we process a bunch of alerts at a time.
|
62
|
+
2. Make delete configurable
|
63
|
+
EOF
|
64
|
+
|
65
|
+
cat >README.md <<EOF
|
66
|
+
# Fluent::Plugin::$plugin
|
67
|
+
|
68
|
+
fluent-plugin-$plugin is an input plug-in for [Fluentd](http://fluentd.org)
|
69
|
+
|
70
|
+
## Installation
|
71
|
+
|
72
|
+
These instructions assume you already have fluentd installed.
|
73
|
+
If you don't, please run through [quick start for fluentd] (https://github.com/fluent/fluentd#quick-start)
|
74
|
+
|
75
|
+
Now after you have fluentd installed you can follow either of the steps below:
|
76
|
+
|
77
|
+
Add this line to your application's Gemfile:
|
78
|
+
|
79
|
+
gem 'fluent-plugin-$plugin'
|
80
|
+
|
81
|
+
Or install it yourself as:
|
82
|
+
|
83
|
+
$ gem install fluent-plugin-$plugin
|
84
|
+
|
85
|
+
## Usage
|
86
|
+
Add the following into your fluentd config.
|
87
|
+
|
88
|
+
<source>
|
89
|
+
type $plugin # required, chossing the input plugin.
|
90
|
+
endpoint # Optional.
|
91
|
+
projectId # Needed for Ironio
|
92
|
+
token # Needed for Ironio
|
93
|
+
endpointQueue # Needed for Ironio
|
94
|
+
endpointType # Example ironio, kinesis
|
95
|
+
oauthId # authorization key
|
96
|
+
interval # frequency to pull data
|
97
|
+
readOnly # True or false to control deletion of message after it is read
|
98
|
+
</source>
|
99
|
+
|
100
|
+
<match alert.$plugin>
|
101
|
+
type stdout
|
102
|
+
</match>
|
103
|
+
|
104
|
+
Now startup fluentd
|
105
|
+
|
106
|
+
$ sudo fluentd -c fluent.conf &
|
107
|
+
|
108
|
+
Send a test trap using net-snmp tools
|
109
|
+
|
110
|
+
$ cd test; rvmsudo ./ironmq.rb
|
111
|
+
|
112
|
+
## To Do
|
113
|
+
1. Change the logic to do a get all call so we process a bunch of alerts at a time.
|
114
|
+
2. Make delete configurable
|
115
|
+
EOF
|
116
|
+
|
117
|
+
|
118
|
+
cat > fluent-plugin-$plugin.gemspec <<EOF
|
119
|
+
# -*- encoding: utf-8 -*-
|
120
|
+
$:.push File.expand_path("../lib", __FILE__)
|
121
|
+
|
122
|
+
Gem::Specification.new do |gem|
|
123
|
+
gem.name = "fluent-plugin-$plugin"
|
124
|
+
gem.version = "0.0.1"
|
125
|
+
gem.date = '$currdate'
|
126
|
+
gem.authors = ["chandrashekar Tippur"]
|
127
|
+
gem.email = ["ctippur@gmail.com"]
|
128
|
+
gem.summary = %q{Fluentd input plugin for $plugin alerts}
|
129
|
+
gem.description = %q{FLuentd plugin for $plugin alerts... WIP}
|
130
|
+
gem.homepage = 'https://github.com/Bigel0w/fluent-plugin-$plugin'
|
131
|
+
gem.license = 'MIT'
|
132
|
+
|
133
|
+
gem.files = `git ls-files`.split($\)
|
134
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
135
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
136
|
+
gem.require_paths = ["lib"]
|
137
|
+
# Add GEM dependencies below
|
138
|
+
# For Example: gem.add_development_dependency "rake", '~> 0.9', '>= 0.9.6'
|
139
|
+
end
|
140
|
+
EOF
|
141
|
+
|
142
|
+
cat >Gemfile <<EOF
|
143
|
+
source 'https://rubygems.org'
|
144
|
+
|
145
|
+
# Specify your gem's dependencies in fluent-plugin-snmp.gemspec
|
146
|
+
gemspec
|
147
|
+
EOF
|
148
|
+
|
149
|
+
|
150
|
+
# Create files
|
151
|
+
|
152
|
+
cat >lib/fluent/plugin/in_${plugin}.rb <<EOF
|
153
|
+
module Fluent
|
154
|
+
|
155
|
+
# Read trap messages as events in to fluentd
|
156
|
+
class NewRelicInput < Input
|
157
|
+
Fluent::Plugin.register_input('newrelic', self)
|
158
|
+
|
159
|
+
# Define default configurations
|
160
|
+
# Example: config_param :tag, :string, :default => "alert.newrelic"
|
161
|
+
config_param :interval, :string, :default => "5"
|
162
|
+
config_param :tag, :string, :default => "alert.$plugin"
|
163
|
+
config_param :endpoint, :string, :default => "" # Optional
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
# Initialize and bring in dependencies
|
168
|
+
def initialize
|
169
|
+
super
|
170
|
+
require 'json'
|
171
|
+
require 'daemons'
|
172
|
+
require 'pp'
|
173
|
+
# Add any other dependencies
|
174
|
+
end # def initialize
|
175
|
+
|
176
|
+
# Load internal and external configs
|
177
|
+
def configure(conf)
|
178
|
+
super
|
179
|
+
@conf = conf
|
180
|
+
# TO DO Add code to choke if config parameters are not there
|
181
|
+
end # def configure
|
182
|
+
|
183
|
+
def start
|
184
|
+
super
|
185
|
+
@loop = Coolio::Loop.new
|
186
|
+
timer_trigger = TimerWatcher.new(@interval, true, &method(:input))
|
187
|
+
timer_trigger.attach(@loop)
|
188
|
+
@thread = Thread.new(&method(:run))
|
189
|
+
$log.info "starting $plugin poller, interval #{@interval}"
|
190
|
+
end
|
191
|
+
|
192
|
+
# Stop Listener and cleanup any open connections.
|
193
|
+
def shutdown
|
194
|
+
super
|
195
|
+
@loop.stop
|
196
|
+
@thread.join
|
197
|
+
end
|
198
|
+
|
199
|
+
def run
|
200
|
+
@loop.run
|
201
|
+
$log.info "Running $plugin Input"
|
202
|
+
end
|
203
|
+
|
204
|
+
# Start $plugin Trap listener
|
205
|
+
# Add the code to run this
|
206
|
+
def input
|
207
|
+
end # def Input
|
208
|
+
|
209
|
+
end # End Input class
|
210
|
+
|
211
|
+
class TimerWatcher < Coolio::TimerWatcher
|
212
|
+
def initialize(interval, repeat, &callback)
|
213
|
+
@callback = callback
|
214
|
+
super(interval, repeat)
|
215
|
+
end
|
216
|
+
|
217
|
+
def on_timer
|
218
|
+
@callback.call
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
end # module Fluent
|
223
|
+
EOF
|
224
|
+
|
225
|
+
|
226
|
+
cat >sample/snmp.conf.sample <<EOF
|
227
|
+
<source>
|
228
|
+
type $plugin # required, chossing the input plugin.
|
229
|
+
endpoint # Optional.
|
230
|
+
interval # frequency to pull data
|
231
|
+
readOnly # True or false. This is to control the deletion of message after it is read
|
232
|
+
# Add any more parameters here
|
233
|
+
</source>
|
234
|
+
|
235
|
+
<match alert.$plugin>
|
236
|
+
type stdout
|
237
|
+
</match>
|
238
|
+
EOF
|
239
|
+
|
240
|
+
|
241
|
+
cat >test/helper.rb <<EOF
|
242
|
+
require 'rubygems'
|
243
|
+
require 'bundler'
|
244
|
+
begin
|
245
|
+
Bundler.setup(:default, :development)
|
246
|
+
rescue Bundler::BundlerError => e
|
247
|
+
$stderr.puts e.message
|
248
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
249
|
+
exit e.status_code
|
250
|
+
end
|
251
|
+
require 'test/unit'
|
252
|
+
|
253
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
254
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
255
|
+
require 'fluent/test'
|
256
|
+
unless ENV.has_key?('VERBOSE')
|
257
|
+
nulllogger = Object.new
|
258
|
+
nulllogger.instance_eval {|obj|
|
259
|
+
def method_missing(method, *args)
|
260
|
+
# pass
|
261
|
+
end
|
262
|
+
}
|
263
|
+
$log = nulllogger
|
264
|
+
end
|
265
|
+
|
266
|
+
require 'fluent/plugin/in_$plugin'
|
267
|
+
|
268
|
+
class Test::Unit::TestCase
|
269
|
+
end
|
270
|
+
EOF
|
271
|
+
|
272
|
+
|
273
|
+
cat >test/plugin/test_in_${plugin}.rb <<EOF
|
274
|
+
require 'helper'
|
275
|
+
|
276
|
+
class ${plugin}TrapInputTest < Test::Unit::TestCase
|
277
|
+
def setup
|
278
|
+
Fluent::Test.setup
|
279
|
+
end
|
280
|
+
|
281
|
+
# Add config here
|
282
|
+
CONFIG = %[
|
283
|
+
# Example hostt 0
|
284
|
+
# Example port 1062
|
285
|
+
# Example tag alert.snmptrap
|
286
|
+
]
|
287
|
+
|
288
|
+
def create_driver(conf=CONFIG)
|
289
|
+
Fluent::Test::InputTestDriver.new(Fluent::${plugin}TrapInput).configure(conf)
|
290
|
+
end
|
291
|
+
|
292
|
+
# Configure the test
|
293
|
+
def test_configure
|
294
|
+
d = create_driver('')
|
295
|
+
# Example assert_equal "0".to_i, d.instance.host
|
296
|
+
# Example assert_equal "1062".to_i, d.instance.port
|
297
|
+
# Example assert_equal 'alert.snmptrap', d.instance.tag
|
298
|
+
end
|
299
|
+
end
|
300
|
+
EOF
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "fluent-plugin-appdynamics"
|
6
|
+
gem.version = "0.0.1"
|
7
|
+
gem.date = '2015-03-02'
|
8
|
+
gem.authors = ["chandrashekar Tippur"]
|
9
|
+
gem.email = ["ctippur@gmail.com"]
|
10
|
+
gem.summary = %q{Fluentd input plugin for appdynamics alerts}
|
11
|
+
gem.description = %q{FLuentd plugin for appdynamics alerts... WIP}
|
12
|
+
gem.homepage = 'https://github.com/Bigel0w/fluent-plugin-appdynamics'
|
13
|
+
gem.license = 'MIT'
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($\)
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
# Add GEM dependencies below
|
20
|
+
# For Example: gem.add_development_dependency "rake", '~> 0.9', '>= 0.9.6'
|
21
|
+
gem.add_runtime_dependency "fluentd", '~> 0.10', '>= 0.10.52'
|
22
|
+
gem.add_runtime_dependency "json", '~> 1.1', '>= 1.8.2'
|
23
|
+
gem.add_runtime_dependency "rest-client", '~> 1.7', '>= 1.7.3'
|
24
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'uri'
|
2
|
+
module Appdynamics
|
3
|
+
class Controller
|
4
|
+
include HTTParty
|
5
|
+
attr_reader :host_name, :account_name, :user_name, :password, :application_name, :application_id,
|
6
|
+
:base_uri, :applications, :nodes, :tiers
|
7
|
+
|
8
|
+
def initialize host_name, account_name, user_name, password
|
9
|
+
@host_name = host_name
|
10
|
+
@account_name = account_name
|
11
|
+
@user_name = user_name
|
12
|
+
@password = password
|
13
|
+
@base_uri = "http://#{host_name}/controller/rest"
|
14
|
+
@auth = {username: "#{user_name}@#{account_name}", password: password}
|
15
|
+
end
|
16
|
+
|
17
|
+
def serialize
|
18
|
+
YAML.dump self
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.deserialize datum
|
22
|
+
YAML.load datum
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_hash
|
26
|
+
hsh = {
|
27
|
+
host_name: @host_name,
|
28
|
+
account_name: @account_name,
|
29
|
+
user_name: @user_name,
|
30
|
+
password: @password
|
31
|
+
}
|
32
|
+
hsh.merge!({applications: @applications.map{|app| app.to_hash}}) if @applications
|
33
|
+
hsh
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.from_hash hsh
|
37
|
+
controller = Controller.new hsh['host_name'], hsh['account_name'], hsh['user_name'], hsh['password']
|
38
|
+
controller.applications = hsh['applications']
|
39
|
+
controller
|
40
|
+
end
|
41
|
+
|
42
|
+
def applications
|
43
|
+
return @applications unless @applications.nil?
|
44
|
+
result = []
|
45
|
+
begin
|
46
|
+
result = self.class.get("#{@base_uri}/applications", options)
|
47
|
+
rescue SocketError => ee
|
48
|
+
raise Exception.new "Bad host name, #{ee}"
|
49
|
+
end
|
50
|
+
|
51
|
+
raise Exception.new "HTTP Error: #{result.response.code}" unless result.response.code == "200"
|
52
|
+
|
53
|
+
@applications ||= result.map{|res|
|
54
|
+
Application.new self, res["id"], res["name"]
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def applications= applications
|
59
|
+
@applications = applications.map{|application|
|
60
|
+
Application.from_hash application, self
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def reset_cache!
|
65
|
+
@nodes = @tiers = @applications = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def get path, additional_options = {}
|
69
|
+
result = self.class.get(URI.escape(path), options(additional_options))
|
70
|
+
raise Exception.new "HTTP Error: #{result.response.code}" unless result.response.code == "200"
|
71
|
+
result
|
72
|
+
end
|
73
|
+
|
74
|
+
def nodes_for application
|
75
|
+
path = "#{base_uri}/#{application.relative_route}/nodes"
|
76
|
+
result = get path
|
77
|
+
result.map{|res|
|
78
|
+
Node.new self, application, res
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
def tiers_for application
|
83
|
+
path = "#{base_uri}/#{application.relative_route}/tiers"
|
84
|
+
result = get path
|
85
|
+
result.map{|res|
|
86
|
+
Tier.new self, application, res
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def metrics_for obj
|
91
|
+
path = "#{base_uri}/#{obj.relative_route}"
|
92
|
+
path += "/metrics" if obj.class == Application
|
93
|
+
result = get path
|
94
|
+
result.map{|res|
|
95
|
+
Metric.new self, obj, res
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
def metric_data_for metric, start_time, end_time, rollup = false
|
100
|
+
path = "#{base_uri}/#{metric.relative_route(true)}"
|
101
|
+
start_time = Time.parse start_time unless start_time.class == Time
|
102
|
+
end_time = Time.parse end_time unless end_time.class == Time
|
103
|
+
path = "#{base_uri}/#{metric.relative_route(true)}"
|
104
|
+
additional_options = {
|
105
|
+
'time-range-type' => "BETWEEN_TIMES",
|
106
|
+
'start-time' => start_time.to_i * 1000,
|
107
|
+
'end-time' => end_time.to_i * 1000,
|
108
|
+
'rollup' => rollup
|
109
|
+
}
|
110
|
+
result = get path, options({query: additional_options})
|
111
|
+
result
|
112
|
+
end
|
113
|
+
|
114
|
+
protected
|
115
|
+
def options additional_options = {}
|
116
|
+
base_options = {basic_auth: @auth}.merge additional_options
|
117
|
+
base_options[:query] ||= {}
|
118
|
+
base_options[:query][:output] ||= 'JSON'
|
119
|
+
base_options[:query][:rollup] ||= false
|
120
|
+
base_options
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Fluent
|
2
|
+
|
3
|
+
# Read trap messages as events in to fluentd
|
4
|
+
class AppdynamicsInput < Input
|
5
|
+
Fluent::Plugin.register_input('appdynamics', self)
|
6
|
+
|
7
|
+
# Define default configurations
|
8
|
+
# Example: config_param :tag, :string, :default => "alert.newrelic"
|
9
|
+
config_param :tag, :string, :default => "alert.appdynamics"
|
10
|
+
config_param :endpoint, :string, :default => "https://intuitapm2.saas.appdynamics.com/controller/rest/applications/xxxx/problems/healthrule-violations?time-range-type=BETWEEN_TIMES&output=JSONJSON" # Optional
|
11
|
+
config_param :interval, :integer, :default => '300' #Default 5 minutes
|
12
|
+
config_param :user, :string, :default => "rest-user"
|
13
|
+
config_param :pass, :string, :default => "AyDS-6q+XdP5S=G"
|
14
|
+
config_param :include_raw, :string, :default => "false" #Include original object as raw
|
15
|
+
config_param :attributes, :string, :default => "ALL" # fields to include, ALL for... well, ALL.
|
16
|
+
|
17
|
+
# function to UTF8 encode
|
18
|
+
def to_utf8(str)
|
19
|
+
str = str.force_encoding('UTF-8')
|
20
|
+
return str if str.valid_encoding?
|
21
|
+
str.encode("UTF-8", 'binary', invalid: :replace, undef: :replace, replace: '')
|
22
|
+
end
|
23
|
+
|
24
|
+
# Initialize and bring in dependencies
|
25
|
+
def initialize
|
26
|
+
super
|
27
|
+
require 'json'
|
28
|
+
require 'rest-client'
|
29
|
+
# Add any other dependencies
|
30
|
+
end # def initialize
|
31
|
+
|
32
|
+
# Load internal and external configs
|
33
|
+
def configure(conf)
|
34
|
+
super
|
35
|
+
@conf = conf
|
36
|
+
def appdynamicsEnd(startTime,endTime)
|
37
|
+
# Setup URL Resource
|
38
|
+
@url = @endpoint.to_s + "&start-time=" + startTime + "&end-time=" + endTime
|
39
|
+
RestClient::Resource.new(@url,@user,@pass)
|
40
|
+
end
|
41
|
+
# TO DO Add code to choke if config parameters are not there
|
42
|
+
end # def configure
|
43
|
+
|
44
|
+
def start
|
45
|
+
super
|
46
|
+
@loop = Coolio::Loop.new
|
47
|
+
timer_trigger = TimerWatcher.new(@interval, true, &method(:input))
|
48
|
+
timer_trigger.attach(@loop)
|
49
|
+
@thread = Thread.new(&method(:run))
|
50
|
+
$log.info "starting appdynamics poller, interval #{@interval}"
|
51
|
+
end
|
52
|
+
|
53
|
+
# Stop Listener and cleanup any open connections.
|
54
|
+
def shutdown
|
55
|
+
super
|
56
|
+
@loop.stop
|
57
|
+
@thread.join
|
58
|
+
end
|
59
|
+
|
60
|
+
def run
|
61
|
+
@loop.run
|
62
|
+
$log.info "Running appdynamics Input"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Start appdynamics Trap listener
|
66
|
+
# Add the code to run this
|
67
|
+
def input
|
68
|
+
alertStartTime = Engine.now.to_i - @interval.to_i
|
69
|
+
$log.info "appdynamics :: Polling alerts for time period: #{alertStartTime.to_i} - #{Engine.now.to_i}"
|
70
|
+
# Post to Appdynamics and parse results
|
71
|
+
responsePost=appdynamicsEnd(alertStartTime,Engine.now.to_i).post @xml,:content_type => 'application/json',:accept => 'application/json'
|
72
|
+
body = JSON.parse(responsePost.body)
|
73
|
+
pp body
|
74
|
+
end # def Input
|
75
|
+
|
76
|
+
end # End Input class
|
77
|
+
|
78
|
+
class TimerWatcher < Coolio::TimerWatcher
|
79
|
+
def initialize(interval, repeat, &callback)
|
80
|
+
@callback = callback
|
81
|
+
super(interval, repeat)
|
82
|
+
end
|
83
|
+
|
84
|
+
def on_timer
|
85
|
+
@callback.call
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end # module Fluent
|
data/notes
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
git config --global user.name "Chandrashekar Tippur"
|
2
|
+
git config --global user.email "chandrashekar_tippur@intuit.com"
|
3
|
+
|
4
|
+
cd fluent-plugin-appdynamics
|
5
|
+
git init
|
6
|
+
touch README
|
7
|
+
git add README
|
8
|
+
git commit -m 'first commit'
|
9
|
+
git remote add origin git@gitlab.corp.intuit.net:ioc-tools/fluent-plugin-appdynamics.git
|
10
|
+
git push -u origin master
|
11
|
+
|
12
|
+
cd existing_git_repo
|
13
|
+
git remote add origin git@gitlab.corp.intuit.net:ioc-tools/fluent-plugin-appdynamics.git
|
14
|
+
git push -u origin master
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<source>
|
2
|
+
type appdynamics # required, chossing the input plugin.
|
3
|
+
endpoint # Optional.
|
4
|
+
interval # frequency to pull data
|
5
|
+
readOnly # True or false. This is to control the deletion of message after it is read
|
6
|
+
# Add any more parameters here
|
7
|
+
</source>
|
8
|
+
|
9
|
+
<match alert.appdynamics>
|
10
|
+
type stdout
|
11
|
+
</match>
|
data/test/helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
.puts e.message
|
7
|
+
.puts "Run There was a NameError while loading fluent-plugin-appdynamics.gemspec:
|
8
|
+
uninitialized constant README from
|
9
|
+
/Users/ctippur/fluent-plugin-appdynamics/fluent-plugin-appdynamics.gemspec:15:in `block in <main>' to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'test/unit'
|
13
|
+
|
14
|
+
.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
15
|
+
.unshift(File.dirname(__FILE__))
|
16
|
+
require 'fluent/test'
|
17
|
+
unless ENV.has_key?('VERBOSE')
|
18
|
+
nulllogger = Object.new
|
19
|
+
nulllogger.instance_eval {|obj|
|
20
|
+
def method_missing(method, *args)
|
21
|
+
# pass
|
22
|
+
end
|
23
|
+
}
|
24
|
+
= nulllogger
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'fluent/plugin/in_appdynamics'
|
28
|
+
|
29
|
+
class Test::Unit::TestCase
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class appdynamicsTrapInputTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
Fluent::Test.setup
|
6
|
+
end
|
7
|
+
|
8
|
+
# Add config here
|
9
|
+
CONFIG = %[
|
10
|
+
# Example hostt 0
|
11
|
+
# Example port 1062
|
12
|
+
# Example tag alert.snmptrap
|
13
|
+
]
|
14
|
+
|
15
|
+
def create_driver(conf=CONFIG)
|
16
|
+
Fluent::Test::InputTestDriver.new(Fluent::appdynamicsTrapInput).configure(conf)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Configure the test
|
20
|
+
def test_configure
|
21
|
+
d = create_driver('')
|
22
|
+
# Example assert_equal "0".to_i, d.instance.host
|
23
|
+
# Example assert_equal "1062".to_i, d.instance.port
|
24
|
+
# Example assert_equal 'alert.snmptrap', d.instance.tag
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-appdynamics
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- chandrashekar Tippur
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fluentd
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.10'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.10.52
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.10'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.10.52
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: json
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.1'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.8.2
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.1'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 1.8.2
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rest-client
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '1.7'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.7.3
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.7'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.7.3
|
73
|
+
description: FLuentd plugin for appdynamics alerts... WIP
|
74
|
+
email:
|
75
|
+
- ctippur@gmail.com
|
76
|
+
executables: []
|
77
|
+
extensions: []
|
78
|
+
extra_rdoc_files: []
|
79
|
+
files:
|
80
|
+
- Gemfile
|
81
|
+
- README
|
82
|
+
- README.md
|
83
|
+
- create_fluentd_str
|
84
|
+
- fluent-plugin-appdynamics.gemspec
|
85
|
+
- lib/fluent/plugin/controller.rb
|
86
|
+
- lib/fluent/plugin/in_appdynamics.rb
|
87
|
+
- notes
|
88
|
+
- sample/snmp.conf.sample
|
89
|
+
- test/helper.rb
|
90
|
+
- test/plugin/test_in_appdynamics.rb
|
91
|
+
homepage: https://github.com/Bigel0w/fluent-plugin-appdynamics
|
92
|
+
licenses:
|
93
|
+
- MIT
|
94
|
+
metadata: {}
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.2.2
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Fluentd input plugin for appdynamics alerts
|
115
|
+
test_files:
|
116
|
+
- test/helper.rb
|
117
|
+
- test/plugin/test_in_appdynamics.rb
|