multiforecast-client 0.62.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1316eee0e12243629951f3a621150271e5df2a3f
4
+ data.tar.gz: f4cb9e1be15332f4f7cf51036f2d509ef93926c6
5
+ SHA512:
6
+ metadata.gz: 61b291a15bbf7ce71c80783ef984ac3b56cc2a10862a8ccce2ae05034848dabf72bc6926f3bbd9fed495adcf0c8d5f4494636e29f250c0c723256564118ebb6f
7
+ data.tar.gz: 0cc4d55285915ff7334b047076c52efa49a3b5dc52d9fcddef604804260da1a5f33ccc9efdcbf37f6da602ad0c1849e100b362fc0d9ccbbcf78181bdffd89e0e
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /*.gem
2
+ ~*
3
+ #*
4
+ *~
5
+ .bundle
6
+ Gemfile.lock
7
+ .rbenv-version
8
+ .ruby-version
9
+ vendor
10
+ doc/*
11
+ tags
12
+ tmp/*
13
+ .yardoc
14
+ multiforecast.yml
data/.pryrc ADDED
@@ -0,0 +1,5 @@
1
+ Pry.commands.alias_command 'c', 'continue'
2
+ Pry.commands.alias_command 's', 'step'
3
+ Pry.commands.alias_command 'n', 'next'
4
+ Pry.commands.alias_command 'f', 'finish'
5
+
data/.rdebugrc ADDED
@@ -0,0 +1,4 @@
1
+ set autolist
2
+ set autoeval
3
+ set autoreload
4
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ # - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - 2.0.0
6
+ gemfile:
7
+ - Gemfile
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # 0.62.0.1 (2013/07/06)
2
+
3
+ First version
4
+
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+ source 'https://rubygems.org'
3
+
4
+ gemspec
5
+ gem 'multiforecast-client', path: '.'
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Naotoshi SEO
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # multiforecast-client
2
+
3
+ testing ruby: 1.9.2, 1.9.3, 2.0.0; GrowthForecast: >= 0.62 (Jun 27, 2013 released)
4
+
5
+ ## About multiforecast-client
6
+
7
+ `multiforecast-client` is a Multiple GrowthForecast Client, aimed to be used for [Yohoushi](https://github.com/yohoushi/yohoushi) visualization tool.
8
+
9
+ Features
10
+
11
+ - Possible to send http requests to multiple growthforecasts seemlessly
12
+ - Enables to create graphs whose levels are more than 3.
13
+ - CRUD graphs
14
+ - Get graph image uri
15
+
16
+ ## USAGE
17
+
18
+ ### Library
19
+
20
+ Create a client.
21
+
22
+ ```ruby
23
+ require 'multiforecast-client'
24
+ client = MultiForecast::Client.new('mapping' => {
25
+ 'foo/' => 'http://localhost:5125',
26
+ '' => 'http://localhost:5000'
27
+ })
28
+ ```
29
+
30
+ The first `post_graph` posts a number to the first GrowthForecast.
31
+ The second `post_graph` posts a number to the second GrowthForecast because the specified path did not match with the first mapping rule 'foo/'.
32
+ Notice that the pattern matching is processed from top as ruby's hash is an ordered hash.
33
+
34
+ ```ruby
35
+ client.post_graph('foo/b/c/d', { 'number' => 0 })
36
+ client.post_graph('bar/b/c/d', { 'number' => 0 })
37
+ ```
38
+
39
+ See [examples](./examples) for more.
40
+
41
+ ### CLI
42
+
43
+ `multiforecast-client` also provides a CLI named `multiforecast`.
44
+
45
+ Generate a config file template to store a mapping rule:
46
+
47
+ ```
48
+ $ multiforecast genearte config
49
+ Generated multiforecast.yml
50
+ $ cat multiforecast.yml
51
+ ---
52
+ mapping:
53
+ '': http://localhost:5125
54
+ short_metrics: true
55
+ ```
56
+
57
+ Post a number and create a graph:
58
+
59
+ ```
60
+ $ multiforecast post '{"number":0}' 'foo/a/b/c' -c multiforecast.yml
61
+ ```
62
+
63
+ Delete a graph or graphs under a path:
64
+
65
+ ```
66
+ $ multiforecast delete 'foo/' -c multiforecast.yml
67
+ ```
68
+
69
+ See help for more:
70
+
71
+ ```
72
+ $ multiforecast help
73
+ ```
74
+
75
+ ## INSIDE: How to treat graphs of more than 3 levels
76
+
77
+ Although GrowthForecast can treat only graphs of 3 leveled path, MultiForecast can handle graphs of more than 3 levels.
78
+ This feature is achieved by converting a given path to GrowthForecast's `service_name/section_name/graph_name` path as follows:
79
+
80
+ service_name = 'multiforecast'
81
+ section_name = CGI.escape(File.dirname(path)).gsub('+', '%20').gsub('.', '%2E')
82
+ graph_name = File.basename(path)
83
+
84
+ As a viewer for these converted path, [Yohoushi](https://github.com/yohoushi/yohoushi) is ready for you.
85
+
86
+ ## Contributing
87
+
88
+ 1. Fork it
89
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
90
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
91
+ 4. Push to the branch (`git push origin my-new-feature`)
92
+ 5. Create new [Pull Request](../../pull/new/master)
93
+
94
+ ## Copyright
95
+
96
+ Copyright (c) 2013 Naotoshi SEO. See [LICENSE](LICENSE) for details.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
9
+ task :default => :spec
10
+
11
+ desc 'Open an irb session preloaded with the gem library'
12
+ task :console do
13
+ sh 'irb -rubygems -I lib -r multiforecast-client.rb'
14
+ end
15
+ task :c => :console
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.62.0.2
data/bin/multiforecast ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ require 'multiforecast/cli'
5
+ MultiForecast::CLI.start(ARGV)
@@ -0,0 +1,161 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'multiforecast-client'
3
+ require 'pp'
4
+
5
+ ### Create a Multi GrowthForecast Client
6
+ client = MultiForecast::Client.new('mapping' => {
7
+ 'app1/' => 'http://localhost:5125',
8
+ 'app2/' => 'http://localhost:5000'
9
+ })
10
+ # client.debug_dev = STDOUT # print out HTTP requests and responses
11
+
12
+ pp 'Create a graph (Post a number)'
13
+ client.post_graph('app1/2xx_count', { 'number' => 0 })
14
+ client.post_graph('app1/3xx_count', { 'number' => 0 })
15
+ pp client.post_graph('app2/2xx_count', { 'number' => 0 }) #=>
16
+ # {"error"=>0,
17
+ # "data"=>
18
+ # {"number"=>0,
19
+ # "llimit"=>-1000000000,
20
+ # "mode"=>"gauge",
21
+ # "stype"=>"AREA",
22
+ # "adjustval"=>"1",
23
+ # "meta"=>"",
24
+ # "service_name"=>"multiforecast",
25
+ # "gmode"=>"gauge",
26
+ # "color"=>"#33cc99",
27
+ # "created_at"=>"2013/05/20 17:57:57",
28
+ # "section_name"=>"multiforecast",
29
+ # "ulimit"=>1000000000,
30
+ # "id"=>2,
31
+ # "graph_name"=>"app2%2F2xx_count",
32
+ # "description"=>"",
33
+ # "sulimit"=>100000,
34
+ # "unit"=>"",
35
+ # "sort"=>0,
36
+ # "updated_at"=>"2013/05/20 17:57:57",
37
+ # "adjust"=>"*",
38
+ # "type"=>"AREA",
39
+ # "sllimit"=>-100000,
40
+ # "md5"=>"c81e728d9d4c2f636f067f89cc14862c"}}
41
+
42
+ pp 'List graphs. All graphs from multiple growthforecasts are shown'
43
+ pp client.list_graph #=>
44
+ # [{"graph_name"=>"app1%2F3xx_count",
45
+ # "service_name"=>"multiforecast",
46
+ # "section_name"=>"multiforecast",
47
+ # "id"=>2,
48
+ # "base_uri"=>"http://localhost:5125",
49
+ # "path"=>"app1/3xx_count"},
50
+ # {"graph_name"=>"app1%2F2xx_count",
51
+ # "service_name"=>"multiforecast",
52
+ # "section_name"=>"multiforecast",
53
+ # "id"=>1,
54
+ # "base_uri"=>"http://localhost:5125",
55
+ # "path"=>"app1/2xx_count"},
56
+ # {"service_name"=>"multiforecast",
57
+ # "graph_name"=>"app2%2F2xx_count",
58
+ # "section_name"=>"multiforecast",
59
+ # "id"=>2,
60
+ # "base_uri"=>"http://localhost:5000",
61
+ # "path"=>"app2/2xx_count"}]
62
+
63
+ pp 'List graphs by filtering by dirpath app1/'
64
+ pp client.list_graph('app1/') #=>
65
+ # [{"graph_name"=>"app1%2F3xx_count",
66
+ # "service_name"=>"multiforecast",
67
+ # "section_name"=>"multiforecast",
68
+ # "id"=>2,
69
+ # "base_uri"=>"http://localhost:5125",
70
+ # "path"=>"app1/3xx_count"},
71
+ # {"graph_name"=>"app1%2F2xx_count",
72
+ # "service_name"=>"multiforecast",
73
+ # "section_name"=>"multiforecast",
74
+ # "id"=>1,
75
+ # "base_uri"=>"http://localhost:5125",
76
+ # "path"=>"app1/2xx_count"}]
77
+
78
+ pp 'Get a graph property'
79
+ pp client.get_graph('app2/2xx_count') #=>
80
+ # {"number"=>0,
81
+ # "llimit"=>-1000000000,
82
+ # "mode"=>"gauge",
83
+ # "stype"=>"AREA",
84
+ # "adjustval"=>"1",
85
+ # "meta"=>"",
86
+ # "service_name"=>"multiforecast",
87
+ # "gmode"=>"gauge",
88
+ # "color"=>"#33cc99",
89
+ # "created_at"=>"2013/05/20 17:57:57",
90
+ # "section_name"=>"multiforecast",
91
+ # "ulimit"=>1000000000,
92
+ # "id"=>2,
93
+ # "graph_name"=>"app2%2F2xx_count",
94
+ # "description"=>"",
95
+ # "sulimit"=>100000,
96
+ # "unit"=>"",
97
+ # "sort"=>0,
98
+ # "updated_at"=>"2013/05/20 17:57:57",
99
+ # "adjust"=>"*",
100
+ # "type"=>"AREA",
101
+ # "sllimit"=>-100000,
102
+ # "md5"=>"c81e728d9d4c2f636f067f89cc14862c",
103
+ # "base_uri"=>"http://localhost:5000",
104
+ # "path"=>"app2/2xx_count"}
105
+
106
+ pp 'Get a graph image uri'
107
+ pp client.get_graph_uri('app2/2xx_count', term: '3h') #=>
108
+ # "http://localhost:5125/graph/multiforecast/multiforecast/app1%2F2xx_count?t=3h"
109
+
110
+ pp 'Delete a complex graph'
111
+ pp client.delete_graph('app2/2xx_count') #=>
112
+ # {"location"=>"http://localhost:5000/list/multiforecast/multiforecast", "error"=>0}
113
+
114
+ pp 'Create a complex graph'
115
+ # Source graphs of a complex graph must exist on *a* GrowthForecast
116
+ from_graphs= [
117
+ {"path"=>'app1/2xx_count', "gmode" => 'gauge', "stack" => true, "type" => 'AREA'},
118
+ {"path"=>'app1/3xx_count', "gmode" => 'gauge', "stack" => true, "type" => 'AREA'},
119
+ ]
120
+ to_complex = {
121
+ 'path' => 'app1/complex',
122
+ "description" => "response time count",
123
+ "sort" => 10,
124
+ }
125
+ pp client.create_complex(from_graphs, to_complex) #=>
126
+ # {"location"=>"http://localhost:5125/list/multiforecast/multiforecast", "error"=>0}
127
+
128
+ pp 'Get a complex graph'
129
+ pp client.get_complex(to_complex['path']) #=>
130
+ # {"number"=>0,
131
+ # "complex"=>true,
132
+ # "created_at"=>"2013/05/20 18:00:09",
133
+ # "service_name"=>"multiforecast",
134
+ # "section_name"=>"multiforecast",
135
+ # "id"=>1,
136
+ # "graph_name"=>"app1%2Fcomplex",
137
+ # "data"=>
138
+ # [{"gmode"=>"gauge", "stack"=>false, "type"=>"AREA", "graph_id"=>1},
139
+ # {"gmode"=>"gauge", "stack"=>true, "type"=>"AREA", "graph_id"=>2}],
140
+ # "sumup"=>false,
141
+ # "description"=>"response time count",
142
+ # "sort"=>10,
143
+ # "updated_at"=>"2013/05/20 18:00:09",
144
+ # "base_uri"=>"http://localhost:5125",
145
+ # "path"=>"app1/complex"}
146
+
147
+ pp 'Get a complex graph image uri'
148
+ pp client.get_complex_uri(to_complex['path'], term: '3h') #=>
149
+ # "http://localhost:5125/complex/graph/multiforecast/multiforecast/app1%2Fcomplex?t=3h"
150
+
151
+ pp 'List complex graphs'
152
+ pp client.list_complex #=>
153
+ # [{"service_name"=>"multiforecast", "graph_name"=>"app1%2Fcomplex", "section_name"=>"multiforecast", "id"=>1, "base_uri"=>"http://localhost:5125", "path"=>"app1/complex"}]
154
+
155
+ pp 'List complex graphs by filetering by dirpath app1/'
156
+ pp client.list_complex('app1/')
157
+
158
+ pp 'Delete a complex graph'
159
+ pp client.delete_complex(to_complex['path']) #=>
160
+ # {"location"=>"http://localhost:5125/list/multiforecast/multiforecast", "error"=>0}
161
+
@@ -0,0 +1,69 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'thor'
3
+ require 'yaml'
4
+ require 'multiforecast-client'
5
+
6
+ class MultiForecast::CLI < Thor
7
+ class_option :config, :aliases => ["-c"], :type => :string
8
+ class_option :silent, :aliases => ["-S"], :type => :boolean
9
+
10
+ def initialize(args = [], opts = [], config = {})
11
+ super(args, opts, config)
12
+
13
+ if options['config'] && File.exists?(options['config'])
14
+ @options = YAML.load_file(options['config']).merge(@options)
15
+ end
16
+ @client = MultiForecast::Client.new(@options)
17
+ end
18
+
19
+ desc 'generate config', 'Generate a sample config file'
20
+ def generate(target)
21
+ config = {
22
+ 'mapping' => { '' => 'http://localhost:5125' },
23
+ }
24
+ File.open("multiforecast.yml", "w") do |file|
25
+ YAML.dump(config, file)
26
+ $stdout.puts "Generated #{file.path}"
27
+ end
28
+ end
29
+
30
+ desc 'post <json> <path>', 'Post a parameter to a path'
31
+ long_desc <<-LONGDESC
32
+ Post a parameter to a path
33
+
34
+ ex)
35
+ $ multiforecast post '{"number":0}' 'test/test' -c multiforecast.yml
36
+ LONGDESC
37
+ def post(json, path)
38
+ begin
39
+ res = @client.post_graph(path, JSON.parse(json))
40
+ $stdout.puts res unless @options['silent']
41
+ rescue => e
42
+ $stderr.puts "\tclass:#{e.class}\t#{e.message}"
43
+ end
44
+ end
45
+
46
+ desc 'delete <base_path>', 'Delete a graph or graphs under a path'
47
+ def delete(base_path)
48
+ graphs = @client.list_graph(base_path)
49
+ graphs.each do |graph|
50
+ begin
51
+ @client.delete_graph(graph['path'])
52
+ $stdout.puts "Deleted #{graph['path']}" unless @options['silent']
53
+ rescue => e
54
+ $stderr.puts "\tclass:#{e.class}\t#{e.message}"
55
+ end
56
+ end
57
+ complexes = @client.list_complex(base_path)
58
+ complexes.each do |graph|
59
+ begin
60
+ @client.delete_complex(graph['path'])
61
+ $stdout.puts "Deleted #{graph['path']}" unless @options['silent']
62
+ rescue => e
63
+ puts "\tclass:#{e.class}\t#{e.message}"
64
+ end
65
+ end
66
+ $stderr.puts "Not found" if graphs.empty? and complexes.empty? unless @options['silent']
67
+ end
68
+ end
69
+