hotdog 0.0.2 → 0.0.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: c0f33496f07a7069e8a6fab90cf456a98f80e986
4
- data.tar.gz: d7bfd8130aa345ff212cabb30f06ddb83b286a46
3
+ metadata.gz: 9ec9c646216c6e398de74ef323b24368fb50ebb9
4
+ data.tar.gz: afbfbb8ae6fde51f3eb651385263c9294c22c864
5
5
  SHA512:
6
- metadata.gz: 5c3aa62c94710e8bd3e1c738489782cfce401a3942d46be03128c4fc427719bba81f74d4cdf108c3cb9c3382ad83bdc2ba4085ca4f554ec2496fcdcb2b6a3b39
7
- data.tar.gz: 19fce13c8757dd1fb0437abd99027d0d10ecbea68ca2db57808da119745fafbb0c704b588480f75682de5b7a12509829e2fe27c572ae1f09da5192ca5d2ace41
6
+ metadata.gz: c2ac8c3bb3d161d8f3ce102ce4a61c022d55b7dc165df776d5b8be31c85d3b103d88516bf60206efac7dbeabe7e26a4a2054d65a0728fff56fc5d2116a26dafc
7
+ data.tar.gz: 55df8e863c2b6234bd593073ea958fdb25d6232de94fd9f499ec6a6530abc5b1b26ac5f6b6f6e7237be16136743016b981a0854b2c6f77ac128aaa9039465627
@@ -15,12 +15,13 @@ module Hotdog
15
15
  @options = {
16
16
  environment: "default",
17
17
  minimum_expiry: 28800, # 8 hours
18
- random_expiry: 57600, # 16 hours
18
+ random_expiry: 604800, # 7 days
19
19
  force: false,
20
20
  formatter: get_formatter("plain").new,
21
21
  headers: false,
22
22
  listing: false,
23
23
  logger: Logger.new(STDERR),
24
+ max_time: 30,
24
25
  api_key: ENV["DATADOG_API_KEY"],
25
26
  application_key: ENV["DATADOG_APPLICATION_KEY"],
26
27
  print0: false,
@@ -54,14 +55,19 @@ module Hotdog
54
55
 
55
56
  begin
56
57
  command = ( args.shift || "help" )
57
- run_command(command, args)
58
+ c = run_command(command, args)
59
+ if c.suspended?
60
+ exit(2)
61
+ end
58
62
  rescue Errno::EPIPE
59
63
  # nop
60
64
  end
61
65
  end
62
66
 
63
67
  def run_command(command, args=[])
64
- get_command(command).new(@db, options.merge(application: self)).run(args)
68
+ get_command(command).new(@db, options.merge(application: self)).tap do |c|
69
+ c.run(args)
70
+ end
65
71
  end
66
72
 
67
73
  private
@@ -72,35 +78,38 @@ module Hotdog
72
78
  @optparse.on("--application-key APP_KEY", "Datadog application key") do |app_key|
73
79
  options[:application_key] = app_key
74
80
  end
75
- @optparse.on("-0", "--null", "Use null character as separator") do
76
- options[:print0] = true
81
+ @optparse.on("-0", "--null", "Use null character as separator") do |v|
82
+ options[:print0] = v
77
83
  end
78
- @optparse.on("-1", "Use newline as separator") do
79
- options[:print1] = true
84
+ @optparse.on("-1", "Use newline as separator") do |v|
85
+ options[:print1] = v
80
86
  end
81
- @optparse.on("-d", "--debug", "Enable debug mode") do
82
- options[:logger].level = Logger::DEBUG
87
+ @optparse.on("-d", "--[no-]debug", "Enable debug mode") do |v|
88
+ options[:logger].level = v ? Logger::DEBUG : Logger::INFO
83
89
  end
84
90
  @optparse.on("-E ENVIRONMENT", "--environment ENVIRONMENT", "Specify environment") do |environment|
85
91
  options[:environment] = environment
86
92
  end
87
- @optparse.on("-f", "--force", "Enable force mode") do
88
- options[:force] = true
93
+ @optparse.on("-f", "--[no-]force", "Enable force mode") do |v|
94
+ options[:force] = v
89
95
  end
90
96
  @optparse.on("-F FORMAT", "--format FORMAT", "Specify output format") do |format|
91
97
  options[:formatter] = get_formatter(format).new
92
98
  end
93
- @optparse.on("-h", "--headers", "Display headeres for each columns") do |headers|
94
- options[:headers] = headers
99
+ @optparse.on("-h", "--[no-]headers", "Display headeres for each columns") do |v|
100
+ options[:headers] = v
95
101
  end
96
- @optparse.on("-l", "Use listing format") do
97
- options[:listing] = true
102
+ @optparse.on("-l", "--[no-]listing", "Use listing format") do |v|
103
+ options[:listing] = v
98
104
  end
99
105
  @optparse.on("-a TAG", "-t TAG", "--tag TAG", "Use specified tag name/value") do |tag|
100
106
  options[:tags] += [tag]
101
107
  end
102
- @optparse.on("-V", "--verbose", "Enable verbose mode") do |tag|
103
- options[:logger].level = Logger::DEBUG
108
+ @optparse.on("-m SECONDS", "--max-time SECONDS", Integer, "Maximum time in seconds") do |seconds|
109
+ options[:max_time] = seconds
110
+ end
111
+ @optparse.on("-V", "--[no-]verbose", "Enable verbose mode") do |v|
112
+ options[:logger].level = v ? Logger::DEBUG : Logger::INFO
104
113
  end
105
114
  end
106
115
 
@@ -36,6 +36,9 @@ module Hotdog
36
36
  execute(<<-EOS)
37
37
  CREATE INDEX IF NOT EXISTS hosts_tags_expires_at ON hosts_tags ( expires_at );
38
38
  EOS
39
+ execute(<<-EOS)
40
+ CREATE INDEX IF NOT EXISTS hosts_tags_host_id_expires_at ON hosts_tags ( host_id, expires_at );
41
+ EOS
39
42
  application.run_command("update")
40
43
  end
41
44
  end
@@ -14,6 +14,8 @@ module Hotdog
14
14
  @application = options[:application]
15
15
  @options = options
16
16
  @dog = Dogapi::Client.new(options[:api_key], options[:application_key])
17
+ @started_at = Time.new
18
+ @suspended = false
17
19
  end
18
20
  attr_reader :application
19
21
  attr_reader :formatter
@@ -34,6 +36,10 @@ module Hotdog
34
36
  @db.execute(query, args)
35
37
  end
36
38
 
39
+ def suspended?()
40
+ @suspended
41
+ end
42
+
37
43
  private
38
44
  def format(result, options={})
39
45
  @formatter.format(result, @options.merge(options))
@@ -106,10 +112,12 @@ module Hotdog
106
112
  def update_hosts(options={})
107
113
  @db.transaction do
108
114
  if not options[:force]
115
+ # Update host list on every expirations to update frequently.
109
116
  @update_hosts_q1 ||= @db.prepare("SELECT MIN(expires_at) FROM hosts_tags;")
110
117
  logger.debug("update_hosts_q1()")
111
118
  if expires_at = @update_hosts_q1.execute().map { |row| row.first }.first
112
119
  if Time.new.to_i < expires_at
120
+ logger.debug("next update will run after %s." % [Time.at(expires_at)])
113
121
  return
114
122
  else
115
123
  logger.debug("minimum expires_at was %s. start updateing." % [Time.at(expires_at)])
@@ -120,26 +128,36 @@ module Hotdog
120
128
  end
121
129
 
122
130
  code, result = @dog.search("hosts:")
131
+ logger.debug("dog.serarch(%s) #==> [%s, %s]" % ["hosts:".inspect, code.inspect, result.inspect])
123
132
  if code.to_i / 100 != 2
124
133
  raise("HTTP #{code}: #{result.inspect}")
125
134
  end
126
135
 
136
+ execute(<<-EOS % result["results"]["hosts"].map { "LOWER(?)" }.join(", "), result["results"]["hosts"])
137
+ DELETE FROM hosts_tags WHERE host_id NOT IN
138
+ ( SELECT id FROM hosts WHERE LOWER(name) IN ( %s ) );
139
+ EOS
140
+
127
141
  result["results"]["hosts"].each do |host_name|
128
142
  @update_hosts_q2 ||= @db.prepare("INSERT OR IGNORE INTO hosts (name) VALUES (?);")
129
143
  logger.debug("update_hosts_q2(%s)" % [host_name.inspect])
130
144
  @update_hosts_q2.execute(host_name)
131
145
  update_host_tags(host_name, options)
132
- end
133
146
 
134
- execute(<<-EOS % result["results"]["hosts"].map { "LOWER(?)" }.join(", "), result["results"]["hosts"])
135
- DELETE FROM hosts_tags WHERE host_id NOT IN
136
- ( SELECT id FROM hosts WHERE LOWER(name) IN ( %s ) );
137
- EOS
147
+ elapsed_time = Time.new - @started_at
148
+ if 0 < options[:max_time] and options[:max_time] < elapsed_time
149
+ logger.info("update host tags exceeded the maximum time (#{options[:max_time]} < #{elapsed_time}). will resume on next run.")
150
+ suspend_host_tags
151
+ break
152
+ end
153
+ end
138
154
  end
139
155
  end
140
156
 
141
157
  def update_tags(options={})
142
158
  @db.transaction do
159
+ resume_host_tags
160
+
143
161
  if options[:force]
144
162
  @update_tags_q1 ||= @db.prepare(<<-EOS)
145
163
  SELECT DISTINCT hosts_tags.host_id FROM hosts_tags;
@@ -154,12 +172,52 @@ module Hotdog
154
172
  EOS
155
173
  hosts = @update_tags_q2.execute(Time.new.to_i)
156
174
  end
157
- hosts.each do |host_name|
158
- update_host_tags(host_name, options)
175
+ hosts.each do |host_id|
176
+ @update_tags_q3 ||= @db.prepare("DELETE FROM hosts_tags WHERE host_id = ? AND hosts_tags.expires_at < ?;")
177
+ logger.debug("update_tags_q3(%s, %s)" % [host_id.inspect, Time.new.to_i])
178
+ @update_tags_q3.execute(host_id, Time.new.to_i)
179
+
180
+ update_host_tags(host_id, options)
181
+
182
+ elapsed_time = Time.new - @started_at
183
+ if 0 < options[:max_time] and options[:max_time] < elapsed_time
184
+ logger.info("update host tags exceeded the maximum time (#{options[:max_time]} < #{elapsed_time}). will resume on next run.")
185
+ suspend_host_tags
186
+ break
187
+ end
159
188
  end
160
189
  end
161
190
  end
162
191
 
192
+ # it'd be better to filter out this host/tag entry on displaying...
193
+ EMPTY_HOST_NAME = ""
194
+ EMPTY_TAG_NAME = ""
195
+ EMPTY_TAG_VALUE = ""
196
+ EMPTY_EXPIRES_AT = Time.at(0).to_i
197
+
198
+ def suspend_host_tags()
199
+ @suspended = true
200
+ @suspend_host_tags_q1 ||= @db.prepare("INSERT OR IGNORE INTO hosts (name) VALUES (?);")
201
+ @suspend_host_tags_q1.execute(EMPTY_HOST_NAME)
202
+ @suspend_host_tags_q2 ||= @db.prepare("INSERT OR IGNORE INTO tags (name, value) VALUES (?, ?);")
203
+ @suspend_host_tags_q2.execute(EMPTY_TAG_NAME, EMPTY_TAG_VALUE)
204
+ @suspend_host_tags_q3 ||= @db.prepare(<<-EOS)
205
+ INSERT OR REPLACE INTO hosts_tags (host_id, tag_id, expires_at)
206
+ SELECT host.id, tag.id, ? FROM
207
+ ( SELECT id FROM hosts WHERE name = ?) AS host,
208
+ ( SELECT id FROM tags WHERE name = ? AND value = ? ) AS tag;
209
+ EOS
210
+ @suspend_host_tags_q3.execute(EMPTY_EXPIRES_AT, EMPTY_HOST_NAME, EMPTY_TAG_NAME, EMPTY_TAG_VALUE)
211
+ end
212
+
213
+ def resume_host_tags()
214
+ @resume_host_tags_q1 ||= @db.prepare(<<-EOS)
215
+ DELETE FROM hosts_tags
216
+ WHERE host_id IN ( SELECT id FROM hosts WHERE name = ? ) AND tag_id IN ( SELECT id FROM tags WHERE name = ? AND value = ? );
217
+ EOS
218
+ @resume_host_tags_q1.execute(EMPTY_HOST_NAME, EMPTY_TAG_NAME, EMPTY_TAG_VALUE)
219
+ end
220
+
163
221
  def update_host_tags(host_name, options={})
164
222
  if Integer === host_name
165
223
  host_id = host_name
@@ -173,13 +231,16 @@ module Hotdog
173
231
  end
174
232
 
175
233
  if not options[:force]
176
- @update_host_tags_q3 ||= @db.prepare("SELECT MIN(expires_at) FROM hosts_tags WHERE host_id = ?;")
234
+ # Update host tags less frequently.
235
+ # Don't need to run updates on every expiration.
236
+ @update_host_tags_q3 ||= @db.prepare("SELECT AVG(expires_at) FROM hosts_tags WHERE host_id = ?;")
177
237
  logger.debug("update_host_tags_q3(%s)" % [host_id.inspect])
178
238
  if expires_at = @update_host_tags_q3.execute(host_id).map { |row| row.first }.first
179
239
  if Time.new.to_i < expires_at
240
+ logger.debug("%s: next update will run after %s." % [host_name, Time.at(expires_at)])
180
241
  return
181
242
  else
182
- logger.debug("%s: minimum expires_at was %s. start updating." % [host_name, Time.at(expires_at)])
243
+ logger.debug("%s: average expires_at was %s. start updating." % [host_name, Time.at(expires_at)])
183
244
  end
184
245
  else
185
246
  logger.debug("%s: expires_at not found. start updateing." % [host_name])
@@ -187,10 +248,12 @@ module Hotdog
187
248
  end
188
249
 
189
250
  code, result = @dog.host_tags(host_name)
251
+ logger.debug("dog.hosts_tags(%s) #==> [%s, %s]" % [host_name.inspect, code.inspect, result.inspect])
190
252
  if code.to_i / 100 != 2
191
253
  case code.to_i
192
254
  when 404 # host not found on datadog
193
255
  @update_host_tags_q7 ||= @db.prepare("DELETE FROM hosts_tags WHERE host_id IN ( SELECT id FROM hosts WHERE LOWER(name) = LOWER(?) );")
256
+ logger.debug("update_host_tags_q7(%s)" % [host_name.inspect])
194
257
  @update_host_tags_q7.execute(host_name)
195
258
  end
196
259
  raise("HTTP #{code}: #{result.inspect}")
@@ -1,3 +1,3 @@
1
1
  module Hotdog
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hotdog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yamashita Yuu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-30 00:00:00.000000000 Z
11
+ date: 2014-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler