flareboard 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +89 -0
  3. data/bin/flareboard +220 -0
  4. metadata +90 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0d2579b252fee593a40c48761c6ac965bab4b39e
4
+ data.tar.gz: a9673657a91d16531d9f40fa8555aefa8d6a7706
5
+ SHA512:
6
+ metadata.gz: d7032d8918a66d9ef8f63cee3fe859a8afb95b6034d1bc138ed0aa77b86410d0f2db1d69ae80d43e44855d98c820639e0ac82be51193de62db12186b5d3f5bc4
7
+ data.tar.gz: 5856f2bdf2487914646e2a3de877aa29f0bd32cd5458617438d9c0a66152c00236ed1826f360820563175483d06a38b2a665e4e523993f8c8a21dbb2a24b95d4
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ ##What is Flareboard?
2
+
3
+ Flareboard is the way to get your [CloudFlare](http://www.cloudflare.com) stats
4
+ to display in your [StatusBoard](http://www.panic.com/statusboard). It has been
5
+ designed to be very easy to install and use. It requires no third-party gems,
6
+ and can be run on any version of ruby from 1.8.7 to 2.1.1.
7
+
8
+ Add your credentials and sites to flareboard, and it will hit the CloudFlare API
9
+ to grab your stats and convert them into the JSON that Statusboard uses for
10
+ graphing. You can drop the resulting file into a dropbox folder or host it on a
11
+ web server. Unless you are paying for a CloudFlare Pro account, your stats will
12
+ only update every 24 hours, so it's no use running flareboard more often than
13
+ that.
14
+
15
+ **Note**: For compatibility with 1.8.7. you *will* have to install the JSON gem.
16
+ Also, you have my sympathies for having to use 1.8.7.
17
+
18
+ ## Installation
19
+
20
+ Copy the file ```bin/flareboard``` onto your computer. Put it either in a bin
21
+ directory in your path or somewhere else. If you are using ruby 1.8.7, then
22
+ you'll have to run ```sudo gem install json``` before it will work.
23
+
24
+ ## Configuration
25
+
26
+ There are three ways of configuring the script. Via the command-line arguments
27
+ documented in the previous section, via a config file (*~/.flareboard.rc*), or
28
+ by editing the script directly. In order of priority (highest to lowest), it
29
+ will use command-line options, the config file, and then the hard-coded config
30
+ hash in the script.
31
+
32
+ It is *highly* recommended to use a config file, as passing your API token on
33
+ the command-line is a security risk, and modifying the script itself will make
34
+ upgrades manual and laborious.
35
+
36
+ ### :title
37
+ The title that will show up on your status board
38
+
39
+ ### :token
40
+ Your Cloudflare token - available via their website at
41
+ https://www.cloudflare.com/my-account
42
+
43
+ ### :email
44
+ The email you have registered with cloudflare. **NOT** your username!
45
+
46
+ ### :interval
47
+ Interval Values - see https://www.cloudflare.com/docs/client-api.html for
48
+ latest.
49
+
50
+ 20-40 only update once a day - it is no use polling more often than that
51
+ 20 = Past 30 days
52
+ 30 = Past 7 days
53
+ 40 = Past day
54
+ !!! Anything higher than this requires a paid CloudFlare account !!!
55
+ !!! This also enables greater than daily updates !!!
56
+ 100 = 24 hours ago
57
+ 110 = 12 hours ago
58
+ 120 = 6 hours ago
59
+
60
+ ### :sites
61
+ Sites have a site specific title, a URL, and a color for the graph.
62
+ Colors: yellow, green, red, purple, blue, mediumGray, pink, aqua, orange, lightGray
63
+
64
+ Here is an example config file, using the same data as the example hash.
65
+
66
+ ---
67
+ :token: XXXXXXX
68
+ :email: user@example.com
69
+ :sites:
70
+ - :title: 'Should I Use That In Prod'
71
+ :url: 'shouldiusethatinprod.com'
72
+ :color: 'red'
73
+ - :title: "It's Not Rocket Science"
74
+ :url: 'itsnotrocketscience.info'
75
+ :color: 'purple'
76
+
77
+ ## Usage
78
+
79
+ Usage: flareboard [options]
80
+ -f, --file FILE Where to write the JSON output
81
+ Defaults to STDOUT
82
+ -t, --token TOKEN Your CloudFlare API token
83
+ -e, --email EMAIL Your CloudFlare email address
84
+ -i, --interval INTERVAL CloudFlare history interval
85
+ Defaults to 40
86
+ --title TITLE Title of the status board
87
+ Defaults to 'Cloudflare - Pageviews'
88
+
89
+ If no file is given, flareboard will write to standard out.
data/bin/flareboard ADDED
@@ -0,0 +1,220 @@
1
+ #!/usr/bin/env ruby
2
+ # @author David Bishop
3
+
4
+ require 'net/http'
5
+ if RUBY_VERSION < '1.9'
6
+ require 'net/https'
7
+ end
8
+ require 'json'
9
+ require 'optparse'
10
+ require 'yaml'
11
+
12
+ # Rather than dump out a free-form string, on errors dump out something that
13
+ # the status board app can read in and display
14
+ #
15
+ # @param error [String] Short description of the problem
16
+ # @param detail [String] Longer description or specific error code
17
+ # @return [nil]
18
+ def exit_json(error, detail)
19
+ # return the error in json form
20
+ sperror = {
21
+ 'error' => {
22
+ 'message' => error,
23
+ 'detail' => detail
24
+ }
25
+ }
26
+ STDERR.puts error, detail
27
+ puts sperror.to_json
28
+ exit 1
29
+ end
30
+
31
+ # Take the integer that CloudFlare uses and return a description in english
32
+ #
33
+ # @param interval [Integer] Integer needed by Cloudflare API
34
+ # @return [String] Description in english
35
+ def name_interval(interval)
36
+ title = {
37
+ 20 => 'Last Month',
38
+ 30 => 'Last Week',
39
+ 40 => 'Yesterday',
40
+ 100 => '24 Hours Ago',
41
+ 110 => '12 Hours Ago',
42
+ 120 => '6 Hours Ago'
43
+ }
44
+
45
+ # hash.fetch will return the second parameter if the key doesn't exist
46
+ title.fetch(interval, 'Invalid interval')
47
+ end
48
+
49
+ # ~~~~~ CONFIG BEGIN ~~~~~
50
+
51
+ options = {
52
+ :title => 'Cloudflare - Pageviews',
53
+ :token => 'XXXXXX',
54
+ :email => 'user@example.com',
55
+ :interval => 40,
56
+ :graph => 'bar',
57
+ :sites => [
58
+ { :title => 'Should I Use That In Prod',
59
+ :url => 'shouldiusethatinprod.com',
60
+ :color => 'red'
61
+ },
62
+ { :title => "It's Not Rocket Science",
63
+ :url => 'itsnotrocketscience.info',
64
+ :color => 'purple'
65
+ }
66
+ ]
67
+ }
68
+
69
+ # YOU SHOULD NOT NEED TO EDIT ANYTHING BELOW HERE
70
+ # IF YOU DO, PLEASE OPEN A BUG REPORT AT http://github.com/teancom/flareboard
71
+ # ~~~~~ CONFIG END ~~~~~
72
+
73
+ # The config file
74
+ CONFIG_FILE = File.join(ENV['HOME'], '.flareboard.rc')
75
+ if File.exist? CONFIG_FILE
76
+ config_options = YAML.load_file(CONFIG_FILE)
77
+ options.merge!(config_options)
78
+ end
79
+
80
+ # The name of this program
81
+ EXE_NAME = File.basename($PROGRAM_NAME)
82
+ # @todo Add support for graph type
83
+ option_parser = OptionParser.new do |opts|
84
+ opts.on('-f FILE',
85
+ '--file',
86
+ 'Where to write the JSON output',
87
+ 'Defaults to STDOUT'
88
+ ) do |file|
89
+ options[:file] = file
90
+ end
91
+ opts.on('-t TOKEN',
92
+ '--token',
93
+ 'Your CloudFlare API token'
94
+ ) do |token|
95
+ options[:token] = token
96
+ end
97
+ opts.on('-e EMAIL',
98
+ '--email',
99
+ 'Your CloudFlare email address'
100
+ ) do |email|
101
+ options[:email] = email
102
+ end
103
+ opts.on('-i INTERVAL',
104
+ '--interval',
105
+ Integer,
106
+ 'CloudFlare history interval',
107
+ 'Defaults to 40'
108
+ ) do |interval|
109
+ options[:interval] = interval
110
+ end
111
+ opts.on('--title TITLE',
112
+ 'Title of the status board',
113
+ "Defaults to 'Cloudflare - Pageviews'"
114
+ ) do |title|
115
+ options[:title] = title
116
+ end
117
+ # opts.on('--graph GRAPH',
118
+ # 'The type of graph - bar or line',
119
+ # 'Defaults to bar'
120
+ # ) do |graph|
121
+ # options[:graph] = graph
122
+ # end
123
+ opts.on("\n")
124
+ opts.on("If no file is given, #{EXE_NAME} will write to standard out.")
125
+ end
126
+
127
+ option_parser.parse!
128
+
129
+ if options.key? :file
130
+ path = File.expand_path(options[:file])
131
+ dir = File.dirname(path)
132
+ begin
133
+ $stdout.reopen(path, 'w')
134
+ rescue Errno::ENOENT
135
+ abort "Can't write into #{dir}. Does it exist?"
136
+ rescue Errno::EACCES
137
+ abort File.writable?(dir) ? "Can't write #{path}. No permission." : "Can't write into #{dir}. No permission."
138
+ rescue Errno::EISDIR
139
+ abort 'Please pass in a file name, not a directory name.'
140
+ rescue => e
141
+ abort e.message
142
+ end
143
+ end
144
+
145
+ # The graph hash needs to match the JSON object that StatusBoard requires
146
+ graph = {
147
+ 'graph' => {
148
+ 'title' => options[:title],
149
+ 'type' => options[:graph],
150
+ 'datasequences' => []
151
+ }
152
+ }
153
+
154
+ uri = URI.parse('https://www.cloudflare.com/api_json.html')
155
+ request = Net::HTTP::Post.new(uri.path)
156
+
157
+ options[:sites].each_with_index do | site, key |
158
+ request.set_form_data(
159
+ 'a' => 'stats',
160
+ 'tkn' => options[:token],
161
+ 'email' => options[:email],
162
+ 'z' => site[:url],
163
+ 'interval' => options[:interval]
164
+ )
165
+ httpreq = Net::HTTP.new(uri.host, uri.port)
166
+ httpreq.use_ssl = true
167
+ if RUBY_VERSION < '1.9'
168
+ httpreq.verify_mode = OpenSSL::SSL::VERIFY_NONE
169
+ end
170
+
171
+ response = httpreq.start do |http|
172
+ http.request(request)
173
+ end
174
+
175
+ # Got back something other than a 2xx response code
176
+ unless response.is_a? Net::HTTPSuccess
177
+ exit_json('Problems contacting the Cloudflare server', response.msg)
178
+ end
179
+
180
+ # Parse the JSON we got back from CloudFlare
181
+ begin
182
+ result = JSON.parse(response.body)
183
+ rescue UnparserError => e
184
+ exit_json('Unable to parse the Cloudflare JSON', e)
185
+ end
186
+
187
+ # Figure out what sort of error we got back
188
+ errcodes = { 'E_UNAUTH' => "Couldn't authenticate: ",
189
+ 'err_ts' => 'Invalid interval: ',
190
+ 'err_zone_not_found' => 'Probable typo in site name: ',
191
+ 'E_MAXAPI' => 'CloudFlare wants you to not hit them as much: ',
192
+ 'E_INVLDINPUT' => 'Unknown problem. Congrats! This is weird: '
193
+ }
194
+
195
+ if result['result'] == 'error'
196
+ if errcodes.key? result['err_code']
197
+ exit_json(errcodes[result['err_code']] + result['msg'],
198
+ result['err_code'])
199
+ else
200
+ exit_json("Unable to retrieve the Cloudflare JSON: #{result['msg']}",
201
+ result['err_code'])
202
+ end
203
+ end
204
+
205
+ totalhits = result['response']['result']['objs'][0]['requestsServed']['cloudflare']
206
+ crawlerhits = result['response']['result']['objs'][0]['trafficBreakdown']['pageviews']['crawler']
207
+
208
+ graph['graph']['datasequences'][key] = {
209
+ 'title' => site[:title],
210
+ 'color' => site[:color],
211
+ 'datapoints' => [{
212
+ 'title' => name_interval(options[:interval]),
213
+ 'value' => totalhits - crawlerhits
214
+ }]
215
+ }
216
+ # graph['graph']['datasequences'][key]['datapoints'][0]['title'] = 'Nudiustertian'
217
+ # graph['graph']['datasequences'][key]['datapoints'][1]['title'] = 'Yesterday'
218
+ end
219
+
220
+ puts graph.to_json
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flareboard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - David Bishop
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.8'
55
+ description: |-
56
+ flareboard allows you to display your CloudFlare statistics
57
+ in the Panic Software's StatusBoard app
58
+ email: david at gnuconsulting dotcom
59
+ executables:
60
+ - flareboard
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - README.md
65
+ - bin/flareboard
66
+ homepage: http://github.com/teancom/flareboard
67
+ licenses:
68
+ - ISC
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project: flareboard
86
+ rubygems_version: 2.2.2
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: flareboard gets your cloudflare stats into statusboard
90
+ test_files: []