samuel 0.1.0
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.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +30 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/lib/samuel.rb +33 -0
- data/lib/samuel/net_http.rb +10 -0
- data/lib/samuel/request.rb +75 -0
- data/samuel.gemspec +65 -0
- data/test/samuel_test.rb +90 -0
- data/test/test_helper.rb +57 -0
- metadata +107 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2009 Chris Kampmeier
|
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.rdoc
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
= Samuel
|
2
|
+
|
3
|
+
Samuel is a gem for automatic logging of your Net::HTTP requests. It's named for
|
4
|
+
the serial diarist Mr. Pepys, who was known to reliably record events both
|
5
|
+
quotidian and remarkable.
|
6
|
+
|
7
|
+
Should a Great Plague, Fire, or Whale befall an important external web service
|
8
|
+
you use, you'll be sure to have a tidy record of it.
|
9
|
+
|
10
|
+
== Usage in Rails:
|
11
|
+
|
12
|
+
# config/environment.rb
|
13
|
+
config.gem "samuel"
|
14
|
+
|
15
|
+
That's about it! For now, Samuel automatically uses Rails' logger, and logs at
|
16
|
+
the +INFO+ level using an ActiveRecord-like format. Failed requests log at the
|
17
|
+
+WARN+ level.
|
18
|
+
|
19
|
+
== Usage in general:
|
20
|
+
|
21
|
+
When Rails isn't loaded, you'll have to manually configure logging, like this:
|
22
|
+
|
23
|
+
require 'samuel'
|
24
|
+
Samuel.logger = Logger.new('http_requests.log')
|
25
|
+
|
26
|
+
If you don't assign a logger, Samuel will configure a default logger on +STDOUT+.
|
27
|
+
|
28
|
+
== License
|
29
|
+
|
30
|
+
Copyright 2009 Chris Kampmeier. See +LICENSE+ for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "samuel"
|
8
|
+
gem.summary = %Q{An automatic logger for HTTP requests in Ruby}
|
9
|
+
gem.description = %Q{An automatic logger for HTTP requests in Ruby. Adds Net::HTTP request logging to your Rails logs, and more.}
|
10
|
+
gem.email = "chris@kampers.net"
|
11
|
+
gem.homepage = "http://github.com/chrisk/samuel"
|
12
|
+
gem.authors = ["Chris Kampmeier"]
|
13
|
+
gem.rubyforge_project = "samuel"
|
14
|
+
gem.add_development_dependency "thoughtbot-shoulda"
|
15
|
+
gem.add_development_dependency "yard"
|
16
|
+
gem.add_development_dependency "mocha"
|
17
|
+
gem.add_development_dependency "fakeweb"
|
18
|
+
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
20
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
21
|
+
rubyforge.doc_task = "yardoc"
|
22
|
+
end
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
Rake::TestTask.new(:test) do |test|
|
29
|
+
test.libs << 'lib' << 'test'
|
30
|
+
test.pattern = 'test/**/*_test.rb'
|
31
|
+
test.verbose = false
|
32
|
+
test.warning = true
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
require 'rcov/rcovtask'
|
37
|
+
Rcov::RcovTask.new do |test|
|
38
|
+
test.libs << 'test'
|
39
|
+
test.pattern = 'test/**/*_test.rb'
|
40
|
+
test.rcov_opts << "--sort coverage"
|
41
|
+
test.rcov_opts << "--exclude gems"
|
42
|
+
test.verbose = false
|
43
|
+
test.warning = true
|
44
|
+
end
|
45
|
+
rescue LoadError
|
46
|
+
task :rcov do
|
47
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
task :test => :check_dependencies
|
52
|
+
|
53
|
+
task :default => :test
|
54
|
+
|
55
|
+
begin
|
56
|
+
require 'yard'
|
57
|
+
YARD::Rake::YardocTask.new
|
58
|
+
rescue LoadError
|
59
|
+
task :yardoc do
|
60
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
61
|
+
end
|
62
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/samuel.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "logger"
|
2
|
+
require "net/http"
|
3
|
+
require "net/https"
|
4
|
+
require "benchmark"
|
5
|
+
|
6
|
+
require "samuel/net_http"
|
7
|
+
require "samuel/request"
|
8
|
+
|
9
|
+
|
10
|
+
module Samuel
|
11
|
+
extend self
|
12
|
+
|
13
|
+
def logger=(new_logger)
|
14
|
+
@logger = new_logger
|
15
|
+
end
|
16
|
+
|
17
|
+
def logger
|
18
|
+
return @logger if !@logger.nil?
|
19
|
+
|
20
|
+
if defined?(RAILS_DEFAULT_LOGGER)
|
21
|
+
@logger = RAILS_DEFAULT_LOGGER
|
22
|
+
else
|
23
|
+
@logger = Logger.new(STDOUT)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def log_request(http, request, &block)
|
28
|
+
request = Request.new(http, request, block)
|
29
|
+
request.execute_and_log!
|
30
|
+
request.response
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Samuel
|
2
|
+
class Request
|
3
|
+
|
4
|
+
attr_accessor :response
|
5
|
+
|
6
|
+
def initialize(http, request, proc)
|
7
|
+
@http, @request, @proc = http, request, proc
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute_and_log!
|
11
|
+
# If an exception is raised in the Benchmark block, it'll interrupt the
|
12
|
+
# benchmark. Instead, use an inner block to record it as the "response"
|
13
|
+
# for raising after the benchmark (and logging) is done.
|
14
|
+
@seconds = Benchmark.realtime do
|
15
|
+
begin; @response = @proc.call; rescue Exception => @response; end
|
16
|
+
end
|
17
|
+
Samuel.logger.add(log_level, log_message)
|
18
|
+
raise @response if @response.is_a?(Exception)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def log_message
|
24
|
+
bold = "\e[1m"
|
25
|
+
blue = "\e[34m"
|
26
|
+
underline = "\e[4m"
|
27
|
+
reset = "\e[0m"
|
28
|
+
" #{bold}#{blue}#{underline}HTTP request (#{milliseconds}ms) " +
|
29
|
+
"#{response_summary}#{reset} #{method} #{uri}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def milliseconds
|
33
|
+
(@seconds * 1000).round
|
34
|
+
end
|
35
|
+
|
36
|
+
def uri
|
37
|
+
"#{scheme}://#{@http.address}#{port_if_not_default}#{@request.path}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def scheme
|
41
|
+
@http.use_ssl? ? "https" : "http"
|
42
|
+
end
|
43
|
+
|
44
|
+
def port_if_not_default
|
45
|
+
ssl, port = @http.use_ssl?, @http.port
|
46
|
+
if (!ssl && port == 80) || (ssl && port == 443)
|
47
|
+
""
|
48
|
+
else
|
49
|
+
":#{port}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def method
|
54
|
+
@request.method.to_s.upcase
|
55
|
+
end
|
56
|
+
|
57
|
+
def response_summary
|
58
|
+
if response.is_a?(Exception)
|
59
|
+
response.class
|
60
|
+
else
|
61
|
+
"[#{response.code} #{response.message}]"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def log_level
|
66
|
+
error_classes = [Exception, Net::HTTPClientError, Net::HTTPServerError]
|
67
|
+
if error_classes.any? { |klass| response.is_a?(klass) }
|
68
|
+
level = Logger::WARN
|
69
|
+
else
|
70
|
+
level = Logger::INFO
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
data/samuel.gemspec
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{samuel}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Chris Kampmeier"]
|
12
|
+
s.date = %q{2009-09-11}
|
13
|
+
s.description = %q{An automatic logger for HTTP requests in Ruby. Adds Net::HTTP request logging to your Rails logs, and more.}
|
14
|
+
s.email = %q{chris@kampers.net}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/samuel.rb",
|
27
|
+
"lib/samuel/net_http.rb",
|
28
|
+
"lib/samuel/request.rb",
|
29
|
+
"samuel.gemspec",
|
30
|
+
"test/samuel_test.rb",
|
31
|
+
"test/test_helper.rb"
|
32
|
+
]
|
33
|
+
s.homepage = %q{http://github.com/chrisk/samuel}
|
34
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubyforge_project = %q{samuel}
|
37
|
+
s.rubygems_version = %q{1.3.5}
|
38
|
+
s.summary = %q{An automatic logger for HTTP requests in Ruby}
|
39
|
+
s.test_files = [
|
40
|
+
"test/samuel_test.rb",
|
41
|
+
"test/test_helper.rb"
|
42
|
+
]
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<mocha>, [">= 0"])
|
52
|
+
s.add_development_dependency(%q<fakeweb>, [">= 0"])
|
53
|
+
else
|
54
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
55
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
56
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
57
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
61
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
62
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
63
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
64
|
+
end
|
65
|
+
end
|
data/test/samuel_test.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SamuelTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "making an HTTP request" do
|
6
|
+
setup { setup_test_logger
|
7
|
+
FakeWeb.clean_registry }
|
8
|
+
teardown { teardown_test_logger }
|
9
|
+
|
10
|
+
context "to GET http://example.com/test, responding with a 200 in 53ms" do
|
11
|
+
setup do
|
12
|
+
FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"])
|
13
|
+
Benchmark.stubs(:realtime).yields.returns(0.053)
|
14
|
+
open "http://example.com/test"
|
15
|
+
end
|
16
|
+
|
17
|
+
should_log_lines 1
|
18
|
+
should_log_at_level :info
|
19
|
+
should_log_including "HTTP request"
|
20
|
+
should_log_including "(53ms)"
|
21
|
+
should_log_including "[200 OK]"
|
22
|
+
should_log_including "GET http://example.com/test"
|
23
|
+
end
|
24
|
+
|
25
|
+
context "on a non-standard port" do
|
26
|
+
setup do
|
27
|
+
FakeWeb.register_uri(:get, "http://example.com:8080/test", :status => [200, "OK"])
|
28
|
+
open "http://example.com:8080/test"
|
29
|
+
end
|
30
|
+
|
31
|
+
should_log_including "GET http://example.com:8080/test"
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with SSL" do
|
35
|
+
setup do
|
36
|
+
FakeWeb.register_uri(:get, "https://example.com/test", :status => [200, "OK"])
|
37
|
+
open "https://example.com/test"
|
38
|
+
end
|
39
|
+
|
40
|
+
should_log_including "HTTP request"
|
41
|
+
should_log_including "GET https://example.com/test"
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with SSL on a non-standard port" do
|
45
|
+
setup do
|
46
|
+
FakeWeb.register_uri(:get, "https://example.com:80/test", :status => [200, "OK"])
|
47
|
+
open "https://example.com:80/test"
|
48
|
+
end
|
49
|
+
|
50
|
+
should_log_including "HTTP request"
|
51
|
+
should_log_including "GET https://example.com:80/test"
|
52
|
+
end
|
53
|
+
|
54
|
+
context "that raises" do
|
55
|
+
setup do
|
56
|
+
FakeWeb.register_uri(:get, "http://example.com/test", :exception => Errno::ECONNREFUSED)
|
57
|
+
begin
|
58
|
+
Net::HTTP.start("example.com") { |http| http.get("/test") }
|
59
|
+
rescue Errno::ECONNREFUSED => @exception
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
should_log_at_level :warn
|
64
|
+
should_log_including "HTTP request"
|
65
|
+
should_log_including "GET http://example.com/test"
|
66
|
+
should_log_including "Errno::ECONNREFUSED"
|
67
|
+
should_log_including %r|\d+ms|
|
68
|
+
should_raise_exception Errno::ECONNREFUSED
|
69
|
+
end
|
70
|
+
|
71
|
+
context "that responds with a 500-level code" do
|
72
|
+
setup do
|
73
|
+
FakeWeb.register_uri(:get, "http://example.com/test", :status => [502, "Bad Gateway"])
|
74
|
+
Net::HTTP.start("example.com") { |http| http.get("/test") }
|
75
|
+
end
|
76
|
+
|
77
|
+
should_log_at_level :warn
|
78
|
+
end
|
79
|
+
|
80
|
+
context "that responds with a 400-level code" do
|
81
|
+
setup do
|
82
|
+
FakeWeb.register_uri(:get, "http://example.com/test", :status => [404, "Not Found"])
|
83
|
+
Net::HTTP.start("example.com") { |http| http.get("/test") }
|
84
|
+
end
|
85
|
+
|
86
|
+
should_log_at_level :warn
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'mocha'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'fakeweb'
|
7
|
+
|
8
|
+
FakeWeb.allow_net_connect = false
|
9
|
+
|
10
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
11
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
12
|
+
require 'samuel'
|
13
|
+
|
14
|
+
class Test::Unit::TestCase
|
15
|
+
TEST_LOG_PATH = File.join(File.dirname(__FILE__), 'test.log')
|
16
|
+
|
17
|
+
def self.should_log_lines(expected_count)
|
18
|
+
should "log #{expected_count} line#{'s' unless expected_count == 1}" do
|
19
|
+
lines = File.readlines(TEST_LOG_PATH)
|
20
|
+
assert_equal expected_count, lines.length
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.should_log_including(what)
|
25
|
+
should "log a line including #{what.inspect}" do
|
26
|
+
contents = File.read(TEST_LOG_PATH)
|
27
|
+
if what.is_a?(Regexp)
|
28
|
+
assert_match what, contents
|
29
|
+
else
|
30
|
+
assert contents.include?(what)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.should_log_at_level(level)
|
36
|
+
level = level.to_s.upcase
|
37
|
+
should "log at the #{level} level" do
|
38
|
+
assert File.read(TEST_LOG_PATH).include?(" #{level} -- :")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.should_raise_exception(klass)
|
43
|
+
should "raise an #{klass} exception" do
|
44
|
+
assert @exception.is_a?(klass)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def setup_test_logger
|
49
|
+
FileUtils.rm_rf TEST_LOG_PATH
|
50
|
+
FileUtils.touch TEST_LOG_PATH
|
51
|
+
Samuel.logger = Logger.new(TEST_LOG_PATH)
|
52
|
+
end
|
53
|
+
|
54
|
+
def teardown_test_logger
|
55
|
+
FileUtils.rm_rf TEST_LOG_PATH
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: samuel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Kampmeier
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-11 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thoughtbot-shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: yard
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: mocha
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: fakeweb
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
description: An automatic logger for HTTP requests in Ruby. Adds Net::HTTP request logging to your Rails logs, and more.
|
56
|
+
email: chris@kampers.net
|
57
|
+
executables: []
|
58
|
+
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- LICENSE
|
63
|
+
- README.rdoc
|
64
|
+
files:
|
65
|
+
- .document
|
66
|
+
- .gitignore
|
67
|
+
- LICENSE
|
68
|
+
- README.rdoc
|
69
|
+
- Rakefile
|
70
|
+
- VERSION
|
71
|
+
- lib/samuel.rb
|
72
|
+
- lib/samuel/net_http.rb
|
73
|
+
- lib/samuel/request.rb
|
74
|
+
- samuel.gemspec
|
75
|
+
- test/samuel_test.rb
|
76
|
+
- test/test_helper.rb
|
77
|
+
has_rdoc: true
|
78
|
+
homepage: http://github.com/chrisk/samuel
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options:
|
83
|
+
- --charset=UTF-8
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
version:
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: "0"
|
97
|
+
version:
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project: samuel
|
101
|
+
rubygems_version: 1.3.5
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: An automatic logger for HTTP requests in Ruby
|
105
|
+
test_files:
|
106
|
+
- test/samuel_test.rb
|
107
|
+
- test/test_helper.rb
|