logstash-output-thinkingdata 0.1.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/logstash/outputs/thinkingdata.rb +115 -21
- data/logstash-output-thinkingdata.gemspec +3 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6859f106a23f8b6f24120c2d51905b7b09e0c9b713235319b0c71f60c105325b
|
4
|
+
data.tar.gz: 50fe28c3a55a3029473afbe70ba115d0e38aa7b17da1c3acacd3572b6e4915a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dda99ed3e2c10d2c7b86e09e71b01f1074609829791d8cb1b8fd42daf54c173cb72d3f644b007b7592d3652e8068cfd2cc6179ff25f80909c1bec292a68462e1
|
7
|
+
data.tar.gz: 3fe885fd3bcd52ef37442d52fbbe37a6b37835d80101f0afb179ecd1b3034e50834436f45dfe6248d5d7b4b511fda4e6b6ee4bdf95d6519641008361c35ce722
|
data/CHANGELOG.md
CHANGED
@@ -28,12 +28,22 @@ class LogStash::Outputs::Thinkingdata < LogStash::Outputs::Base
|
|
28
28
|
config :flush_interval_sec, :validate => :number, :default => 2
|
29
29
|
|
30
30
|
# 批次flush 最大 content 数量
|
31
|
-
config :flush_batch_size, :validate => :number, :default =>
|
31
|
+
config :flush_batch_size, :validate => :number, :default => 500
|
32
32
|
|
33
33
|
# 是否压缩数据 0:不压缩,1:gzip压缩
|
34
34
|
config :compress, :validate => :number, :default => 1
|
35
35
|
|
36
|
-
|
36
|
+
#是否开启uuid
|
37
|
+
config :uuid, :validate => :boolean, :default => false
|
38
|
+
|
39
|
+
|
40
|
+
# 开启 filebeat 状态记录
|
41
|
+
config :is_filebeat_status_record, :validate => :boolean, :default => true
|
42
|
+
|
43
|
+
# 是否检测appid
|
44
|
+
config :appid_check, :validate => :boolean, :default => false
|
45
|
+
|
46
|
+
PLUGIN_VERSION = "1.0.0"
|
37
47
|
|
38
48
|
public
|
39
49
|
def register
|
@@ -42,24 +52,38 @@ class LogStash::Outputs::Thinkingdata < LogStash::Outputs::Base
|
|
42
52
|
:appid => @appid,
|
43
53
|
:flush_interval_sec => @flush_interval_sec,
|
44
54
|
:flush_batch_size => @flush_batch_size,
|
45
|
-
:compress =>@compress
|
55
|
+
:compress =>@compress,
|
56
|
+
:uuid => @uuid,
|
57
|
+
:is_filebeat_status_record => @is_filebeat_status_record,
|
58
|
+
:appid_check => @appid_check
|
46
59
|
)
|
47
60
|
|
48
61
|
http_client_config = client_config
|
49
62
|
http_client_config[:user_agent] = "thinkingdata_logstash_output_plugin_" + PLUGIN_VERSION
|
50
63
|
@client = Manticore::Client.new(http_client_config)
|
51
|
-
appid_check
|
64
|
+
ta_appid_check if @appid_check
|
65
|
+
@receive_count = 0
|
66
|
+
@parse_error_count = 0
|
67
|
+
@last_report_count = 0
|
68
|
+
@total_send_count = 0
|
52
69
|
buffer_config = {
|
53
70
|
:max_items => @flush_batch_size.to_i,
|
54
71
|
:max_interval => @flush_interval_sec.to_i,
|
55
72
|
:logger => @logger
|
56
73
|
}
|
57
74
|
buffer_initialize(buffer_config)
|
75
|
+
@filebeat_status = {} if @is_filebeat_status_record
|
76
|
+
@report_thread = Thread.new do
|
77
|
+
loop do
|
78
|
+
sleep 60
|
79
|
+
report
|
80
|
+
end
|
81
|
+
end
|
58
82
|
end # def register
|
59
83
|
|
60
84
|
#验证appid
|
61
|
-
|
62
|
-
def
|
85
|
+
private
|
86
|
+
def ta_appid_check
|
63
87
|
@server_uri = URI(@url)
|
64
88
|
@server_uri.path = "/check_appid"
|
65
89
|
@server_uri.query= "appid="+@appid
|
@@ -74,26 +98,39 @@ class LogStash::Outputs::Thinkingdata < LogStash::Outputs::Base
|
|
74
98
|
public
|
75
99
|
def multi_receive(events)
|
76
100
|
return if events.empty?
|
77
|
-
|
78
|
-
events.each do |
|
101
|
+
@receive_count += events.length
|
102
|
+
events.each do |event|
|
79
103
|
begin
|
80
|
-
content =
|
104
|
+
content = LogStash::Json.load(event.get("message"))
|
105
|
+
content['#uuid'] = SecureRandom.uuid if @uuid
|
106
|
+
if is_filebeat_input?(event) #filebeat input 记录
|
107
|
+
host = event.get("[host][name]")
|
108
|
+
file = event.get("[log][file][path]")
|
109
|
+
file = event.get("[source]")if file.nil?
|
110
|
+
offset = event.get("[log][offset]")
|
111
|
+
offset = event.get("[offset]") if offset.nil?
|
112
|
+
log_detail = "host: #{host}, file: #{file}"
|
113
|
+
record_filebeat_status(log_detail, offset) if @is_filebeat_status_record
|
114
|
+
end
|
81
115
|
buffer_receive(content)
|
82
|
-
rescue
|
83
|
-
@logger.error("Could not process content", :content =>
|
116
|
+
rescue => e
|
117
|
+
@logger.error("Could not process content", :content => event.to_s, :Exception => e)
|
118
|
+
@parse_error_count += 1
|
84
119
|
end
|
85
120
|
end
|
86
|
-
# return "Event received"
|
87
121
|
end # def event
|
88
122
|
|
89
123
|
public
|
90
124
|
def close
|
125
|
+
buffer_state[:timer].kill
|
91
126
|
buffer_flush(:final => true)
|
92
|
-
|
127
|
+
@report_thread.kill
|
128
|
+
@client.close
|
129
|
+
report
|
93
130
|
end
|
94
131
|
|
95
132
|
public
|
96
|
-
def flush(events, final
|
133
|
+
def flush(events, final)
|
97
134
|
if @compress == 0
|
98
135
|
data = events.to_json
|
99
136
|
compress_type = 'none'
|
@@ -108,14 +145,71 @@ class LogStash::Outputs::Thinkingdata < LogStash::Outputs::Base
|
|
108
145
|
end
|
109
146
|
headers ={'appid' => @appid,'version'=>PLUGIN_VERSION,'user-agent' =>'logstash_'+ PLUGIN_VERSION,
|
110
147
|
'compress' => compress_type}
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
148
|
+
until do_send(data,headers)
|
149
|
+
sleep 5
|
150
|
+
end
|
151
|
+
@total_send_count += events.length
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
def do_send(data, headers)
|
156
|
+
begin
|
157
|
+
response = @client.post(@url, :body => data,:headers =>headers).call
|
158
|
+
if response.code != 200
|
159
|
+
@logger.error("Send failed, code: #{response.code}, body: #{response.body}",:url => @url)
|
160
|
+
return false
|
161
|
+
end
|
162
|
+
rescue => e
|
163
|
+
@logger.error("Send failed",:url => @url, :exception => e.class.name, :backtrace => e.backtrace)
|
164
|
+
return false
|
116
165
|
end
|
117
|
-
|
118
|
-
|
166
|
+
true
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
def is_filebeat_input?(event)
|
171
|
+
type = event.get("[agent][type]")
|
172
|
+
return true if !type.nil? && type == "filebeat"
|
173
|
+
type = event.get("[@metadata][beat]")
|
174
|
+
return true if !type.nil? && type == "filebeat"
|
175
|
+
type = event.get("[beat]")
|
176
|
+
return true unless type.nil?
|
177
|
+
false
|
178
|
+
end
|
179
|
+
|
180
|
+
private
|
181
|
+
def record_filebeat_status(log_detail, offset)
|
182
|
+
status = @filebeat_status[log_detail]
|
183
|
+
if status.nil?
|
184
|
+
status = {:receive_time => Time.now, :offset => offset}
|
185
|
+
@filebeat_status[log_detail] = status
|
186
|
+
else
|
187
|
+
status[:offset] = offset
|
188
|
+
status[:receive_time] = Time.now
|
119
189
|
end
|
120
190
|
end
|
191
|
+
|
192
|
+
private
|
193
|
+
def report
|
194
|
+
interval_count = @total_send_count - @last_report_count
|
195
|
+
@last_report_count = @total_send_count
|
196
|
+
@logger.info("Report",
|
197
|
+
"IntervalReceive(records):" => interval_count,
|
198
|
+
"Receive(records):" => @receive_count,
|
199
|
+
"TotalSend(records)" => @total_send_count,
|
200
|
+
"ParseError(records)" => @parse_error_count)
|
201
|
+
@logger.info("Filebeat Status Report: #{format_filebeat_report}") if @is_filebeat_status_record && @filebeat_status !={}
|
202
|
+
end
|
203
|
+
|
204
|
+
private
|
205
|
+
|
206
|
+
def format_filebeat_report
|
207
|
+
result = "\n"
|
208
|
+
@filebeat_status.each do |k, v|
|
209
|
+
result << k << "=>" << v.to_s << "\n"
|
210
|
+
end
|
211
|
+
@filebeat_status = {}
|
212
|
+
result
|
213
|
+
end
|
214
|
+
|
121
215
|
end # class LogStash::Outputs::Thinkingdata
|
@@ -1,12 +1,12 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'logstash-output-thinkingdata'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '1.0.0'
|
4
4
|
s.licenses = ['Apache-2.0']
|
5
5
|
s.summary = 'Output plugin for Thinkingdata Analytics'
|
6
6
|
s.description = 'This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program.'
|
7
7
|
s.homepage = 'https://www.thinkingdata.cn/manual/api.html'
|
8
|
-
s.authors = ['
|
9
|
-
s.email = '
|
8
|
+
s.authors = ['sdk']
|
9
|
+
s.email = 'sdk@thinkingdata.cn'
|
10
10
|
s.require_paths = ['lib']
|
11
11
|
|
12
12
|
# Files
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-thinkingdata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- sdk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logstash-core-plugin-api
|
@@ -123,7 +123,7 @@ dependencies:
|
|
123
123
|
description: This gem is a logstash plugin required to be installed on top of the
|
124
124
|
Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
|
125
125
|
gem is not a stand-alone program.
|
126
|
-
email:
|
126
|
+
email: sdk@thinkingdata.cn
|
127
127
|
executables: []
|
128
128
|
extensions: []
|
129
129
|
extra_rdoc_files: []
|