xmonitor 0.1.2 → 0.1.3

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: 44a174e8c7490ab651f0823a290e3b4ef94e04a2
4
- data.tar.gz: 1016331ffc5863e623e546c5d0cdae0f767cc7e7
3
+ metadata.gz: 3bae11c8a9e98c0e0747e4bc7c918b17873985a3
4
+ data.tar.gz: 77956a6841772b2da403235c0376d311272d6ce0
5
5
  SHA512:
6
- metadata.gz: 4afdce528b340efae2305e444a18d03812b873c799b8110934d9207e69bce9f8c77ad2892234b212f297a2295a1aab5d392f2906ea98be75b6e4bf9d31f0722c
7
- data.tar.gz: fc7f46884fcab312fb2e7350e2b62aad76ae4ee3827fe91698dccf8c94f8ff6e5932bfd3241105b3f4c8862830d0a13746fde2587d4cac61fab6d23604896eae
6
+ metadata.gz: f8daf556fb7562912b9bc01b0e4aad84b3c508836a145b11e3dd9394aad3698d45f36a686f664a35112248bba51f6982ea6bbff204055125ddd046f6222db6a0
7
+ data.tar.gz: f095fe8d5dbdfd3ecfb7500a4c3c60910a046c529091b7efb0b7858bc9b726de5b1fb6ee06b5142520ac2ed94756591dc1d3ffaa428748345395a3e7b5c51cbb
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "xmonitor"
4
+
5
+ Xmonitor::Dashboard.start ARGV
@@ -6,10 +6,15 @@ module Xmonitor
6
6
  require "yaml"
7
7
  require "json"
8
8
  require "irb"
9
+ require "csv"
9
10
 
10
11
  require "posixpsutil"
11
12
  require "aws-sdk-firehose"
13
+ require "aws-sdk-athena"
14
+ require "aws-sdk-s3"
12
15
 
13
16
  require "xmonitor/config"
14
17
  require "xmonitor/agent"
18
+
19
+ autoload :Dashboard, 'xmonitor/dashboard'
15
20
  end
@@ -56,6 +56,7 @@ class Xmonitor::Agent
56
56
 
57
57
  def monitor
58
58
  records = grab
59
+
59
60
  raise GrabError if records.empty?
60
61
 
61
62
  data = records.join(NEW_LINE) + NEW_LINE
@@ -64,7 +65,7 @@ class Xmonitor::Agent
64
65
  end
65
66
 
66
67
  def grab
67
- grab_cpu + grab_memory
68
+ grab_cpu + grab_memory + grab_disks + grab_network
68
69
  rescue => e
69
70
  raise GrabError.new(e)
70
71
  end
@@ -81,6 +82,47 @@ class Xmonitor::Agent
81
82
  }
82
83
  end
83
84
 
85
+ def grab_disks
86
+ grab_disks_usage + grab_disks_io_counter
87
+ end
88
+
89
+ def grab_disks_usage
90
+ devices = PosixPsutil::Disks.disk_partitions.map{|partition| partition.device}
91
+
92
+ devices.map{|device|
93
+ PosixPsutil::Disks.disk_usage(device).each_pair.map{|(k, v)|
94
+ metric = "#{device}.#{k}"
95
+ create_record('disks', metric, v)
96
+ }
97
+ }.flatten
98
+ end
99
+
100
+ def grab_disks_io_counter
101
+ PosixPsutil::Disks.disk_io_counters.each_pair.map{|(k, v)|
102
+ disk = k
103
+
104
+ v.each_pair.map{|k2, v2|
105
+ metric = "#{disk}.#{k2}"
106
+ create_record('disks', metric, v2)
107
+ }
108
+ }.flatten
109
+ end
110
+
111
+ def grab_network
112
+ grab_net_io_counter
113
+ end
114
+
115
+ def grab_net_io_counter
116
+ PosixPsutil::Network.net_io_counters(true).each_pair.map{|(k, v)|
117
+ interface = k
118
+
119
+ v.each_pair.map{|k2, v2|
120
+ metric = "#{interface}.#{k2}"
121
+ create_record('network', metric, v2)
122
+ }
123
+ }.flatten
124
+ end
125
+
84
126
  def create_record(metric, dimension, value)
85
127
  {timestamp: Time.now.strftime(TIME_FORMAT), host: @hostname, metric: metric, dimension: dimension, value: value}.to_json
86
128
  end
@@ -1,18 +1,21 @@
1
1
  class Xmonitor::Config
2
- attr_reader :region, :stream_name, :access_key_id, :secret_access_key,
2
+ attr_reader :region, :stream_name, :access_key_id, :secret_access_key, :athena_database, :athena_s3_bucket, :athena_table_name
3
3
 
4
4
  KEY_REGION = 'region'
5
5
  KEY_STREAM_NAME = 'stream_name'
6
6
  KEY_ACCESS_KEY_ID = 'access_key_id'
7
7
  KEY_SECRET_ACCESS_KEY = 'secret_access_key'
8
+ KEY_ATHENA_DATABASE = 'athena_database'
9
+ KEY_ATHENA_S3_BUCKET = 'athena_s3_bucket'
10
+ KEY_ATHENA_TABLE_NAME = 'athena_table_name'
8
11
 
9
12
  def self.from_yaml(path)
10
- json = YAML.load(File.read(path))
13
+ yaml = YAML.load(File.read(path))
11
14
 
