x_runtime 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -0
- data/Gemfile.lock +28 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +76 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/lib/x_runtime/array.rb +15 -0
- data/lib/x_runtime/data_set.rb +46 -0
- data/lib/x_runtime/middleware.rb +56 -0
- data/lib/x_runtime/redis.lua +17 -0
- data/lib/x_runtime/script.rb +23 -0
- data/lib/x_runtime/template.erb +43 -0
- data/lib/x_runtime/template.rb +24 -0
- data/lib/x_runtime/utils.rb +4 -0
- data/lib/x_runtime.rb +23 -0
- data/test/client.rb +12 -0
- data/test/helper.rb +18 -0
- data/test/server.rb +12 -0
- data/test/test_x_runtime.rb +7 -0
- metadata +150 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://ruby.taobao.org/
|
3
|
+
specs:
|
4
|
+
active_support (3.0.0)
|
5
|
+
activesupport (= 3.0.0)
|
6
|
+
activesupport (3.0.0)
|
7
|
+
git (1.2.5)
|
8
|
+
jeweler (1.8.4)
|
9
|
+
bundler (~> 1.0)
|
10
|
+
git (>= 1.2.5)
|
11
|
+
rake
|
12
|
+
rdoc
|
13
|
+
json (1.7.3)
|
14
|
+
rack (1.4.1)
|
15
|
+
rake (0.9.2.2)
|
16
|
+
rdoc (3.12)
|
17
|
+
json (~> 1.4)
|
18
|
+
redis (3.0.1)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
active_support
|
25
|
+
jeweler
|
26
|
+
rack
|
27
|
+
rake
|
28
|
+
redis (~> 3.0.1)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 崔峥
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# x_runtime
|
2
|
+
|
3
|
+
XRuntime是一个Rack的middleware,配合Redis用来分析Http Server每个URI请求时长.
|
4
|
+
由于使用到Redis的**lua script**,所以需要你的Redis服务支持.
|
5
|
+
|
6
|
+
版本要求:
|
7
|
+
* redis-server版本>2.6.x
|
8
|
+
* redis(ruby gem)>3.0.1
|
9
|
+
|
10
|
+
在Redis中,对每一个URI记录了以下信息:
|
11
|
+
* 请求总数
|
12
|
+
* 总共请求时间
|
13
|
+
* 最近一次请求时间
|
14
|
+
* 平均请求时间
|
15
|
+
|
16
|
+
## Portal
|
17
|
+
|
18
|
+
可以访问Http Server的这个URL来实时查看当前记录的请求:[/xruntime](/xruntime)
|
19
|
+
这个页面是按照每个URI数次执行后的平均时间来排序的。
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
引入这个middleware需要两个参数:
|
24
|
+
|
25
|
+
1. threshold,表示处理时间超过多少毫秒的请求才会被记录
|
26
|
+
2. redis对象
|
27
|
+
|
28
|
+
可以指定XRuntime使用的Redis的key前缀或者叫命名空间:
|
29
|
+
`XRuntime::NameSpace = "RuntimeEx::Threshold"`
|
30
|
+
|
31
|
+
### Sinatra
|
32
|
+
|
33
|
+
use Rack::XRuntime, 100, Redis.connect(:url => "redis://localhost:6380/")
|
34
|
+
|
35
|
+
### Rails3
|
36
|
+
|
37
|
+
# config/environment.rb
|
38
|
+
config.middleware.insert_after Rack::Runtime, Rack::XRuntime, 100, Redis.connect(:url => "redis://localhost:6380/")
|
39
|
+
|
40
|
+
### Test
|
41
|
+
|
42
|
+
请先修改test/server.rb和test/client.rb中的Redis参数,我的地址是localhost:6380,这个请改为你的地址。
|
43
|
+
|
44
|
+
* 先启动服务 `ruby test/server.rb`
|
45
|
+
* 再产生测试数据 `ruby test/client.rb`
|
46
|
+
|
47
|
+
执行完毕后可以打开浏览器访问[/xruntime](http://localhost:4567/xruntime),看是否已经准确的记录了一些数据
|
48
|
+
|
49
|
+
## Redis Lua Script
|
50
|
+
|
51
|
+
redis-server的版本要大于2.6.0才会支持lua script,
|
52
|
+
可以使用__script__系列命令来测试服务端是否支持
|
53
|
+
|
54
|
+
启动__redis-cli__
|
55
|
+
|
56
|
+
redis 127.0.0.1:6380> SCRIPT LOAD "local key = KEYS[1];local path = tonumber(ARGV[1]);redis.call('set',key, path)"
|
57
|
+
"dab89791b5a512390f69e1f59eb1753f671b6649"
|
58
|
+
redis 127.0.0.1:6380> evalsha dab89791b5a512390f69e1f59eb1753f671b6649 1 hahaha 123456789
|
59
|
+
redis 127.0.0.1:6380> get hahaha
|
60
|
+
"123456789"
|
61
|
+
|
62
|
+
## Contributing to x_runtime
|
63
|
+
|
64
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
65
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
66
|
+
* Fork the project.
|
67
|
+
* Start a feature/bugfix branch.
|
68
|
+
* Commit and push until you are happy with your contribution.
|
69
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
70
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
71
|
+
|
72
|
+
## Copyright
|
73
|
+
|
74
|
+
Copyright (c) 2012 崔峥. See LICENSE.txt for
|
75
|
+
further details.
|
76
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "x_runtime"
|
18
|
+
gem.homepage = "http://github.com/charlescui/x_runtime"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{XRuntime是一个Rack的middleware,配合Redis用来分析Http Server每个URI请求时长}
|
21
|
+
gem.description = %Q{由于使用到Redis的lua script,所以需要你的Redis服务支持,redis-server版本>2.6.x,redis(ruby gem)>3.0.1.}
|
22
|
+
gem.email = "zheng.cuizh@gmail.com"
|
23
|
+
gem.authors = ["崔峥"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
task :default => :test
|
36
|
+
|
37
|
+
require 'rdoc/task'
|
38
|
+
Rake::RDocTask.new do |rdoc|
|
39
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
|
+
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = "x_runtime #{version}"
|
43
|
+
rdoc.rdoc_files.include('README*')
|
44
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module XRuntime
|
2
|
+
class DataSet
|
3
|
+
|
4
|
+
def initialize(key, script)
|
5
|
+
raise ArgumentError, "Script must not nil and be valid!" unless script
|
6
|
+
@key = key
|
7
|
+
@key_counter = "#{@key}::Counter"
|
8
|
+
@key_amount = "#{@key}::Amount"
|
9
|
+
@key_average = "#{@key}::Average"
|
10
|
+
@script = script
|
11
|
+
end
|
12
|
+
|
13
|
+
# {key => {:score => score, :count => count, :average => average}}
|
14
|
+
def latest(opts = {})
|
15
|
+
opts.delete_if{|k,v| v == nil}
|
16
|
+
opts = {:limit => 100, :offset => 0}.update(opts)
|
17
|
+
data = {}
|
18
|
+
key_average = @script.redis
|
19
|
+
.zrevrangebyscore(@key_average, '+inf', '-inf', :limit => [opts[:offset], opts[:limit]], :withscores => true)
|
20
|
+
.inject({}){|hash, array|hash[array[0]] = array[1]; hash}
|
21
|
+
|
22
|
+
if key_average.size > 0
|
23
|
+
key_count = {}
|
24
|
+
keys = key_average.keys
|
25
|
+
@script.redis.hmget(@key_counter, *key_average.keys).each_with_index{|count, idx| key_count[keys[idx]] = count}
|
26
|
+
|
27
|
+
key_average.keys.each do |key|
|
28
|
+
data[key] = {
|
29
|
+
:latest => @script.redis.zscore(@key, key),
|
30
|
+
:count => key_count[key],
|
31
|
+
:average => key_average[key]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
data
|
36
|
+
end
|
37
|
+
|
38
|
+
def size
|
39
|
+
@script.redis.zcard(@key)
|
40
|
+
end
|
41
|
+
|
42
|
+
def add(member, score)
|
43
|
+
@script.evalsha([@key], [member, score])
|
44
|
+
end
|
45
|
+
end#end of DataSet
|
46
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module XRuntime
|
2
|
+
class Middleware
|
3
|
+
# threshold => ms
|
4
|
+
def initialize(app, threshold, redis)
|
5
|
+
@app = app
|
6
|
+
@threshold = threshold.to_f
|
7
|
+
@redis = redis
|
8
|
+
end
|
9
|
+
|
10
|
+
def ds
|
11
|
+
@@ds ||= DataSet.new(redis_key, script)
|
12
|
+
end
|
13
|
+
|
14
|
+
def script
|
15
|
+
@@script ||= Script.new(@redis)
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(env)
|
19
|
+
status, headers, body = nil
|
20
|
+
|
21
|
+
if env['REQUEST_PATH'] == "/xruntime"
|
22
|
+
status, headers, body = call_portal(env)
|
23
|
+
else
|
24
|
+
status, headers, body = call_app(env)
|
25
|
+
end
|
26
|
+
|
27
|
+
[status, headers, body]
|
28
|
+
end
|
29
|
+
|
30
|
+
def call_app(env)
|
31
|
+
start_time = Time.now
|
32
|
+
status, headers, body = @app.call(env)
|
33
|
+
request_time = (Time.now - start_time).to_f*1000
|
34
|
+
|
35
|
+
if request_time >= @threshold
|
36
|
+
logredis(request_time, env['REQUEST_URI']) rescue nil
|
37
|
+
end
|
38
|
+
|
39
|
+
[status, headers, body]
|
40
|
+
end
|
41
|
+
|
42
|
+
def call_portal(env)
|
43
|
+
@req = Rack::Request.new(env)
|
44
|
+
[200, {}, [Template.new(ds, :limit => (@req.params["limit"] ? @req.params["limit"].to_i : 20), :offset => @req.params["offset"].to_i).render]]
|
45
|
+
end
|
46
|
+
|
47
|
+
def logredis(cost,uri)
|
48
|
+
ds.add(uri, cost)
|
49
|
+
end
|
50
|
+
|
51
|
+
def redis_key
|
52
|
+
@key ||= "#{XRuntime::NameSpace}::#{@threshold}"
|
53
|
+
end
|
54
|
+
|
55
|
+
end#end of Middleware
|
56
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
local path = ARGV[1];
|
2
|
+
local score = tonumber(ARGV[2])
|
3
|
+
local key = KEYS[1]
|
4
|
+
local key_counter = string.format("%s::Counter",key)
|
5
|
+
local key_amount = string.format("%s::Amount",key)
|
6
|
+
local key_average = string.format("%s::Average",key)
|
7
|
+
|
8
|
+
-- 记录最新一次请求的耗时
|
9
|
+
redis.call('zadd',key,score,path)
|
10
|
+
-- 记录某个path的请求次数
|
11
|
+
redis.call('hincrby',key_counter,path,1)
|
12
|
+
-- 记录某个path的请求总时长
|
13
|
+
redis.call('hincrbyfloat',key_amount,path,score)
|
14
|
+
-- 记录某个path的平均时长
|
15
|
+
local average = tonumber(redis.call('hget',key_amount,path))/tonumber(redis.call('hget',key_counter,path))
|
16
|
+
redis.call('zadd',key_average,average,path)
|
17
|
+
return average
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module XRuntime
|
2
|
+
class Script
|
3
|
+
attr_accessor :redis
|
4
|
+
|
5
|
+
def initialize(redis)
|
6
|
+
@redis = redis
|
7
|
+
end
|
8
|
+
|
9
|
+
def content
|
10
|
+
@script ||= IO.read(::File.join(::File.dirname(__FILE__),'redis.lua'))
|
11
|
+
end
|
12
|
+
|
13
|
+
def sha
|
14
|
+
# 加载脚本 redis-server会将该脚本缓存起来
|
15
|
+
@sha ||= @redis.script(:load, content)
|
16
|
+
end
|
17
|
+
|
18
|
+
def evalsha(keys, argv)
|
19
|
+
@redis.evalsha(sha, :keys => keys, :argv => argv)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>XRuntime</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<table>
|
7
|
+
<tr>
|
8
|
+
<td>#</td>
|
9
|
+
<td>Last</td>
|
10
|
+
<td>URI</td>
|
11
|
+
<td>Count</td>
|
12
|
+
<td>Average</td>
|
13
|
+
</tr>
|
14
|
+
<% num = 0 %>
|
15
|
+
<% @data.each do |member, hash| %>
|
16
|
+
<% num +=1 %>
|
17
|
+
<tr>
|
18
|
+
<td><%= num %></td>
|
19
|
+
<td><%= hash[:latest] %>ms</td>
|
20
|
+
<td><a href=<%= member %>><%= member %></a></td>
|
21
|
+
<td><%= hash[:count]%></td>
|
22
|
+
<td><%= hash[:average]%></td>
|
23
|
+
</tr>
|
24
|
+
<% end %>
|
25
|
+
<% num = nil %>
|
26
|
+
</table>
|
27
|
+
<br/>
|
28
|
+
<br/>
|
29
|
+
<div>
|
30
|
+
<% if @offset - @limit < 0 %>
|
31
|
+
Prev
|
32
|
+
<% else %>
|
33
|
+
<a href="/xruntime?offset=<%=[@offset - @limit, 0].max%>&limit=<%=@limit%>">Prev</a>
|
34
|
+
<% end %>
|
35
|
+
 - - 
|
36
|
+
<% if @offset + @limit >= @ds.size %>
|
37
|
+
Next
|
38
|
+
<% else %>
|
39
|
+
<a href="/xruntime?offset=<%=[@offset + @limit, @ds.size].min%>&limit=<%=@limit%>">Next</a>
|
40
|
+
<% end %>
|
41
|
+
</div>
|
42
|
+
</body>
|
43
|
+
</html>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module XRuntime
|
2
|
+
class Template
|
3
|
+
def initialize(ds, opts={})
|
4
|
+
opts.delete_if{|k,v| v == nil}
|
5
|
+
opts = {:limit => 100, :offset => 0}.update(opts)
|
6
|
+
@ds = ds
|
7
|
+
@offset = opts[:offset]
|
8
|
+
@limit = opts[:limit]
|
9
|
+
@data = @ds.latest(:limit => opts[:limit], :offset => opts[:offset])
|
10
|
+
end
|
11
|
+
|
12
|
+
def render
|
13
|
+
Template.erb.result(binding)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.erb
|
17
|
+
@erb ||= ERB.new(self.html)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.html
|
21
|
+
@html ||= IO.read(File.join(File.dirname(__FILE__),'template.erb'))
|
22
|
+
end
|
23
|
+
end#end of Template
|
24
|
+
end
|
data/lib/x_runtime.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "pp"
|
2
|
+
require "rack"
|
3
|
+
require "redis"
|
4
|
+
require "digest"
|
5
|
+
require "fileutils"
|
6
|
+
|
7
|
+
require_relative "x_runtime/array"
|
8
|
+
|
9
|
+
$:.unshift(File.dirname(__FILE__))
|
10
|
+
|
11
|
+
module XRuntime
|
12
|
+
NameSpace = "RuntimeEx::Threshold"
|
13
|
+
end
|
14
|
+
|
15
|
+
XRuntime.autoload :Middleware, "x_runtime/middleware"
|
16
|
+
XRuntime.autoload :DataSet, "x_runtime/data_set"
|
17
|
+
XRuntime.autoload :Script, "x_runtime/script"
|
18
|
+
XRuntime.autoload :Template, "x_runtime/template"
|
19
|
+
XRuntime.autoload :Utils, "x_runtime/utils"
|
20
|
+
|
21
|
+
module Rack
|
22
|
+
XRuntime = XRuntime::Middleware
|
23
|
+
end
|
data/test/client.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
def alpha
|
2
|
+
# @@alpha ||= ('a'..'z').to_a | ('A'..'Z').to_a | ('0'..'9').to_a
|
3
|
+
@@alpha ||= ('a'..'z').to_a
|
4
|
+
end
|
5
|
+
|
6
|
+
def rand_url(size=1)
|
7
|
+
"http://localhost:4567/#{(1..size).to_a.inject(''){|s,t|s+=alpha[rand(alpha.size-1)].to_s}}"
|
8
|
+
end
|
9
|
+
|
10
|
+
100.times do
|
11
|
+
`curl "#{rand_url}" >/dev/null 2>&1`
|
12
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'x_runtime'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
data/test/server.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "sinatra"
|
2
|
+
require_relative "../lib/x_runtime"
|
3
|
+
|
4
|
+
# redis-server version must > 2.6.0 for lua script.
|
5
|
+
# use XRuntime::Middleware, 10, Redis.connect(:url => "redis://localhost:6380/")
|
6
|
+
use Rack::XRuntime, 10, Redis.connect(:url => "redis://localhost:6380/")
|
7
|
+
|
8
|
+
get /.*/ do
|
9
|
+
# sleep(1)
|
10
|
+
sleep(0.01*rand(10))
|
11
|
+
"Hello, I'am x_runtime"
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: x_runtime
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- 崔峥
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rack
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: jeweler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: active_support
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: redis
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 3.0.1
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 3.0.1
|
94
|
+
description: 由于使用到Redis的lua script,所以需要你的Redis服务支持,redis-server版本>2.6.x,redis(ruby
|
95
|
+
gem)>3.0.1.
|
96
|
+
email: zheng.cuizh@gmail.com
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files:
|
100
|
+
- LICENSE.txt
|
101
|
+
- README.markdown
|
102
|
+
files:
|
103
|
+
- Gemfile
|
104
|
+
- Gemfile.lock
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.markdown
|
107
|
+
- Rakefile
|
108
|
+
- VERSION
|
109
|
+
- lib/x_runtime.rb
|
110
|
+
- lib/x_runtime/array.rb
|
111
|
+
- lib/x_runtime/data_set.rb
|
112
|
+
- lib/x_runtime/middleware.rb
|
113
|
+
- lib/x_runtime/redis.lua
|
114
|
+
- lib/x_runtime/script.rb
|
115
|
+
- lib/x_runtime/template.erb
|
116
|
+
- lib/x_runtime/template.rb
|
117
|
+
- lib/x_runtime/utils.rb
|
118
|
+
- test/client.rb
|
119
|
+
- test/helper.rb
|
120
|
+
- test/server.rb
|
121
|
+
- test/test_x_runtime.rb
|
122
|
+
homepage: http://github.com/charlescui/x_runtime
|
123
|
+
licenses:
|
124
|
+
- MIT
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
hash: 1659196055007791068
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ! '>='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
144
|
+
requirements: []
|
145
|
+
rubyforge_project:
|
146
|
+
rubygems_version: 1.8.24
|
147
|
+
signing_key:
|
148
|
+
specification_version: 3
|
149
|
+
summary: XRuntime是一个Rack的middleware,配合Redis用来分析Http Server每个URI请求时长
|
150
|
+
test_files: []
|