thinkingdata-ruby 1.2.0 → 2.0.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.
- checksums.yaml +4 -4
- data/.gitignore +59 -0
- data/CHANGELOG.md +22 -14
- data/Gemfile +7 -7
- data/LICENSE +201 -201
- data/README.md +11 -202
- data/demo/demo.rb +104 -142
- data/lib/thinkingdata-ruby/td_analytics.rb +495 -0
- data/lib/thinkingdata-ruby/{batch_consumer.rb → td_batch_consumer.rb} +142 -120
- data/lib/thinkingdata-ruby/td_debug_consumer.rb +73 -0
- data/lib/thinkingdata-ruby/td_errors.rb +38 -0
- data/lib/thinkingdata-ruby/td_logger_consumer.rb +77 -0
- data/lib/thinkingdata-ruby/td_version.rb +3 -0
- data/lib/thinkingdata-ruby.rb +5 -5
- data/thinkingdata-ruby.gemspec +16 -16
- metadata +13 -12
- data/lib/thinkingdata-ruby/debug_consumer.rb +0 -61
- data/lib/thinkingdata-ruby/errors.rb +0 -35
- data/lib/thinkingdata-ruby/logger_consumer.rb +0 -57
- data/lib/thinkingdata-ruby/tracker.rb +0 -402
- data/lib/thinkingdata-ruby/version.rb +0 -3
@@ -1,120 +1,142 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'net/http'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@
|
18
|
-
@
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
module ThinkingData
|
6
|
+
##
|
7
|
+
# Upload data by http
|
8
|
+
class TDBatchConsumer
|
9
|
+
|
10
|
+
# buffer count
|
11
|
+
DEFAULT_LENGTH = 20
|
12
|
+
MAX_LENGTH = 2000
|
13
|
+
|
14
|
+
##
|
15
|
+
# Init batch consumer
|
16
|
+
def initialize(server_url, app_id, max_buffer_length = DEFAULT_LENGTH)
|
17
|
+
@server_uri = URI.parse(server_url)
|
18
|
+
@server_uri.path = '/sync_server'
|
19
|
+
@app_id = app_id
|
20
|
+
@compress = true
|
21
|
+
@max_length = [max_buffer_length, MAX_LENGTH].min
|
22
|
+
@buffers = []
|
23
|
+
TDLog.info("TDBatchConsumer init success. ServerUrl: #{server_url}, appId: #{app_id}")
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# http request compress
|
28
|
+
# @param compress [Boolean] compress or not
|
29
|
+
# @deprecated please use: set_compress
|
30
|
+
def _set_compress(compress)
|
31
|
+
@compress = compress
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# http request compress
|
36
|
+
# @param compress [Boolean] compress or not
|
37
|
+
def set_compress(compress)
|
38
|
+
@compress = compress
|
39
|
+
end
|
40
|
+
|
41
|
+
def add(message)
|
42
|
+
TDLog.info("Enqueue data to buffer. buffer size: #{@buffers.length}, data: #{message}")
|
43
|
+
@buffers << message
|
44
|
+
flush if @buffers.length >= @max_length
|
45
|
+
end
|
46
|
+
|
47
|
+
def close
|
48
|
+
flush
|
49
|
+
TDLog.info("TDBatchConsumer close.")
|
50
|
+
end
|
51
|
+
|
52
|
+
def flush
|
53
|
+
TDLog.info("TDBatchConsumer flush data.")
|
54
|
+
begin
|
55
|
+
@buffers.each_slice(@max_length) do |chunk|
|
56
|
+
if @compress
|
57
|
+
wio = StringIO.new("w")
|
58
|
+
gzip_io = Zlib::GzipWriter.new(wio)
|
59
|
+
gzip_io.write(chunk.to_json)
|
60
|
+
gzip_io.close
|
61
|
+
data = wio.string
|
62
|
+
else
|
63
|
+
data = chunk.to_json
|
64
|
+
end
|
65
|
+
compress_type = @compress ? 'gzip' : 'none'
|
66
|
+
headers = {'Content-Type' => 'application/plaintext',
|
67
|
+
'appid' => @app_id,
|
68
|
+
'compress' => compress_type,
|
69
|
+
'TE-Integration-Type'=>'Ruby',
|
70
|
+
'TE-Integration-Version'=>ThinkingData::VERSION,
|
71
|
+
'TE-Integration-Count'=>@buffers.count,
|
72
|
+
'TA_Integration-Extra'=>'batch'}
|
73
|
+
request = CaseSensitivePost.new(@server_uri.request_uri, headers)
|
74
|
+
request.body = data
|
75
|
+
|
76
|
+
TDLog.info("Send data, request: #{data}")
|
77
|
+
begin
|
78
|
+
response_code, response_body = _request(@server_uri, request)
|
79
|
+
TDLog.info("Send data, response: #{response_body}")
|
80
|
+
rescue => e
|
81
|
+
raise ConnectionError.new("Could not connect to TE server, with error \"#{e.message}\".")
|
82
|
+
end
|
83
|
+
|
84
|
+
result = {}
|
85
|
+
if response_code.to_i == 200
|
86
|
+
begin
|
87
|
+
result = JSON.parse(response_body.to_s)
|
88
|
+
rescue JSON::JSONError
|
89
|
+
raise ServerError.new("Could not interpret TE server response: '#{response_body}'")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
if result['code'] != 0
|
94
|
+
raise ServerError.new("Could not write to TE, server responded with #{response_code} returning: '#{response_body}'")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
rescue
|
98
|
+
raise
|
99
|
+
end
|
100
|
+
@buffers = []
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
def _request(uri, request)
|
105
|
+
client = Net::HTTP.new(uri.host, uri.port)
|
106
|
+
client.use_ssl = uri.scheme === 'https' ? true : false
|
107
|
+
client.open_timeout = 10
|
108
|
+
client.continue_timeout = 10
|
109
|
+
client.read_timeout = 10
|
110
|
+
client.ssl_timeout = 10
|
111
|
+
|
112
|
+
response = client.request(request)
|
113
|
+
[response.code, response.body]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# Private class. Send data tools
|
119
|
+
class CaseSensitivePost < Net::HTTP::Post
|
120
|
+
def initialize_http_header(headers)
|
121
|
+
@header = {}
|
122
|
+
headers.each{|k,v| @header[k.to_s] = [v] }
|
123
|
+
end
|
124
|
+
|
125
|
+
def [](name)
|
126
|
+
@header[name.to_s]
|
127
|
+
end
|
128
|
+
|
129
|
+
def []=(name, val)
|
130
|
+
if val
|
131
|
+
@header[name.to_s] = [val]
|
132
|
+
else
|
133
|
+
@header.delete(name.to_s)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def capitalize(name)
|
138
|
+
name
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module ThinkingData
|
5
|
+
##
|
6
|
+
# The data is reported one by one, and when an error occurs, the log will be printed on the console.
|
7
|
+
class TDDebugConsumer
|
8
|
+
|
9
|
+
##
|
10
|
+
# Init debug consumer
|
11
|
+
# @param server_url: server url
|
12
|
+
# @param app_id: app id
|
13
|
+
# @param write_data: is write data to TE
|
14
|
+
# @param device_id: device id
|
15
|
+
def initialize(server_url, app_id, write_data = true, device_id: nil)
|
16
|
+
@server_uri = URI.parse(server_url)
|
17
|
+
@server_uri.path = '/data_debug'
|
18
|
+
@app_id = app_id
|
19
|
+
@write_data = write_data
|
20
|
+
@device_id = device_id
|
21
|
+
TDLog.info("TDDebugConsumer init success. ServerUrl: #{server_url}, appId: #{app_id}, deviceId: #{device_id}")
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(message)
|
25
|
+
msg_json_str = message.to_json
|
26
|
+
TDLog.info("Send data, request: #{msg_json_str}")
|
27
|
+
headers = {
|
28
|
+
'TE-Integration-Type'=>'Ruby',
|
29
|
+
'TE-Integration-Version'=>ThinkingData::VERSION,
|
30
|
+
'TE-Integration-Count'=>'1',
|
31
|
+
'TA_Integration-Extra'=>'debug'
|
32
|
+
}
|
33
|
+
form_data = {"data" => msg_json_str, "appid" => @app_id, "dryRun" => @write_data ? "0" : "1", "source" => "server"}
|
34
|
+
@device_id.is_a?(String) ? form_data["deviceId"] = @device_id : nil
|
35
|
+
|
36
|
+
begin
|
37
|
+
response_code, response_body = request(@server_uri, form_data,headers)
|
38
|
+
TDLog.info("Send data, response: #{response_body}")
|
39
|
+
rescue => e
|
40
|
+
raise ConnectionError.new("Could not connect to TE server, with error \"#{e.message}\".")
|
41
|
+
end
|
42
|
+
|
43
|
+
result = {}
|
44
|
+
if response_code.to_i == 200
|
45
|
+
begin
|
46
|
+
result = JSON.parse(response_body.to_s)
|
47
|
+
rescue JSON::JSONError
|
48
|
+
raise ServerError.new("Could not interpret TE server response: '#{response_body}'")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if result['errorLevel'] != 0
|
53
|
+
raise ServerError.new("Could not write to TE, server responded with #{response_code} returning: '#{response_body}'")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def request(uri, form_data,headers)
|
58
|
+
request = Net::HTTP::Post.new(uri.request_uri, headers)
|
59
|
+
request.set_form_data(form_data)
|
60
|
+
|
61
|
+
client = Net::HTTP.new(uri.host, uri.port)
|
62
|
+
client.use_ssl = uri.scheme === 'https' ? true : false
|
63
|
+
client.open_timeout = 10
|
64
|
+
client.continue_timeout = 10
|
65
|
+
client.read_timeout = 10
|
66
|
+
client.ssl_timeout = 10
|
67
|
+
|
68
|
+
response = client.request(request)
|
69
|
+
[response.code, response.body]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ThinkingData
|
2
|
+
##
|
3
|
+
# SDK error
|
4
|
+
TDAnalyticsError = Class.new(StandardError)
|
5
|
+
|
6
|
+
##
|
7
|
+
# SDK error: illegal parameter
|
8
|
+
IllegalParameterError = Class.new(TDAnalyticsError)
|
9
|
+
|
10
|
+
##
|
11
|
+
# SDK error: connection error
|
12
|
+
ConnectionError = Class.new(TDAnalyticsError)
|
13
|
+
|
14
|
+
##
|
15
|
+
# SDK error: server error
|
16
|
+
ServerError = Class.new(TDAnalyticsError)
|
17
|
+
|
18
|
+
##
|
19
|
+
# Error handler
|
20
|
+
#
|
21
|
+
# e.g.
|
22
|
+
# class MyErrorHandler < ThinkingData::ErrorHandler
|
23
|
+
# def handle(error)
|
24
|
+
# puts error
|
25
|
+
# raise error
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# my_error_handler = MyErrorHandler.new
|
30
|
+
# tracker = ThinkingData::TDAnalytics.new(consumer, my_error_handler)
|
31
|
+
class TDErrorHandler
|
32
|
+
##
|
33
|
+
# Override #handle to customize error handling
|
34
|
+
def handle(error)
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'thinkingdata-ruby/td_errors'
|
3
|
+
|
4
|
+
module ThinkingData
|
5
|
+
|
6
|
+
##
|
7
|
+
# Dismantle the header and save it under another name
|
8
|
+
class HeadlessLogger < Logger
|
9
|
+
def initialize(logdev, shift_age = 0, shift_size = 1048576)
|
10
|
+
super(nil)
|
11
|
+
if logdev
|
12
|
+
@logdev = HeadlessLogger::LogDevice.new(logdev, shift_age: shift_age, shift_size: shift_size)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class LogDevice < ::Logger::LogDevice
|
17
|
+
def add_log_header(file); end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Write data to file, it works with LogBus
|
23
|
+
class TDLoggerConsumer
|
24
|
+
|
25
|
+
##
|
26
|
+
# Init logger consumer
|
27
|
+
# @param log_path: log file's path
|
28
|
+
# @param mode: file rotate mode
|
29
|
+
# @param prefix: file prefix
|
30
|
+
def initialize(log_path='.', mode='daily', prefix:'te.log')
|
31
|
+
case mode
|
32
|
+
when 'hourly'
|
33
|
+
@suffix_mode = '%Y-%m-%d-%H'
|
34
|
+
when 'daily'
|
35
|
+
@suffix_mode = '%Y-%m-%d'
|
36
|
+
else
|
37
|
+
raise IllegalParameterError.new("#{mode} is unsupported for LoggerConsumer. Replaced it by daily or hourly")
|
38
|
+
end
|
39
|
+
|
40
|
+
raise IllegalParameterError.new("prefix couldn't be empty") if prefix.nil? || prefix.length == 0
|
41
|
+
|
42
|
+
@current_suffix = Time.now.strftime(@suffix_mode)
|
43
|
+
@log_path = log_path
|
44
|
+
@full_prefix = "#{log_path}/#{prefix}"
|
45
|
+
TDLog.info("TDLoggerConsumer init success. LogPath: #{log_path}")
|
46
|
+
_reset
|
47
|
+
end
|
48
|
+
|
49
|
+
def add(msg)
|
50
|
+
unless Time.now.strftime(@suffix_mode) == @current_suffix
|
51
|
+
@logger.close
|
52
|
+
@current_suffix = Time.now.strftime(@suffix_mode)
|
53
|
+
_reset
|
54
|
+
end
|
55
|
+
msg_json_str = msg.to_json
|
56
|
+
TDLog.info("Write data to file: #{msg_json_str}")
|
57
|
+
@logger.info(msg_json_str)
|
58
|
+
end
|
59
|
+
|
60
|
+
def close
|
61
|
+
@logger.close
|
62
|
+
TDLog.info("TDLoggerConsumer close.")
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def _reset
|
68
|
+
Dir::mkdir(@log_path) unless Dir::exist?(@log_path)
|
69
|
+
@logger = HeadlessLogger.new("#{@full_prefix}.#{@current_suffix}")
|
70
|
+
@logger.level = HeadlessLogger::INFO
|
71
|
+
@logger.formatter = proc do |severity, datetime, progname, msg|
|
72
|
+
"#{msg}\n"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
data/lib/thinkingdata-ruby.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'thinkingdata-ruby/
|
2
|
-
require 'thinkingdata-ruby/
|
3
|
-
require 'thinkingdata-ruby/
|
4
|
-
require 'thinkingdata-ruby/
|
5
|
-
require 'thinkingdata-ruby/
|
1
|
+
require 'thinkingdata-ruby/td_logger_consumer'
|
2
|
+
require 'thinkingdata-ruby/td_debug_consumer'
|
3
|
+
require 'thinkingdata-ruby/td_batch_consumer'
|
4
|
+
require 'thinkingdata-ruby/td_analytics'
|
5
|
+
require 'thinkingdata-ruby/td_errors'
|
data/thinkingdata-ruby.gemspec
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'lib/thinkingdata-ruby/
|
2
|
-
|
3
|
-
spec = Gem::Specification.new do |spec|
|
4
|
-
spec.name = 'thinkingdata-ruby'
|
5
|
-
spec.version =
|
6
|
-
spec.files = Dir.glob(`git ls-files`.split("\n"))
|
7
|
-
spec.require_paths = ['lib']
|
8
|
-
spec.summary = 'Official ThinkingData Analytics API for ruby'
|
9
|
-
spec.description = 'The official ThinkingData Analytics API for ruby'
|
10
|
-
spec.authors = [ 'ThinkingData' ]
|
11
|
-
spec.email = 'sdk@thinkingdata.cn'
|
12
|
-
spec.homepage = 'https://github.com/ThinkingDataAnalytics/ruby-sdk'
|
13
|
-
spec.license = 'Apache-2.0'
|
14
|
-
|
15
|
-
spec.required_ruby_version = '>= 2.0.0'
|
16
|
-
end
|
1
|
+
require File.join(File.dirname(__FILE__), 'lib/thinkingdata-ruby/td_version.rb')
|
2
|
+
|
3
|
+
spec = Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'thinkingdata-ruby'
|
5
|
+
spec.version = ThinkingData::VERSION
|
6
|
+
spec.files = Dir.glob(`git ls-files`.split("\n"))
|
7
|
+
spec.require_paths = ['lib']
|
8
|
+
spec.summary = 'Official ThinkingData Analytics API for ruby'
|
9
|
+
spec.description = 'The official ThinkingData Analytics API for ruby'
|
10
|
+
spec.authors = [ 'ThinkingData' ]
|
11
|
+
spec.email = 'sdk@thinkingdata.cn'
|
12
|
+
spec.homepage = 'https://github.com/ThinkingDataAnalytics/ruby-sdk'
|
13
|
+
spec.license = 'Apache-2.0'
|
14
|
+
|
15
|
+
spec.required_ruby_version = '>= 2.0.0'
|
16
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thinkingdata-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ThinkingData
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: The official ThinkingData Analytics API for ruby
|
14
14
|
email: sdk@thinkingdata.cn
|
@@ -16,24 +16,25 @@ executables: []
|
|
16
16
|
extensions: []
|
17
17
|
extra_rdoc_files: []
|
18
18
|
files:
|
19
|
+
- ".gitignore"
|
19
20
|
- CHANGELOG.md
|
20
21
|
- Gemfile
|
21
22
|
- LICENSE
|
22
23
|
- README.md
|
23
24
|
- demo/demo.rb
|
24
25
|
- lib/thinkingdata-ruby.rb
|
25
|
-
- lib/thinkingdata-ruby/
|
26
|
-
- lib/thinkingdata-ruby/
|
27
|
-
- lib/thinkingdata-ruby/
|
28
|
-
- lib/thinkingdata-ruby/
|
29
|
-
- lib/thinkingdata-ruby/
|
30
|
-
- lib/thinkingdata-ruby/
|
26
|
+
- lib/thinkingdata-ruby/td_analytics.rb
|
27
|
+
- lib/thinkingdata-ruby/td_batch_consumer.rb
|
28
|
+
- lib/thinkingdata-ruby/td_debug_consumer.rb
|
29
|
+
- lib/thinkingdata-ruby/td_errors.rb
|
30
|
+
- lib/thinkingdata-ruby/td_logger_consumer.rb
|
31
|
+
- lib/thinkingdata-ruby/td_version.rb
|
31
32
|
- thinkingdata-ruby.gemspec
|
32
33
|
homepage: https://github.com/ThinkingDataAnalytics/ruby-sdk
|
33
34
|
licenses:
|
34
35
|
- Apache-2.0
|
35
36
|
metadata: {}
|
36
|
-
post_install_message:
|
37
|
+
post_install_message:
|
37
38
|
rdoc_options: []
|
38
39
|
require_paths:
|
39
40
|
- lib
|
@@ -48,8 +49,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
49
|
- !ruby/object:Gem::Version
|
49
50
|
version: '0'
|
50
51
|
requirements: []
|
51
|
-
rubygems_version: 3.
|
52
|
-
signing_key:
|
52
|
+
rubygems_version: 3.4.6
|
53
|
+
signing_key:
|
53
54
|
specification_version: 4
|
54
55
|
summary: Official ThinkingData Analytics API for ruby
|
55
56
|
test_files: []
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'net/http'
|
3
|
-
|
4
|
-
module TDAnalytics
|
5
|
-
# DebugConsumer 逐条、同步地向服务端上报数据
|
6
|
-
# DebugConsumer 会返回详细的报错信息,建议在集成阶段先使用 DebugConsumer 调试接口
|
7
|
-
class DebugConsumer
|
8
|
-
|
9
|
-
def initialize(server_url, app_id, write_data = true)
|
10
|
-
@server_uri = URI.parse(server_url)
|
11
|
-
@server_uri.path = '/data_debug'
|
12
|
-
@app_id = app_id
|
13
|
-
@write_data = write_data
|
14
|
-
end
|
15
|
-
|
16
|
-
def add(message)
|
17
|
-
puts message.to_json
|
18
|
-
headers = {
|
19
|
-
'TA-Integration-Type'=>'Ruby',
|
20
|
-
'TA-Integration-Version'=>TDAnalytics::VERSION,
|
21
|
-
'TA-Integration-Count'=>'1',
|
22
|
-
'TA_Integration-Extra'=>'debug'
|
23
|
-
}
|
24
|
-
form_data = {"data" => message.to_json, "appid" => @app_id, "dryRun" => @write_data ? "0" : "1", "source" => "server"}
|
25
|
-
begin
|
26
|
-
response_code, response_body = request(@server_uri, form_data,headers)
|
27
|
-
rescue => e
|
28
|
-
raise ConnectionError.new("Could not connect to TA server, with error \"#{e.message}\".")
|
29
|
-
end
|
30
|
-
|
31
|
-
result = {}
|
32
|
-
if response_code.to_i == 200
|
33
|
-
begin
|
34
|
-
result = JSON.parse(response_body.to_s)
|
35
|
-
rescue JSON::JSONError
|
36
|
-
raise ServerError.new("Could not interpret TA server response: '#{response_body}'")
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
if result['errorLevel'] != 0
|
41
|
-
raise ServerError.new("Could not write to TA, server responded with #{response_code} returning: '#{response_body}'")
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def request(uri, form_data,headers)
|
46
|
-
request = Net::HTTP::Post.new(uri.request_uri,headers)
|
47
|
-
request.set_form_data(form_data)
|
48
|
-
|
49
|
-
client = Net::HTTP.new(uri.host, uri.port)
|
50
|
-
client.use_ssl = uri.scheme === 'https' ? true : false
|
51
|
-
client.open_timeout = 10
|
52
|
-
client.continue_timeout = 10
|
53
|
-
client.read_timeout = 10
|
54
|
-
client.ssl_timeout = 10
|
55
|
-
|
56
|
-
response = client.request(request)
|
57
|
-
[response.code, response.body]
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module TDAnalytics
|
2
|
-
|
3
|
-
# TD Analytics SDK 的错误
|
4
|
-
TDAnalyticsError = Class.new(StandardError)
|
5
|
-
|
6
|
-
# 参数不合法
|
7
|
-
IllegalParameterError = Class.new(TDAnalyticsError)
|
8
|
-
|
9
|
-
# 网络连接错误
|
10
|
-
ConnectionError = Class.new(TDAnalyticsError)
|
11
|
-
|
12
|
-
# 服务器返回错误
|
13
|
-
ServerError = Class.new(TDAnalyticsError)
|
14
|
-
|
15
|
-
|
16
|
-
# 默认情况下,所有异常都不会被抛出。如果希望自己处理异常,可以实现继承自 ErrorHandler 的
|
17
|
-
# 错误处理类,并在初始化 SDK 的时候作为参数传入.
|
18
|
-
# 例如:
|
19
|
-
# class MyErrorHandler < TDAnalytics::ErrorHandler
|
20
|
-
# def handle(error)
|
21
|
-
# puts error
|
22
|
-
# raise error
|
23
|
-
# end
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# my_error_handler = MyErrorHandler.new
|
27
|
-
# tracker = TDAnalytics::Tracker.new(consumer, my_error_handler)
|
28
|
-
class ErrorHandler
|
29
|
-
|
30
|
-
# Override #handle to customize error handling
|
31
|
-
def handle(error)
|
32
|
-
false
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|