12
- self.new(json[KEY_REGION], json[KEY_STREAM_NAME], json[KEY_ACCESS_KEY_ID], json[KEY_SECRET_ACCESS_KEY])
15
+ self.new(yaml[KEY_REGION], yaml[KEY_STREAM_NAME], yaml[KEY_ACCESS_KEY_ID], yaml[KEY_SECRET_ACCESS_KEY], yaml[KEY_ATHENA_DATABASE], yaml[KEY_ATHENA_S3_BUCKET], yaml[KEY_ATHENA_TABLE_NAME])
13
16
  end
14
17
 
15
18
  def initialize(*args)
16
- @region, @stream_name, @access_key_id, @secret_access_key = *args
19
+ @region, @stream_name, @access_key_id, @secret_access_key, @athena_database, @athena_s3_bucket, @athena_table_name = *args
17
20
  end
18
21
  end
@@ -0,0 +1,79 @@
1
+ class Xmonitor::Dashboard
2
+ def self.start(argv)
3
+ config_file = argv[0]
4
+
5
+ config = Xmonitor::Config.from_yaml(config_file)
6
+
7
+ server = self.new(config)
8
+
9
+ server.run
10
+ end
11
+
12
+ def initialize(config)
13
+ @config = config
14
+ @logger = Logger.new(STDERR)
15
+ end
16
+
17
+ def run
18
+ init_aws_config_and_clients
19
+
20
+ query_execution_response = start_query_execution(all_metrics_by_hour_query)
21
+
22
+ query_execution_id = query_execution_response.query_execution_id
23
+ @logger.info(query_execution_id: query_execution_id)
24
+
25
+ last_get_query_execution_response = wait_for_finish_query_execution(query_execution_id)
26
+
27
+ output_location = last_get_query_execution_response.query_execution.result_configuration.output_location
28
+ @logger.info(output_location: output_location)
29
+
30
+ get_s3_object_and_process_body(output_location) do |body|
31
+ CSV.new(body, headers: true).each{|row|
32
+ puts [Time.parse(row[0]), row[1], row[2], row[3], row[4].to_f].to_csv
33
+ }
34
+ end
35
+ rescue StandardError => e
36
+ @logger.error(error: e, backtrace: e.backtrace)
37
+ end
38
+
39
+ def init_aws_config_and_clients
40
+ Aws.config[:credentials] = Aws::Credentials.new(@config.access_key_id, @config.secret_access_key)
41
+
42
+ @athena = Aws::Athena::Client.new(region: @config.region)
43
+ @s3 = Aws::S3::Client.new(region: @config.region)
44
+ end
45
+
46
+ def all_metrics_by_hour_query
47
+ 'SELECT DATE_FORMAT(timestamp, \'%Y-%m-%d %H:00:00\') AS _timestamp, host AS _host, metric AS _metric, dimension AS _dimension, AVG(value) AS _value FROM "' + @config.athena_database + '"."' + @config.athena_table_name + '" GROUP BY DATE_FORMAT(timestamp, \'%Y-%m-%d %H:00:00\'), host, metric, dimension ORDER BY _host, _metric, _dimension, _timestamp DESC;'
48
+ end
49
+
50
+ def start_query_execution(query_string)
51
+ @athena.start_query_execution(
52
+ query_string: query_string,
53
+ query_execution_context: {database: @config.athena_database},
54
+ result_configuration: {output_location: "s3://#{@config.athena_s3_bucket}/"}
55
+ ).tap{|response|
56
+ @logger.info(response: response)
57
+ }
58
+ end
59
+
60
+ def wait_for_finish_query_execution(query_execution_id)
61
+ loop do
62
+ response = @athena.get_query_execution(query_execution_id: query_execution_id)
63
+
64
+ @logger.info(response: response)
65
+
66
+ state = response.query_execution.status.state
67
+
68
+ return response unless ['QUEUED', 'RUNNING'].include?(state)
69
+
70
+ sleep 1
71
+ end
72
+ end
73
+
74
+ def get_s3_object_and_process_body(s3_object_arn, &blk)
75
+ _, bucket, key = s3_object_arn.match(/s3:\/\/(.+?)\/(.+)$/).to_a
76
+
77
+ yield @s3.get_object(bucket: bucket, key: key).body
78
+ end
79
+ end
@@ -1,3 +1,3 @@
1
1
  module Xmonitor
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -25,5 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "minitest", "~> 5.0"
27
27
  spec.add_runtime_dependency "aws-sdk-firehose", "~> 1.1"
28
+ spec.add_runtime_dependency "aws-sdk-athena", "~> 1.0"
29
+ spec.add_runtime_dependency "aws-sdk-s3", "~> 1.8"
28
30
  spec.add_runtime_dependency "posixpsutil", "~> 0.1"
29
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xmonitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - xmisao
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-25 00:00:00.000000000 Z
11
+ date: 2017-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: aws-sdk-athena
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: aws-sdk-s3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.8'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.8'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: posixpsutil
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -86,6 +114,7 @@ email:
86
114
  - mail@xmisao.com
87
115
  executables:
88
116
  - xmonitor
117
+ - xmonitor_dashboard
89
118
  extensions: []
90
119
  extra_rdoc_files: []
91
120
  files:
@@ -99,9 +128,11 @@ files:
99
128
  - bin/console
100
129
  - bin/setup
101
130
  - exe/xmonitor
131
+ - exe/xmonitor_dashboard
102
132
  - lib/xmonitor.rb
103
133
  - lib/xmonitor/agent.rb
104
134
  - lib/xmonitor/config.rb
135
+ - lib/xmonitor/dashboard.rb
105
136
  - lib/xmonitor/version.rb
106
137
  - xmonitor.gemspec
107
138
  homepage: https://github.com/xmisao/xmonitor