riemann-tools 0.2.13 → 1.1.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.
Files changed (91) hide show
  1. checksums.yaml +5 -5
  2. data/.docker/Dockerfile +7 -0
  3. data/.docker/publish.sh +35 -0
  4. data/.github/dependabot.yml +11 -0
  5. data/.github/workflows/ci.yml +42 -0
  6. data/.github/workflows/codeql-analysis.yml +72 -0
  7. data/.gitignore +6 -0
  8. data/.rspec +2 -0
  9. data/.rubocop.yml +32 -0
  10. data/.travis.yml +31 -0
  11. data/CHANGELOG.md +422 -0
  12. data/Gemfile +6 -0
  13. data/ISSUE_TEMPLATE.md +15 -0
  14. data/README.markdown +14 -15
  15. data/Rakefile +23 -0
  16. data/SECURITY.md +42 -0
  17. data/bin/riemann-apache-status +92 -77
  18. data/bin/riemann-bench +54 -48
  19. data/bin/riemann-cloudant +44 -39
  20. data/bin/riemann-consul +82 -75
  21. data/bin/riemann-dir-files-count +53 -46
  22. data/bin/riemann-dir-space +53 -46
  23. data/bin/riemann-diskstats +78 -74
  24. data/bin/riemann-fd +68 -47
  25. data/bin/riemann-freeswitch +108 -102
  26. data/bin/riemann-haproxy +46 -39
  27. data/bin/riemann-health +4 -335
  28. data/bin/riemann-kvminstance +18 -12
  29. data/bin/riemann-memcached +35 -28
  30. data/bin/riemann-net +4 -103
  31. data/bin/riemann-nginx-status +74 -66
  32. data/bin/riemann-ntp +4 -32
  33. data/bin/riemann-portcheck +40 -30
  34. data/bin/riemann-proc +96 -89
  35. data/bin/riemann-varnish +51 -44
  36. data/bin/riemann-zookeeper +38 -33
  37. data/lib/riemann/tools/health.rb +347 -0
  38. data/lib/riemann/tools/net.rb +104 -0
  39. data/lib/riemann/tools/ntp.rb +41 -0
  40. data/lib/riemann/tools/utils.rb +17 -0
  41. data/lib/riemann/tools/version.rb +7 -0
  42. data/lib/riemann/tools.rb +40 -33
  43. data/riemann-tools.gemspec +42 -0
  44. data/tools/riemann-aws/LICENSE +21 -0
  45. data/tools/riemann-aws/README.md +54 -0
  46. data/tools/riemann-aws/Rakefile +37 -0
  47. data/tools/riemann-aws/bin/riemann-aws-billing +93 -0
  48. data/tools/riemann-aws/bin/riemann-aws-rds-status +68 -0
  49. data/tools/riemann-aws/bin/riemann-aws-sqs-status +50 -0
  50. data/tools/riemann-aws/bin/riemann-aws-status +83 -0
  51. data/tools/riemann-aws/bin/riemann-elb-metrics +168 -0
  52. data/tools/riemann-aws/bin/riemann-s3-list +87 -0
  53. data/tools/riemann-aws/bin/riemann-s3-status +102 -0
  54. data/tools/riemann-chronos/LICENSE +21 -0
  55. data/tools/riemann-chronos/README.md +10 -0
  56. data/tools/riemann-chronos/Rakefile +37 -0
  57. data/tools/riemann-chronos/bin/riemann-chronos +161 -0
  58. data/tools/riemann-docker/LICENSE +21 -0
  59. data/tools/riemann-docker/README.md +10 -0
  60. data/tools/riemann-docker/Rakefile +36 -0
  61. data/tools/riemann-docker/bin/riemann-docker +206 -0
  62. data/tools/riemann-elasticsearch/LICENSE +21 -0
  63. data/tools/riemann-elasticsearch/README.md +10 -0
  64. data/tools/riemann-elasticsearch/Rakefile +37 -0
  65. data/tools/riemann-elasticsearch/bin/riemann-elasticsearch +174 -0
  66. data/tools/riemann-marathon/LICENSE +21 -0
  67. data/tools/riemann-marathon/README.md +10 -0
  68. data/tools/riemann-marathon/Rakefile +37 -0
  69. data/tools/riemann-marathon/bin/riemann-marathon +163 -0
  70. data/tools/riemann-mesos/LICENSE +21 -0
  71. data/tools/riemann-mesos/README.md +10 -0
  72. data/tools/riemann-mesos/Rakefile +37 -0
  73. data/tools/riemann-mesos/bin/riemann-mesos +146 -0
  74. data/tools/riemann-munin/LICENSE +21 -0
  75. data/tools/riemann-munin/README.md +10 -0
  76. data/tools/riemann-munin/Rakefile +36 -0
  77. data/tools/riemann-munin/bin/riemann-munin +43 -0
  78. data/tools/riemann-rabbitmq/LICENSE +21 -0
  79. data/tools/riemann-rabbitmq/README.md +10 -0
  80. data/tools/riemann-rabbitmq/Rakefile +37 -0
  81. data/tools/riemann-rabbitmq/bin/riemann-rabbitmq +273 -0
  82. data/tools/riemann-riak/LICENSE +21 -0
  83. data/tools/riemann-riak/README.md +10 -0
  84. data/tools/riemann-riak/Rakefile +36 -0
  85. data/tools/riemann-riak/bin/riemann-riak +323 -0
  86. data/tools/riemann-riak/bin/riemann-riak-keys +13 -0
  87. data/tools/riemann-riak/bin/riemann-riak-ring +9 -0
  88. data/tools/riemann-riak/riak_status/key_count.erl +13 -0
  89. data/tools/riemann-riak/riak_status/riak_status.rb +152 -0
  90. data/tools/riemann-riak/riak_status/ringready.erl +9 -0
  91. metadata +195 -34
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/riemann/tools/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'riemann-tools'
7
+ spec.version = Riemann::Tools::VERSION
8
+ spec.authors = ['Kyle Kingsbury']
9
+ spec.email = ['aphyr@aphyr.com']
10
+
11
+ spec.summary = 'Utilities which submit events to Riemann.'
12
+ spec.description = 'Collection of utilities which submit events to Riemann,'
13
+ spec.homepage = 'https://github.com/aphyr/riemann-tools'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
16
+
17
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = spec.homepage
21
+ spec.metadata['changelog_uri'] = spec.homepage
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ end
28
+ spec.bindir = 'bin'
29
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
30
+ spec.require_paths = ['lib']
31
+
32
+ spec.add_runtime_dependency 'json', '>= 1.8'
33
+ spec.add_runtime_dependency 'optimist', '~> 3.0', '>= 3.0.0'
34
+ spec.add_runtime_dependency 'riemann-client', '~> 1.0'
35
+
36
+ spec.add_development_dependency 'github_changelog_generator'
37
+ spec.add_development_dependency 'rake'
38
+ spec.add_development_dependency 'rspec'
39
+ spec.add_development_dependency 'rubocop'
40
+ spec.add_development_dependency 'rubocop-rake'
41
+ spec.add_development_dependency 'rubocop-rspec'
42
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Kyle Kingsbury
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,54 @@
1
+ # Riemann AWS tools
2
+
3
+ Gathers various AWS services statistics and submits them to Riemann.
4
+
5
+ ## Getting started
6
+
7
+ ```
8
+ gem install riemann-aws
9
+ ```
10
+
11
+ ## AWS Commands
12
+
13
+
14
+ ### Riemann AWS Billing
15
+
16
+ ```
17
+ riemann-aws-billing --help
18
+ ```
19
+
20
+ ### Riemann AWS RDS Status
21
+
22
+ ```
23
+ riemann-aws-rds-status --help
24
+ ```
25
+
26
+ ### Riemann AWS SQS Status
27
+
28
+ ```
29
+ riemann-aws-sqs-status --help
30
+ ```
31
+
32
+ ### Riemann AWS Status
33
+
34
+ ```
35
+ riemann-aws-status --help
36
+ ```
37
+
38
+ ### Riemann ELB Metrics
39
+
40
+ ```
41
+ riemann-elb-metrics --help
42
+ ```
43
+
44
+ ### Riemann S3 Status by asking Cloudwatch
45
+
46
+ ```
47
+ riemann-s3-status --help
48
+ ```
49
+
50
+ ### Riemann S3 Count by listing objects
51
+
52
+ ```
53
+ riemann-s3-list --help
54
+ ```
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+ require 'rubygems/package_task'
5
+ require 'rdoc/task'
6
+ require 'find'
7
+
8
+ # Don't include resource forks in tarballs on Mac OS X.
9
+ ENV['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true'
10
+ ENV['COPYFILE_DISABLE'] = 'true'
11
+
12
+ # Gemspec
13
+ gemspec = Gem::Specification.new do |s|
14
+ s.rubyforge_project = 'riemann-aws'
15
+
16
+ s.name = 'riemann-aws'
17
+ s.version = '0.1.4'
18
+ s.author = 'Kyle Kingsbury'
19
+ s.email = 'aphyr@aphyr.com'
20
+ s.homepage = 'https://github.com/riemann/riemann-tools'
21
+ s.platform = Gem::Platform::RUBY
22
+ s.summary = 'Submits AWS stats to riemann.'
23
+ s.license = 'MIT'
24
+
25
+ s.add_dependency 'riemann-tools', '>= 0.2.13'
26
+ s.add_dependency 'fog', '>= 1.4.0'
27
+ s.add_dependency 'json'
28
+
29
+ s.files = FileList['bin/*', 'LICENSE', 'README.md'].to_a
30
+ s.executables |= Dir.entries('bin/')
31
+ s.has_rdoc = false
32
+
33
+ s.required_ruby_version = '>= 1.8.7'
34
+ end
35
+
36
+ Gem::PackageTask.new gemspec do |p|
37
+ end
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools'
7
+
8
+ $0 = __FILE__
9
+
10
+ module Riemann
11
+ module Tools
12
+ class AWSBilling
13
+ include Riemann::Tools
14
+ require 'fog'
15
+
16
+ opt :fog_credentials_file, 'Fog credentials file', type: String
17
+ opt :fog_credential, 'Fog credentials to use', type: String
18
+
19
+ opt :access_key, 'AWS access key', type: String
20
+ opt :secret_key, 'Secret access key', type: String
21
+ opt :services, 'AWS services: AmazonEC2 AmazonS3 AWSDataTransfer', type: :strings, multi: true,
22
+ default: %w[AmazonEC2 AmazonS3 AWSDataTransfer]
23
+
24
+ opt :time_start, 'Start time in seconds of the metrics period (2hrs ago default)', type: Integer,
25
+ default: 7200
26
+ opt :time_end, 'End time in seconds of the metrics period ', type: Integer, default: 60
27
+
28
+ def initialize
29
+ if options[:fog_credentials_file]
30
+ Fog.credentials_path = opts[:fog_credentials_file]
31
+ Fog.credential = opts[:fog_credential].to_sym
32
+ @cloudwatch = Fog::AWS::CloudWatch.new
33
+ else
34
+ creds = if opts.key?('secret_key') && opts.key?('access_key')
35
+ {
36
+ aws_secret_access_key: opts[:secret_key],
37
+ aws_access_key_id: opts[:access_key],
38
+ }
39
+ else
40
+ { use_iam_profile: true }
41
+ end
42
+ @cloudwatch = Fog::AWS::CloudWatch.new(creds)
43
+ end
44
+ @start_time = (Time.now.utc - opts[:time_start]).iso8601
45
+ @end_time = (Time.now.utc - opts[:time_end]).iso8601
46
+ end
47
+
48
+ def tick
49
+ opts[:services].each do |service|
50
+ data = @cloudwatch.get_metric_statistics({
51
+ 'Statistics' => ['Maximum'],
52
+ 'StartTime' => @start_time,
53
+ 'EndTime' => @end_time,
54
+ 'Period' => 3600,
55
+ 'Unit' => 'None',
56
+ 'MetricName' => 'EstimatedCharges',
57
+ 'Namespace' => 'AWS/Billing',
58
+ 'Dimensions' => [
59
+ {
60
+ 'Name' => 'ServiceName',
61
+ 'Value' => service,
62
+ },
63
+ {
64
+ 'Name' => 'Currency',
65
+ 'Value' => 'USD',
66
+ },
67
+ ],
68
+ }).body['GetMetricStatisticsResult']['Datapoints']
69
+
70
+ data.each do |metrics|
71
+ name = "AWScloudwatch.Billing.#{service}"
72
+ value = metrics['Maximum']
73
+ timestamp = metrics['Timestamp'].to_i
74
+
75
+ event = {
76
+ host: nil,
77
+ service: name,
78
+ time: timestamp,
79
+ description: "AWS Estimate Charges for #{service}",
80
+ tags: ['aws_billing'],
81
+ state: 'ok',
82
+ metric: value,
83
+ }
84
+
85
+ report event
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ Riemann::Tools::AWSBilling.run
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools'
7
+
8
+ $0 = __FILE__ # Let's not expose our AWS keys in the process list
9
+
10
+ module Riemann
11
+ module Tools
12
+ class AWS
13
+ include Riemann::Tools
14
+ require 'fog'
15
+ require 'date'
16
+ require 'time'
17
+ require 'json'
18
+
19
+ opt :access_key, 'AWS access key', type: String
20
+ opt :secret_key, 'Secret access key', type: String
21
+ opt :region, 'AWS region', type: String, default: 'eu-west-1'
22
+ opt :dbinstance_identifier, 'DBInstanceIdentifier', type: String
23
+ def initialize
24
+ abort 'FATAL: specify a DB instance name, see --help for usage' unless opts[:dbinstance_identifier]
25
+ creds = if opts[:access_key] && opts[:secret_key]
26
+ {
27
+ aws_access_key_id: opts[:access_key],
28
+ aws_secret_access_key: opts[:secret_key],
29
+ }
30
+ else
31
+ { use_iam_profile: true }
32
+ end
33
+ creds['region'] = opts[:region]
34
+ @cloudwatch = Fog::AWS::CloudWatch.new(creds)
35
+ end
36
+
37
+ def tick
38
+ time = Time.new
39
+ %w[DatabaseConnections FreeableMemory FreeStorageSpace NetworkReceiveThroughput
40
+ NetworkTransmitThroughput ReadThroughput CPUUtilization].each do |metric|
41
+ result = @cloudwatch.get_metric_statistics(
42
+ 'Namespace' => 'AWS/RDS',
43
+ 'MetricName' => metric.to_s,
44
+ 'Statistics' => 'Average',
45
+ 'Dimensions' => [{ 'Name' => 'DBInstanceIdentifier', 'Value' => opts[:dbinstance_identifier].to_s }],
46
+ 'StartTime' => (time - 120).to_time.iso8601,
47
+ 'EndTime' => time.to_time.iso8601, 'Period' => 60,
48
+ )
49
+ metrics_result = result.data[:body]['GetMetricStatisticsResult']
50
+ next unless metrics_result['Datapoints'].length.positive?
51
+
52
+ datapoint = metrics_result['Datapoints'][0]
53
+ ev = {
54
+ metric: datapoint['Average'],
55
+ service: "#{opts[:dbinstance_identifier]}.#{metric} (#{datapoint['Unit']})",
56
+ description: JSON.dump(metrics_result),
57
+ state: 'ok',
58
+ ttl: 300,
59
+ }
60
+
61
+ report ev
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ Riemann::Tools::AWS.run
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools'
7
+
8
+ $0 = __FILE__ # Let's not expose our AWS keys in the process list
9
+
10
+ module Riemann
11
+ module Tools
12
+ class AWS
13
+ include Riemann::Tools
14
+ require 'fog'
15
+
16
+ opt :access_key, 'AWS access key', type: String
17
+ opt :secret_key, 'Secret access key', type: String
18
+ opt :region, 'AWS region', type: String, default: 'us-east-1'
19
+ opt :queue, 'SQS Queue name', type: String
20
+ def initialize
21
+ creds = if opts.key?('access_key') && opts.key?('secret_key')
22
+ {
23
+ aws_access_key_id: opts[:access_key],
24
+ aws_secret_access_key: opts[:secret_key],
25
+ }
26
+ else
27
+ { use_iam_profile: true }
28
+ end
29
+ creds['region'] = opts[:region]
30
+ @sqs = Fog::AWS::SQS.new(creds)
31
+ response = @sqs.list_queues({ 'QueueNamePrefix' => opts[:queue] })
32
+ @queue_url = response[:body]['QueueUrls'].first
33
+ end
34
+
35
+ def tick
36
+ response = @sqs.get_queue_attributes(@queue_url, 'All')
37
+ %w[ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible].each do |attr|
38
+ msg = {
39
+ metric: response[:body]['Attributes'][attr],
40
+ service: "#{opts[:queue]} #{attr}",
41
+ state: 'ok',
42
+ }
43
+ report msg
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ Riemann::Tools::AWS.run
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools'
7
+
8
+ $0 = __FILE__ # Let's not expose our AWS keys in the process list
9
+
10
+ module Riemann
11
+ module Tools
12
+ class AWS
13
+ include Riemann::Tools
14
+ require 'fog'
15
+ require 'date'
16
+
17
+ opt :access_key, 'AWS access key', type: String
18
+ opt :secret_key, 'Secret access key', type: String
19
+ opt :region, 'AWS region', type: String, default: 'eu-west-1'
20
+
21
+ opt :retirement_critical, 'Number of days before retirement. Defaults to 2', default: 2
22
+ opt :event_warning, 'Number of days before event. Defaults to nil (i.e. when the event appears)', default: nil
23
+
24
+ def initialize
25
+ creds = if opts.key?('secret_key') && opts.key?('access_key')
26
+ {
27
+ aws_secret_access_key: opts[:secret_key],
28
+ aws_access_key_id: opts[:access_key],
29
+ }
30
+ else
31
+ { use_iam_profile: true }
32
+ end
33
+ creds['region'] = opts[:region]
34
+ creds['provider'] = 'AWS'
35
+ @compute = Fog::Compute.new(creds)
36
+ end
37
+
38
+ def tick
39
+ # XXX: needs work:
40
+ # * instance_status and status seems unused
41
+ # * where is inject comming from
42
+ # It looks line the only needed line for the 2 next paragraph is the one that assigns hosts.
43
+ instance_status = @compute.describe_instance_status.body['instanceStatusSet']
44
+ status = instance_status.each_with_object({}) do |i, acc|
45
+ acc[i.delete('instanceId')] = i
46
+ end
47
+
48
+ hosts = @compute.servers.select { |s| s.state == 'running' }
49
+ inject([status, {}]) do |(astatus, acc), host|
50
+ acc[host.private_dns_name] = astatus.delete(host.id)
51
+ [astatus, acc]
52
+ end[1]
53
+
54
+ hosts.each do |host, host_status|
55
+ host_status['eventsSet'].each do |event|
56
+ before, _after = %w[notBefore notAfter].map { |k| Date.parse event[k].to_s if event[k] }
57
+
58
+ ev = {
59
+ host: host,
60
+ service: 'aws_instance_status',
61
+ description: "#{event['code']}\n\nstart #{event['notBefore']}\nend #{event['notAfter']}\n\n#{event['description']}",
62
+ state: 'ok',
63
+ ttl: 300,
64
+ }
65
+
66
+ ev2 = if (event['code'] == 'instance-retirement') &&
67
+ (Date.today >= before - opts[:retirement_critical])
68
+ { state: 'critical' }
69
+ elsif opts[:event_warning] && (Date.today >= before - opts[:event_warning])
70
+ { state: 'warning' }
71
+ else
72
+ { state: 'warning' }
73
+ end
74
+
75
+ report ev.merge(ev2)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ Riemann::Tools::AWS.run
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools'
7
+
8
+ $0 = __FILE__
9
+
10
+ module Riemann
11
+ module Tools
12
+ class ELBMetrics
13
+ include Riemann::Tools
14
+ require 'fog'
15
+ require 'time'
16
+
17
+ opt :fog_credentials_file, 'Fog credentials file', type: String
18
+ opt :fog_credential, 'Fog credentials to use', type: String
19
+ opt :aws_access, 'AWS Access Key', type: String
20
+ opt :aws_secret, 'AWS Secret Key', type: String
21
+ opt :aws_region, 'AWS Region', type: String, default: 'eu-west-1'
22
+ opt :aws_azs, 'List of AZs to aggregate against', type: :strings, default: ['all_az']
23
+ opt :elbs, 'List of ELBs to pull metrics from', type: :strings, required: true
24
+
25
+ def standard_metrics
26
+ # ELB metric types, from:
27
+ # http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#elb-metricscollected
28
+ {
29
+ 'Latency' => {
30
+ 'Unit' => 'Seconds',
31
+ 'Statistics' => %w[Maximum Minimum Average],
32
+ },
33
+ 'RequestCount' => {
34
+ 'Unit' => 'Count',
35
+ 'Statistics' => ['Sum'],
36
+ },
37
+ 'HealthyHostCount' => {
38
+ 'Units' => 'Count',
39
+ 'Statistics' => %w[Minimum Maximum Average],
40
+ },
41
+ 'UnHealthyHostCount' => {
42
+ 'Units' => 'Count',
43
+ 'Statistics' => %w[Minimum Maximum Average],
44
+ },
45
+ 'HTTPCode_ELB_4XX' => {
46
+ 'Units' => 'Count',
47
+ 'Statistics' => ['Sum'],
48
+ },
49
+ 'HTTPCode_ELB_5XX' => {
50
+ 'Units' => 'Count',
51
+ 'Statistics' => ['Sum'],
52
+ },
53
+ 'HTTPCode_Backend_2XX' => {
54
+ 'Units' => 'Count',
55
+ 'Statistics' => ['Sum'],
56
+ },
57
+ 'HTTPCode_Backend_3XX' => {
58
+ 'Units' => 'Count',
59
+ 'Statistics' => ['Sum'],
60
+ },
61
+ 'HTTPCode_Backend_4XX' => {
62
+ 'Units' => 'Count',
63
+ 'Statistics' => ['Sum'],
64
+ },
65
+ 'HTTPCode_Backend_5XX' => {
66
+ 'Units' => 'Count',
67
+ 'Statistics' => ['Sum'],
68
+ },
69
+ }
70
+ end
71
+
72
+ def base_metrics
73
+ # get last 60 seconds
74
+ start_time = (Time.now.utc - 60).iso8601
75
+ end_time = Time.now.utc.iso8601
76
+
77
+ # The base query that all metrics would get
78
+ {
79
+ 'Namespace' => 'AWS/ELB',
80
+ 'StartTime' => start_time,
81
+ 'EndTime' => end_time,
82
+ 'Period' => 60,
83
+ }
84
+ end
85
+
86
+ def tick
87
+ if options[:fog_credentials_file]
88
+ Fog.credentials_path = options[:fog_credentials_file]
89
+ Fog.credential = options[:fog_credential].to_sym
90
+ connection = Fog::AWS::CloudWatch.new
91
+ else
92
+ connection = if options[:aws_access] && options[:aws_secret]
93
+ Fog::AWS::CloudWatch.new({
94
+ aws_access_key_id: options[:aws_access],
95
+ aws_secret_access_key: options[:aws_secret],
96
+ region: options[:aws_region],
97
+ })
98
+ else
99
+ Fog::AWS::CloudWatch.new({
100
+ use_iam_profile: true,
101
+ region: options[:aws_region],
102
+ })
103
+ end
104
+ end
105
+
106
+ options[:elbs].each do |lb|
107
+ metric_options = standard_metrics
108
+ metric_base_options = base_metrics
109
+
110
+ options[:aws_azs].each do |az|
111
+ metric_options.keys.sort.each do |metric_type|
112
+ merged_options = metric_base_options.merge(metric_options[metric_type])
113
+ merged_options['MetricName'] = metric_type
114
+ merged_options['Dimensions'] = if az == 'all_az'
115
+ [{ 'Name' => 'LoadBalancerName', 'Value' => lb }]
116
+ else
117
+ [
118
+ { 'Name' => 'LoadBalancerName', 'Value' => lb },
119
+ { 'Name' => 'AvailabilityZone', 'Value' => az },
120
+ ]
121
+ end
122
+
123
+ result = connection.get_metric_statistics(merged_options)
124
+
125
+ # "If no response codes in the category 2XX-5XX range are sent to clients within
126
+ # the given time period, values for these metrics will not be recorded in CloudWatch"
127
+ # next if result.body["GetMetricStatisticsResult"]["Datapoints"].empty? && metric_type =~ /[2345]XX/
128
+ #
129
+ if result.body['GetMetricStatisticsResult']['Datapoints'].empty?
130
+ standard_metrics[metric_type]['Statistics'].each do |stat_type|
131
+ event = event(lb, az, metric_type, stat_type, 0.0)
132
+ report(event)
133
+ end
134
+ next
135
+ end
136
+
137
+ # We should only ever have a single data point
138
+ result.body['GetMetricStatisticsResult']['Datapoints'][0].keys.sort.each do |stat_type|
139
+ next if stat_type == 'Unit'
140
+ next if stat_type == 'Timestamp'
141
+
142
+ unit = result.body['GetMetricStatisticsResult']['Datapoints'][0]['Unit']
143
+ metric = result.body['GetMetricStatisticsResult']['Datapoints'][0][stat_type]
144
+ event = event(lb, az, metric_type, stat_type, metric, unit)
145
+ report(event)
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ private
153
+
154
+ def event(lb, az, metric_type, stat_type, metric, unit = nil)
155
+ {
156
+ host: lb,
157
+ service: "elb.#{az}.#{metric_type}.#{stat_type}",
158
+ ttl: 60,
159
+ description: "#{lb} #{metric_type} #{stat_type} (#{unit})",
160
+ tags: ['elb_metrics'],
161
+ metric: metric,
162
+ }
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ Riemann::Tools::ELBMetrics.run