aliyun_sls_sdk 0.0.6 → 0.0.7
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.
- checksums.yaml +4 -4
- data/lib/aliyun_sls_sdk/get_log_store_response.rb +13 -0
- data/lib/aliyun_sls_sdk/log_client.rb +35 -24
- data/lib/aliyun_sls_sdk/log_exception.rb +15 -0
- data/lib/aliyun_sls_sdk/version.rb +1 -1
- data/lib/aliyun_sls_sdk.rb +2 -1
- metadata +4 -3
- data/lib/aliyun_sls_sdk/connection.rb +0 -251
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cc8dd23dc081504838e6cd2b4c8cc50dfe504a9
|
4
|
+
data.tar.gz: 3934f12ddfd4f13221bf5a0c3502f467205cf064
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e2a6200ca463e4f83a838f830d858253623379f6b3c3667928b082159ce702ef3b42c13c5ef9279408d654fe362611a4ef9f8913953ce53c7f31efe95cdea2e
|
7
|
+
data.tar.gz: aa2c99f77d280e28948560312e6b0d03ead80b8250efeed8181b540064c65e61859f9c1012b61492835c4a49fa4a299783e7e7fb6f2698cbe208cf7666ef6757
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module AliyunSlsSdk
|
2
|
+
class GetLogStoreResponse < LogResponse
|
3
|
+
|
4
|
+
attr_accessor :ttl, :shard_count, :logstore_name
|
5
|
+
def initialize(resp, header)
|
6
|
+
super(header)
|
7
|
+
puts resp
|
8
|
+
@logstore_name = resp["logstoreName"]
|
9
|
+
@ttl = resp["ttl"] ? resp["ttl"].to_i : 0
|
10
|
+
@shard_count = resp["shardCount"] ? resp["shardCount"].to_i : 0
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -9,12 +9,22 @@ module AliyunSlsSdk
|
|
9
9
|
@@API_VERSION = "0.6.0"
|
10
10
|
@@USER_AGENT = "log-ruby-sdk-v-0.6.1"
|
11
11
|
@@http = Net::HTTP::Persistent.new
|
12
|
-
def initialize(endpoint, accessKeyId, accessKeySecret)
|
12
|
+
def initialize(endpoint, accessKeyId, accessKeySecret, ssl_verify = false)
|
13
13
|
@endpoint = endpoint
|
14
14
|
@accessKeyId = accessKeyId
|
15
15
|
@accessKeySecret = accessKeySecret
|
16
|
+
@ssl_verify = ssl_verify
|
16
17
|
end
|
17
18
|
|
19
|
+
def get_logstore(project_name, logstore_name)
|
20
|
+
headers = {}
|
21
|
+
params = {}
|
22
|
+
resource = "/logstores/" + logstore_name
|
23
|
+
resp, header = send("GET", project_name, nil, resource, params, headers)
|
24
|
+
return GetLogStoreResponse.new(resp, header)
|
25
|
+
end
|
26
|
+
|
27
|
+
|
18
28
|
def create_logstore(project_name, logstore_name, ttl, shard_count)
|
19
29
|
headers = {}
|
20
30
|
params = {}
|
@@ -101,7 +111,8 @@ module AliyunSlsSdk
|
|
101
111
|
end
|
102
112
|
headers['x-log-apiversion'] = @@API_VERSION
|
103
113
|
headers['x-log-signaturemethod'] = 'hmac-sha1'
|
104
|
-
|
114
|
+
scheme = @ssl_verify ? "https" : "http"
|
115
|
+
url = "#{scheme}://" + project + "." + @endpoint
|
105
116
|
headers['Host'] = project + "." + @endpoint
|
106
117
|
headers['Date'] = headers["Date"] = DateTime.now.httpdate
|
107
118
|
signature = Util.get_request_authorization(method, resource,
|
@@ -111,6 +122,18 @@ module AliyunSlsSdk
|
|
111
122
|
return sendRequest(method, url, params, body, headers, respons_body_type)
|
112
123
|
end
|
113
124
|
|
125
|
+
def loadJson(respText, requestId)
|
126
|
+
if respText.empty?
|
127
|
+
return nil
|
128
|
+
else
|
129
|
+
begin
|
130
|
+
return JSON.parse(respText)
|
131
|
+
rescue JSON::ParserError => e
|
132
|
+
raise LogException.new("BadResponse", "Bad json format:\n#{respText}", requestId)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
114
137
|
def sendRequest(method, url, params, body, headers, respons_body_type = 'json')
|
115
138
|
statusCode, respBody, respHeaders = getHttpResponse(method, url, params, body, headers)
|
116
139
|
if respHeaders['x-log-requestid']
|
@@ -121,34 +144,22 @@ module AliyunSlsSdk
|
|
121
144
|
|
122
145
|
if statusCode == '200'
|
123
146
|
if respons_body_type == 'json'
|
124
|
-
return respBody
|
125
|
-
else
|
126
|
-
return respBody, respHeaders
|
127
|
-
end
|
128
|
-
elsif statusCode.to_s =~ /[4|5]\d\d/
|
129
|
-
msg = "status: #{statusCode}, request_id: #{requestId}, body: #{respBody}"
|
130
|
-
if $logger and $logger.respond_to?(:error)
|
131
|
-
$logger.error msg
|
132
|
-
else
|
133
|
-
puts msg
|
134
|
-
end
|
135
|
-
if respons_body_type == 'json'
|
136
|
-
return respBody.to_json, respHeaders
|
147
|
+
return loadJson(respBody, requestId), respHeaders
|
137
148
|
else
|
138
149
|
return respBody, respHeaders
|
139
150
|
end
|
151
|
+
end
|
152
|
+
respJson = loadJson(respBody, requestId)
|
153
|
+
if respJson["errorCode"] and respJson["errorMessage"]
|
154
|
+
raise LogException.new(respJson["errorCode"], respJson["errorMessage"], requestId)
|
140
155
|
else
|
141
|
-
|
142
|
-
if
|
143
|
-
|
156
|
+
exStr = ""
|
157
|
+
if respBody
|
158
|
+
exStr = ". Return Json is #{respBody}"
|
144
159
|
else
|
145
|
-
|
146
|
-
end
|
147
|
-
if respons_body_type == 'json'
|
148
|
-
return respBody.to_json, respHeaders
|
149
|
-
else
|
150
|
-
return respBody, respHeaders
|
160
|
+
exStr = "."
|
151
161
|
end
|
162
|
+
raise LogException.new("LogRequestError", "Request is failed. Http code is #{statusCode} #{exStr}", requestId)
|
152
163
|
end
|
153
164
|
end
|
154
165
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
module AliyunSlsSdk
|
3
|
+
class LogException < StandardError
|
4
|
+
attr_accessor :errorCode, :errorMessage, :requestId
|
5
|
+
def initialize(errorCode, errorMessage, requestId)
|
6
|
+
@errorCode = errorCode
|
7
|
+
@errorMessage = errorMessage
|
8
|
+
@requestId = requestId
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s()
|
12
|
+
"LogException: \n{\n ErrorCode: #{@errorCode}\n ErrorMessage: #{@errorMessage}\n RequestId: #{@requestId}\n}\n"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/aliyun_sls_sdk.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'version.rb')
|
2
|
-
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'connection.rb')
|
3
2
|
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'protobuf.rb')
|
4
3
|
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'log_request.rb')
|
5
4
|
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'get_log_request.rb')
|
@@ -10,6 +9,8 @@ require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'util.rb')
|
|
10
9
|
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'log_client.rb')
|
11
10
|
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'log_item.rb')
|
12
11
|
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'create_log_store_response.rb')
|
12
|
+
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'get_log_store_response.rb')
|
13
|
+
require File.join(File.dirname(__FILE__), 'aliyun_sls_sdk', 'log_exception.rb')
|
13
14
|
|
14
15
|
module AliyunSlsSdk
|
15
16
|
class PostBodyInvalid < RuntimeError;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aliyun_sls_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- linhua.tlh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -121,10 +121,11 @@ files:
|
|
121
121
|
- README.md
|
122
122
|
- aliyun_sls_sdk.gemspec
|
123
123
|
- lib/aliyun_sls_sdk.rb
|
124
|
-
- lib/aliyun_sls_sdk/connection.rb
|
125
124
|
- lib/aliyun_sls_sdk/create_log_store_response.rb
|
126
125
|
- lib/aliyun_sls_sdk/get_log_request.rb
|
126
|
+
- lib/aliyun_sls_sdk/get_log_store_response.rb
|
127
127
|
- lib/aliyun_sls_sdk/log_client.rb
|
128
|
+
- lib/aliyun_sls_sdk/log_exception.rb
|
128
129
|
- lib/aliyun_sls_sdk/log_item.rb
|
129
130
|
- lib/aliyun_sls_sdk/log_request.rb
|
130
131
|
- lib/aliyun_sls_sdk/log_response.rb
|
@@ -1,251 +0,0 @@
|
|
1
|
-
require "addressable/uri"
|
2
|
-
require 'hmac-sha1'
|
3
|
-
require "base64"
|
4
|
-
require "zlib"
|
5
|
-
require "time"
|
6
|
-
require "net/http/persistent"
|
7
|
-
require "json"
|
8
|
-
|
9
|
-
module AliyunSlsSdk
|
10
|
-
class Connection
|
11
|
-
|
12
|
-
def initialize(project, region_endpoint, aliyun_access_key_id, aliyun_access_key_secret, opts={})
|
13
|
-
default_headers = {
|
14
|
-
"x-sls-apiversion" => "0.6.0",
|
15
|
-
"x-sls-signaturemethod" => "hmac-sha1"
|
16
|
-
}
|
17
|
-
@headers = default_headers.update opts
|
18
|
-
@aliyun_access_key_id = aliyun_access_key_id
|
19
|
-
@aliyun_access_key_secret = aliyun_access_key_secret
|
20
|
-
@host = "#{project}.#{region_endpoint}"
|
21
|
-
@http = Net::HTTP::Persistent.new
|
22
|
-
# @http.debug_output = $stdout
|
23
|
-
end
|
24
|
-
|
25
|
-
# https://help.aliyun.com/document_detail/29015.html
|
26
|
-
def create_logstore(logStoreName, ttl, shardCount, ssl_verify = false)
|
27
|
-
body = {:logstoreName => logStoreName, :ttl => ttl, :shardCount => shardCount}
|
28
|
-
content = body.to_json
|
29
|
-
# 压缩content数据
|
30
|
-
compressed = Zlib::Deflate.deflate(content.encode.to_s)
|
31
|
-
headers = compact_headers(content, compressed)
|
32
|
-
headers["Authorization"] = signature("POST", nil, headers, content, {})
|
33
|
-
scheme = ssl_verify ? "https" : "http"
|
34
|
-
|
35
|
-
post_uri = URI "#{scheme}://#{@host}/logstores"
|
36
|
-
post = Net::HTTP::Post.new(post_uri.request_uri, headers)
|
37
|
-
post.body = compressed
|
38
|
-
response = @http.request post_uri, post
|
39
|
-
parse_response(response)
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
# http://docs.aliyun.com/#/pub/sls/api/apilist&PutLogs
|
44
|
-
def puts_logs(logstorename, content, ssl_verify = false)
|
45
|
-
# 压缩content数据
|
46
|
-
compressed = Zlib::Deflate.deflate(content.encode.to_s)
|
47
|
-
headers = compact_headers(content, compressed)
|
48
|
-
headers["Authorization"] = signature("POST", logstorename, headers, content, {})
|
49
|
-
scheme = ssl_verify ? "https" : "http"
|
50
|
-
|
51
|
-
post_uri = URI "#{scheme}://#{@host}/logstores/#{logstorename}"
|
52
|
-
post = Net::HTTP::Post.new(post_uri.request_uri, headers)
|
53
|
-
post.body = compressed
|
54
|
-
response = @http.request post_uri, post
|
55
|
-
parse_response(response)
|
56
|
-
end
|
57
|
-
|
58
|
-
# http://docs.aliyun.com/#/pub/sls/api/apilist&ListLogstores
|
59
|
-
def list_logstores(ssl_verify = false)
|
60
|
-
headers = compact_headers(nil, nil)
|
61
|
-
headers["Authorization"] = signature("GET", nil, headers, nil, {})
|
62
|
-
|
63
|
-
scheme = ssl_verify ? "https" : "http"
|
64
|
-
get_uri = URI "#{scheme}://#{@host}/logstores"
|
65
|
-
headers["Referer"] = get_uri.to_s
|
66
|
-
get = Net::HTTP::Get.new(get_uri.request_uri, headers)
|
67
|
-
response = @http.request get_uri, get
|
68
|
-
parse_response(response)
|
69
|
-
end
|
70
|
-
|
71
|
-
# http://docs.aliyun.com/#/pub/sls/api/apilist&GetLogs
|
72
|
-
def get_logs(logstorename, ssl_verify=false, opts={})
|
73
|
-
default_opts = {
|
74
|
-
:type => "log",
|
75
|
-
:from => Time.now.to_i - 60*5, #默认是五分钟前
|
76
|
-
:to => Time.now.to_i,
|
77
|
-
# :line => 100,
|
78
|
-
# :offset => 0,
|
79
|
-
:reverse => false
|
80
|
-
}
|
81
|
-
opts = default_opts.update opts
|
82
|
-
headers = compact_headers(nil, nil)
|
83
|
-
headers["Authorization"] = signature("GET", logstorename, headers, nil, opts)
|
84
|
-
scheme = ssl_verify ? "https" : "http"
|
85
|
-
get_uri = Addressable::URI.parse("#{scheme}://#{@host}/logstores/#{logstorename}")
|
86
|
-
headers["Referer"] = get_uri.to_s
|
87
|
-
get_uri.query_values = opts
|
88
|
-
get = Net::HTTP::Get.new(get_uri.request_uri, headers)
|
89
|
-
response = @http.request get_uri, get
|
90
|
-
parse_response(response)
|
91
|
-
end
|
92
|
-
|
93
|
-
# http://docs.aliyun.com/#/pub/sls/api/apilist&ListTopics
|
94
|
-
def list_topics(logstorename, ssl_verify=false, opts={})
|
95
|
-
default_opts = {
|
96
|
-
:type => "topic",
|
97
|
-
:line => 100,
|
98
|
-
:toke => ""
|
99
|
-
}
|
100
|
-
opts = default_opts.update opts
|
101
|
-
headers = compact_headers(nil, nil)
|
102
|
-
headers["Authorization"] = signature("GET", logstorename, headers, nil, opts)
|
103
|
-
scheme = ssl_verify ? "https" : "http"
|
104
|
-
get_uri = Addressable::URI.parse("#{scheme}://#{@host}/logstores/#{logstorename}")
|
105
|
-
headers["Referer"] = get_uri.to_s
|
106
|
-
get_uri.query_values = opts
|
107
|
-
get = Net::HTTP::Get.new(get_uri.request_uri, headers)
|
108
|
-
response = @http.request get_uri, get
|
109
|
-
parse_response(response)
|
110
|
-
end
|
111
|
-
|
112
|
-
# http://docs.aliyun.com/#/pub/sls/api/apilist&GetHistograms
|
113
|
-
def get_histograms(logstorename, ssl_verify=false, opts={})
|
114
|
-
default_opts = {
|
115
|
-
:type => "histogram",
|
116
|
-
:from => Time.now.to_i - 60*5, #默认是五分钟前
|
117
|
-
:to => Time.now.to_i,
|
118
|
-
:topic => "",
|
119
|
-
:query => "",
|
120
|
-
}
|
121
|
-
opts = default_opts.update opts
|
122
|
-
headers = compact_headers(nil, nil)
|
123
|
-
headers["Authorization"] = signature("GET", logstorename, headers, nil, opts)
|
124
|
-
scheme = ssl_verify ? "https" : "http"
|
125
|
-
get_uri = Addressable::URI.parse("#{scheme}://#{@host}/logstores/#{logstorename}")
|
126
|
-
headers["Referer"] = get_uri.to_s
|
127
|
-
get_uri.query_values = opts
|
128
|
-
get = Net::HTTP::Get.new(get_uri.request_uri, headers)
|
129
|
-
response = @http.request get_uri, get
|
130
|
-
parse_response(response)
|
131
|
-
end
|
132
|
-
|
133
|
-
private
|
134
|
-
|
135
|
-
def string_to_sign(verb, logstorename, headers, content, query={})
|
136
|
-
if content
|
137
|
-
string_to_sign_with_content(verb, logstorename, headers, query)
|
138
|
-
else
|
139
|
-
string_to_sign_without_content(verb, logstorename, headers, query)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def string_to_sign_with_content(verb, logstorename, headers, query={})
|
144
|
-
|
145
|
-
<<~DOC
|
146
|
-
#{verb}
|
147
|
-
#{headers['Content-MD5']}
|
148
|
-
#{headers['Content-Type']}
|
149
|
-
#{headers['Date']}
|
150
|
-
#{canonicalized_sls_headers(headers)}
|
151
|
-
#{canonicalized_resource(logstorename, query)}
|
152
|
-
DOC
|
153
|
-
end
|
154
|
-
|
155
|
-
def string_to_sign_without_content(verb, logstorename, headers, query={})
|
156
|
-
<<~DOC
|
157
|
-
#{verb}
|
158
|
-
|
159
|
-
|
160
|
-
#{headers['Date']}
|
161
|
-
#{canonicalized_sls_headers(headers)}
|
162
|
-
#{canonicalized_resource(logstorename, query)}
|
163
|
-
DOC
|
164
|
-
end
|
165
|
-
|
166
|
-
# “CanonicalizedSLSHeaders”的构造方式如下:
|
167
|
-
# 1. 将所有以“x-sls-”为前缀的HTTP请求头的名字转换成小写字母;
|
168
|
-
# 2. 将上一步得到的所有SLS自定义请求头按照字典序进行升序排序;
|
169
|
-
# 3. 删除请求头和内容之间分隔符两端出现的任何空格;
|
170
|
-
# 4. 将所有的头和内容用\n分隔符组合成最后的CanonicalizedSLSHeader;
|
171
|
-
def canonicalized_sls_headers(headers)
|
172
|
-
h = {}
|
173
|
-
headers.each { |k, v|
|
174
|
-
if k =~ /x-sls-.*/
|
175
|
-
h[k.downcase] = v
|
176
|
-
end
|
177
|
-
}
|
178
|
-
h.keys.sort.map { |e|
|
179
|
-
h[e]
|
180
|
-
"#{e}:#{h[e].gsub(/^\s+/, '')}"
|
181
|
-
}.join($/)
|
182
|
-
end
|
183
|
-
|
184
|
-
# “CanonicalizedResource”的构造方式如下:
|
185
|
-
# 1. 将CanonicalizedResource设置为空字符串("");
|
186
|
-
# 2. 放入要访问的SLS资源:"/logstores/logstorename"(无logstorename则不填);
|
187
|
-
# 3. 如请求包含查询字符串(QUERY_STRING),则在CanonicalizedResource字符串尾部添加“?”和查询字符串。
|
188
|
-
def canonicalized_resource(logstorename, query={})
|
189
|
-
u = logstorename ? Addressable::URI.parse("/logstores/#{logstorename}") : Addressable::URI.parse("/logstores")
|
190
|
-
if query.size != 0
|
191
|
-
# 不能对请求的URL参数做URLEncode编码
|
192
|
-
q_str = query.keys.sort.map { |e|
|
193
|
-
"#{e}=#{query[e]}"
|
194
|
-
}.join('&')
|
195
|
-
"#{u}?#{q_str}"
|
196
|
-
else
|
197
|
-
u.to_s
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
# 目前,SLS API只支持一种数字签名算法,即默认签名算法"hmac-sha1"。其整个签名公式如下:
|
202
|
-
# Signature = base64(hmac-sha1(UTF8-Encoding-Of(SignString),AccessKeySecret))
|
203
|
-
def sign(method, logstorename, headers, content, query)
|
204
|
-
Base64.encode64((HMAC::SHA1.new(@aliyun_access_key_secret) << string_to_sign(method, logstorename, headers, content, query).chomp).digest).strip
|
205
|
-
end
|
206
|
-
|
207
|
-
def signature(method, logstorename, headers, content, query)
|
208
|
-
"SLS #{@aliyun_access_key_id}:#{sign(method, logstorename, headers, content, query)}"
|
209
|
-
end
|
210
|
-
|
211
|
-
# https://help.aliyun.com/document_detail/29010.html
|
212
|
-
def setup_common_headers()
|
213
|
-
|
214
|
-
end
|
215
|
-
|
216
|
-
# content是LogGroup
|
217
|
-
def compact_headers(content, compressed)
|
218
|
-
headers = @headers.dup
|
219
|
-
# headers["x-sls-date"] =
|
220
|
-
headers["Date"] = DateTime.now.httpdate
|
221
|
-
headers["x-sls-bodyrawsize"] = "0"
|
222
|
-
|
223
|
-
if content and compressed
|
224
|
-
body = content.encode.to_s
|
225
|
-
headers["Content-Length"] = compressed.bytesize.to_s
|
226
|
-
# 日志内容包含的日志必须小于3MB和4096条。
|
227
|
-
raise AliyunSls::PostBodyTooLarge, "content length is larger than 3MB" if headers["Content-Length"].to_i > 3*1024**2*8
|
228
|
-
# raise AliyunSls::PostBodyTooLarge, "content size is more than 4096" if content.logs && content.logs.size > 4096
|
229
|
-
# MD5必须为大写字符串
|
230
|
-
headers["Content-MD5"] = Digest::MD5.hexdigest(compressed).upcase
|
231
|
-
headers["Content-Type"] = "application/json"
|
232
|
-
headers["x-sls-bodyrawsize"] = body.bytesize.to_s
|
233
|
-
headers["x-sls-compresstype"] = "deflate"
|
234
|
-
end
|
235
|
-
headers
|
236
|
-
end
|
237
|
-
|
238
|
-
def parse_response(response)
|
239
|
-
# 如果返回结果报错,则解析报错内容打印到日志中
|
240
|
-
if response.code.to_s =~ /[4|5]\d\d/
|
241
|
-
msg = "status #{response.code} body #{response.body}"
|
242
|
-
if $logger and $logger.respond_to?(:error)
|
243
|
-
$logger.error msg
|
244
|
-
else
|
245
|
-
puts msg
|
246
|
-
end
|
247
|
-
end
|
248
|
-
response
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|