elastomer-cli 0.3.1 → 0.3.2
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 +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/elastomer/cli.rb +1 -0
- data/lib/elastomer/cli/application.rb +5 -0
- data/lib/elastomer/cli/shard_stats.rb +165 -0
- data/lib/elastomer/cli/version.rb +1 -1
- data/test/fixtures/vcr_cassettes/default.yml +62 -2
- data/test/shard_stats_test.rb +13 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 772a6ed6f013c952c66223437cd17fc820cacbe4
|
4
|
+
data.tar.gz: c8f8346f6209a636e714652792d2679f9c29debb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c2ff9ada4ac6515f836f36415a61e9316bdc9785a6827f67ca42f09e6399a72659cb026b534e3b91f05c67b1eddf2a1360dcbfbf6c290a2e843fac71152fba0
|
7
|
+
data.tar.gz: fb7ed301f832fea0378f085945c986102886ce0fa5af4215a16fe9c3df82559a6d301d1ef57abb0331037790868af71c8b2448ae1d0bff2cab0a01cbae82a2ca
|
data/CHANGELOG.md
CHANGED
data/lib/elastomer/cli.rb
CHANGED
@@ -17,6 +17,11 @@ module Elastomer
|
|
17
17
|
desc "snapshot SUBCOMMAND ...ARGS", "execute snapshot commands"
|
18
18
|
subcommand "snapshot", Snapshot
|
19
19
|
|
20
|
+
desc "shard_stats", "show shard count and disk usage for all indices across all nodes"
|
21
|
+
def shard_stats
|
22
|
+
puts ShardStats.table
|
23
|
+
end
|
24
|
+
|
20
25
|
desc "cat [COMMAND] [SCOPE] ...ARGS", "access the ES cat api"
|
21
26
|
long_desc <<-LONGDESC
|
22
27
|
Access the ES cat api. The cat api returns text formatted for humans.
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module Elastomer
|
2
|
+
module CLI
|
3
|
+
class ShardStats < Base
|
4
|
+
no_commands do
|
5
|
+
def self.table
|
6
|
+
self.new.table
|
7
|
+
end
|
8
|
+
|
9
|
+
def table
|
10
|
+
Terminal::Table.new do |table|
|
11
|
+
table << node_names.dup.unshift(nil)
|
12
|
+
table << generate_row("total", node_data)
|
13
|
+
table << :separator
|
14
|
+
|
15
|
+
index_data.keys.sort.each do |index_name|
|
16
|
+
table << generate_row(index_name, index_data[index_name])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_row(title, data)
|
22
|
+
row = node_names.map do |node_name|
|
23
|
+
|
24
|
+
total = total_disk_size_for_node(node_name)
|
25
|
+
data_for_node = data[node_name]
|
26
|
+
shards = data_for_node["shards"]
|
27
|
+
|
28
|
+
if shards > 0
|
29
|
+
usage = data_for_node["size"].to_f / total.to_f * 100.0
|
30
|
+
"%d : %.1f%" % [shards, usage]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
row.unshift title
|
35
|
+
row
|
36
|
+
end
|
37
|
+
|
38
|
+
# Collect data for each index broken down by node. This is a Hash keyed by
|
39
|
+
# index name. The value for each index is another Hash that contains shard
|
40
|
+
# information for each node in the cluster that holds shards for the index.
|
41
|
+
#
|
42
|
+
# {
|
43
|
+
# "index1" => {
|
44
|
+
# "storage1 => {
|
45
|
+
# "shards" => 2,
|
46
|
+
# "size" => 1024 # size in bytes
|
47
|
+
# },
|
48
|
+
# "storage2 => {
|
49
|
+
# "shards" => 1,
|
50
|
+
# "size" => 512 # size in bytes
|
51
|
+
# }
|
52
|
+
# },
|
53
|
+
# "index2" => {
|
54
|
+
# "storage2 => {
|
55
|
+
# "shards" => 1,
|
56
|
+
# "size" => 2048
|
57
|
+
# },
|
58
|
+
# "storage3 => {
|
59
|
+
# "shards" => 1,
|
60
|
+
# "size" => 2048
|
61
|
+
# }
|
62
|
+
# }
|
63
|
+
# ...
|
64
|
+
# }
|
65
|
+
#
|
66
|
+
# Only shards that are in the STARTED state will count towards these metrics.
|
67
|
+
def index_data
|
68
|
+
return @index_data if defined? @index_data
|
69
|
+
|
70
|
+
@index_data = Hash.new do |index_hash, index_name|
|
71
|
+
index_hash[index_name] = Hash.new do |node_hash, node_name|
|
72
|
+
node_hash[node_name] = {
|
73
|
+
"shards" => 0,
|
74
|
+
"size" => 0
|
75
|
+
}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
client.get("/_cat/shards", :h => "index,state,store,node", :bytes => "b").body.split("\n").each do |row|
|
80
|
+
index, state, size, node = row.split(%r/\s+/)
|
81
|
+
next unless state == "STARTED"
|
82
|
+
|
83
|
+
node_stats_for_index = @index_data[index][node]
|
84
|
+
node_stats_for_index["shards"] += 1
|
85
|
+
node_stats_for_index["size"] += Integer(size)
|
86
|
+
end
|
87
|
+
|
88
|
+
@index_data
|
89
|
+
end
|
90
|
+
|
91
|
+
# Take the `index_data` and roll up shard counts and size at the node level.
|
92
|
+
# This information will be reported in the `node_data` method.
|
93
|
+
def shard_data_by_node
|
94
|
+
nodes = Hash.new do |hash, name|
|
95
|
+
hash[name] = {
|
96
|
+
"shards" => 0,
|
97
|
+
"size" => 0
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
index_data.values.each do |hash|
|
102
|
+
hash.each do |name, data|
|
103
|
+
nodes[name]["shards"] += data["shards"]
|
104
|
+
nodes[name]["size"] += data["size"]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
nodes
|
109
|
+
end
|
110
|
+
|
111
|
+
# Collect data about the file system usage and shard counts for each node in
|
112
|
+
# the cluster.
|
113
|
+
#
|
114
|
+
# {
|
115
|
+
# "storage1" => {
|
116
|
+
# "total" => 4294967296, # size in bytes
|
117
|
+
# "free" => 1073741824, # size in bytes
|
118
|
+
# "shards" => 17,
|
119
|
+
# "size" => 3221225472 # size in bytes
|
120
|
+
# },
|
121
|
+
# "storage2" => {
|
122
|
+
# "total" => 4294967296,
|
123
|
+
# "free" => 1073741824,
|
124
|
+
# "shards" => 17,
|
125
|
+
# "size" => 3221225472
|
126
|
+
# },
|
127
|
+
# ...
|
128
|
+
# }
|
129
|
+
#
|
130
|
+
def node_data
|
131
|
+
return @node_data if defined? @node_data
|
132
|
+
|
133
|
+
@node_data = {}
|
134
|
+
shard_data = shard_data_by_node
|
135
|
+
|
136
|
+
client.nodes.stats(:stats => "fs")["nodes"].values.each do |hash|
|
137
|
+
data_node = hash["attributes"]["data"]
|
138
|
+
next if data_node == "false" || data_node == false
|
139
|
+
|
140
|
+
name = hash["name"]
|
141
|
+
fs = hash["fs"]["total"]
|
142
|
+
|
143
|
+
@node_data[name] = {
|
144
|
+
"total" => fs["total_in_bytes"],
|
145
|
+
"free" => fs["available_in_bytes"]
|
146
|
+
}.merge(shard_data[name])
|
147
|
+
end
|
148
|
+
|
149
|
+
@node_data
|
150
|
+
end
|
151
|
+
|
152
|
+
# Returns the total size of the disk for the given cluster node.
|
153
|
+
def total_disk_size_for_node(name)
|
154
|
+
node_data[name]["total"]
|
155
|
+
end
|
156
|
+
|
157
|
+
# Returns the names of the nodes in the cluster sorted alphabetically.
|
158
|
+
def node_names
|
159
|
+
@node_names ||= node_data.keys.sort
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -527,7 +527,67 @@ http_interactions:
|
|
527
527
|
- '121'
|
528
528
|
body:
|
529
529
|
encoding: UTF-8
|
530
|
-
string:
|
530
|
+
string: '{"acknowledged":true,"persistent":{"cluster.routing.allocation.enable":"all","indices.ttl.interval":"70"},"transient":{}}'
|
531
531
|
http_version:
|
532
532
|
recorded_at: Thu, 18 Dec 2014 00:51:29 GMT
|
533
|
-
|
533
|
+
- request:
|
534
|
+
method: get
|
535
|
+
uri: http://127.0.0.1:19200/_cat/shards?bytes=b&h=index,state,store,node
|
536
|
+
body:
|
537
|
+
encoding: US-ASCII
|
538
|
+
string: ''
|
539
|
+
headers:
|
540
|
+
User-Agent:
|
541
|
+
- Faraday v0.9.2
|
542
|
+
Accept-Encoding:
|
543
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
544
|
+
Accept:
|
545
|
+
- "*/*"
|
546
|
+
response:
|
547
|
+
status:
|
548
|
+
code: 200
|
549
|
+
message: OK
|
550
|
+
headers:
|
551
|
+
Content-Type:
|
552
|
+
- text/plain; charset=UTF-8
|
553
|
+
Content-Length:
|
554
|
+
- '444'
|
555
|
+
body:
|
556
|
+
encoding: UTF-8
|
557
|
+
string: "hi STARTED 115 boxen \nbleh STARTED 115
|
558
|
+
boxen \nblog-1 STARTED 115 boxen \nusers-1 STARTED 115
|
559
|
+
boxen \nfoo STARTED 115 boxen \nshowcases-1 STARTED 115
|
560
|
+
boxen \naudit_log-2015-08 STARTED 115 boxen \nrepos-1 STARTED 115
|
561
|
+
boxen \nissues-1 STARTED 115 boxen \ncode-search-1 STARTED 115
|
562
|
+
boxen \ngists-1 STARTED 115 boxen \npull-requests-1 STARTED 115
|
563
|
+
boxen \n"
|
564
|
+
http_version:
|
565
|
+
recorded_at: Tue, 27 Oct 2015 23:40:41 GMT
|
566
|
+
- request:
|
567
|
+
method: get
|
568
|
+
uri: http://127.0.0.1:19200/_nodes/_all/stats/fs
|
569
|
+
body:
|
570
|
+
encoding: US-ASCII
|
571
|
+
string: ''
|
572
|
+
headers:
|
573
|
+
User-Agent:
|
574
|
+
- Faraday v0.9.2
|
575
|
+
Accept-Encoding:
|
576
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
577
|
+
Accept:
|
578
|
+
- "*/*"
|
579
|
+
response:
|
580
|
+
status:
|
581
|
+
code: 200
|
582
|
+
message: OK
|
583
|
+
headers:
|
584
|
+
Content-Type:
|
585
|
+
- application/json; charset=UTF-8
|
586
|
+
Content-Length:
|
587
|
+
- '899'
|
588
|
+
body:
|
589
|
+
encoding: UTF-8
|
590
|
+
string: '{"cluster_name":"elasticsearch_boxen_chrismwendt","nodes":{"ekfO1wDuQ8m1YLD-i39lhQ":{"timestamp":1445989241430,"name":"boxen","transport_address":"inet[/127.0.0.1:19300]","host":"Chriss-MacBook-Air.local","ip":["inet[/127.0.0.1:19300]","NONE"],"attributes":{"max_local_storage_nodes":"1"},"fs":{"timestamp":1445989241430,"total":{"total_in_bytes":499071844352,"free_in_bytes":407380561920,"available_in_bytes":407118417920,"disk_reads":0,"disk_writes":0,"disk_io_op":0,"disk_read_size_in_bytes":0,"disk_write_size_in_bytes":0,"disk_io_size_in_bytes":0},"data":[{"path":"/opt/boxen/data/elasticsearch/elasticsearch_boxen_chrismwendt/nodes/0","mount":"/","dev":"/dev/disk1","total_in_bytes":499071844352,"free_in_bytes":407380561920,"available_in_bytes":407118417920,"disk_reads":0,"disk_writes":0,"disk_io_op":0,"disk_read_size_in_bytes":0,"disk_write_size_in_bytes":0,"disk_io_size_in_bytes":0}]}}}}'
|
591
|
+
http_version:
|
592
|
+
recorded_at: Tue, 27 Oct 2015 23:40:41 GMT
|
593
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Elastomer::CLI::ShardStats do
|
4
|
+
describe 'shard_stats' do
|
5
|
+
it 'should show shard stats' do
|
6
|
+
VCR.use_cassette('default') do
|
7
|
+
elastomer 'shard_stats'
|
8
|
+
@out.must_match /total.*12/m
|
9
|
+
@out.must_match /audit_log/m
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastomer-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grant Rodgers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -146,6 +146,7 @@ files:
|
|
146
146
|
- lib/elastomer/cli/index.rb
|
147
147
|
- lib/elastomer/cli/node.rb
|
148
148
|
- lib/elastomer/cli/repository.rb
|
149
|
+
- lib/elastomer/cli/shard_stats.rb
|
149
150
|
- lib/elastomer/cli/snapshot.rb
|
150
151
|
- lib/elastomer/cli/version.rb
|
151
152
|
- script/bootstrap
|
@@ -165,6 +166,7 @@ files:
|
|
165
166
|
- test/index_test.rb
|
166
167
|
- test/node_test.rb
|
167
168
|
- test/repository_test.rb
|
169
|
+
- test/shard_stats_test.rb
|
168
170
|
- test/snapshot_test.rb
|
169
171
|
- test/test_helper.rb
|
170
172
|
homepage: https://github.com/github/elastomer-cli
|
@@ -187,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
189
|
version: '0'
|
188
190
|
requirements: []
|
189
191
|
rubyforge_project:
|
190
|
-
rubygems_version: 2.2.
|
192
|
+
rubygems_version: 2.2.3
|
191
193
|
signing_key:
|
192
194
|
specification_version: 4
|
193
195
|
summary: Command line interface for elastomer
|
@@ -205,5 +207,7 @@ test_files:
|
|
205
207
|
- test/index_test.rb
|
206
208
|
- test/node_test.rb
|
207
209
|
- test/repository_test.rb
|
210
|
+
- test/shard_stats_test.rb
|
208
211
|
- test/snapshot_test.rb
|
209
212
|
- test/test_helper.rb
|
213
|
+
has_rdoc:
|