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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c02a307fd4272626a3066db6f4d924767fa058dbb889477583d19db2b195b9e3
4
- data.tar.gz: e019db8cd60d9fd6625d6a16391f2bcd899c88082442d6004579b3213fc8e7e4
3
+ metadata.gz: 6859f106a23f8b6f24120c2d51905b7b09e0c9b713235319b0c71f60c105325b
4
+ data.tar.gz: 50fe28c3a55a3029473afbe70ba115d0e38aa7b17da1c3acacd3572b6e4915a9
5
5
  SHA512:
6
- metadata.gz: f990de3bab4004e223ad6f9691ec22f217f51ed711d617036fd14527ddc73a4fa353da3aae9713a95533006cb0793aba44aa9b999d57acc9369da7e590c2dc70
7
- data.tar.gz: 92787899f34fc00787ec28130b91013a8197e5ba22534a6958a0fec36c602ef5dd5a816c9f6744818cf8f9ddb941c89c2cd9b087f8efa0ed713dd39f6552d077
6
+ metadata.gz: dda99ed3e2c10d2c7b86e09e71b01f1074609829791d8cb1b8fd42daf54c173cb72d3f644b007b7592d3652e8068cfd2cc6179ff25f80909c1bec292a68462e1
7
+ data.tar.gz: 3fe885fd3bcd52ef37442d52fbbe37a6b37835d80101f0afb179ecd1b3034e50834436f45dfe6248d5d7b4b511fda4e6b6ee4bdf95d6519641008361c35ce722
@@ -1,2 +1,6 @@
1
+ **v1.0.0** (2020-06-09)
2
+ - 接收Logstash中event传递的message发送到TA中
3
+ - filebeat 日志打印支持
4
+
1
5
  **v0.1.1** (2020-04-27)
2
6
  - thinkingdata output plugin created with the logstash plugin generator
@@ -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 => 100
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
- PLUGIN_VERSION = "0.1.1"
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
- public
62
- def appid_check
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 |e|
101
+ @receive_count += events.length
102
+ events.each do |event|
79
103
  begin
80
- content = JSON.parse(e.get("message"))
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 => e.to_s)
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
- client.close
127
+ @report_thread.kill
128
+ @client.close
129
+ report
93
130
  end
94
131
 
95
132
  public
96
- def flush(events, final = false)
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
- response = client.post(@url, :body => data,:headers =>headers).call
112
- result = JSON.parse(response.body)
113
- if response.code != 200
114
- @logger.warn("Send failed, code: #{response.code}, body: #{response.body}")
115
- raise
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
- if result['code'] != 0
118
- @logger.error(" Send failed data:" , :failData => events.to_json,:responseBody => response.body)
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.1.1'
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 = ['xuzz']
9
- s.email = 'xuzz@thinkingdata.cn'
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.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - xuzz
7
+ - sdk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-27 00:00:00.000000000 Z
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: xuzz@thinkingdata.cn
126
+ email: sdk@thinkingdata.cn
127
127
  executables: []
128
128
  extensions: []
129
129
  extra_rdoc_files: []