fluent-plugin-light-core 0.1.1 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c42d7ebbc40db04faa3683d2f19cc13b8faaad30f0a103dcd8284015cf41634
4
- data.tar.gz: 7b1dc8dc732a0cdc15a8e9ac124a86a9981dd8a032488b73a6d2f00dc022b229
3
+ metadata.gz: 84773035328d3e9f94b3a41242a24038c9f00bf84ff4e4c282ac67d44fa75350
4
+ data.tar.gz: 393720c2ce0fc4d55fabf7e9206ab57bf8085c0df9c5e043356cc87f356328c4
5
5
  SHA512:
6
- metadata.gz: 27d1c95d1b34923806055fc51e72f16e13af8c33d6c501aff6b2ad829c65817cfaacfce0ef687a373656738051035478cb4d06d6327666b8fa6adf872192a4d7
7
- data.tar.gz: feb76078202bf213d7692ec0cd2a7faef62ce46219e4165ded55e13e9bc3eaaaf43f8de4eb49a5407c926ee6b091bd435fa7f4ce4f1aba5f2b12bc2507c517ad
6
+ metadata.gz: eca26afd55eb797b228c2cf65653882d31718c66630041ab05243c5be3d1b85f995a8dca5c8e6cd79971cb4db5735cd2d49ccb8f0e4c9357117e90252fae81ea
7
+ data.tar.gz: 8faa457619809fe3b26db9658fdf5dc66a960477541bc9ac7342b21612eb649743ec99be49ba1584e01fb8e615cd97f94dc9be9303d01fe222ed5ac654665226
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = "fluent-plugin-light-core"
6
- spec.version = "0.1.1"
6
+ spec.version = "0.1.6"
7
7
  spec.authors = ["LIN LI"]
8
8
  spec.email = ["l.li@alphabets.cn"]
9
9
 
@@ -13,25 +13,73 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "fluent/plugin/filter"
16
+ require 'fluent/plugin/filter'
17
+ require 'socket'
18
+ require 'json'
17
19
 
18
20
  module Fluent
19
21
  module Plugin
20
22
  class LightCoreFilter < Fluent::Plugin::Filter
21
- Fluent::Plugin.register_filter("light_core", self)
23
+ Fluent::Plugin.register_filter('light_core', self)
24
+
25
+ # 通知相关配置
26
+ config_param :notice, :bool, default: false
27
+ config_param :port, :integer, default: 7000
28
+ config_param :host, :string, default: '255.255.255.255'
29
+
30
+ # Application 异常 settings
31
+ config_param :app_stream, :string, default: 'stderr'
32
+ config_param :app_message, :array, default: [], value_type: :regexp
33
+ config_param :app_status, :array, default: ['500'], value_type: :string
34
+ config_param :app_elapsed, :float, default: 2000
35
+
36
+ # Nginx 异常 settings
37
+ config_param :lb_stream, :string, default: 'stderr'
38
+ config_param :lb_code, :array, default: ['500'], value_type: :string
39
+ config_param :lb_elapsed, :float, default: 3000
40
+
41
+ # MongoDB 异常 settings
42
+ config_param :mongo_severity, :array, default: ['F', 'E'], value_type: :string
43
+ config_param :mongo_querytime, :float, default: 100
44
+
45
+ # 初始化UDP实例
46
+ def start
47
+ super
48
+
49
+ if @notice
50
+ log.info('init udp connection')
51
+ @udp = UDPSocket.open()
52
+ @udp.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1)
53
+ end
54
+ end
55
+
56
+ # 清理UDP连接
57
+ def shutdown
58
+
59
+ if @notice
60
+ log.info('close udp connection')
61
+ @udp.close if @udp
62
+ end
63
+
64
+ super
65
+ end
22
66
 
67
+ # 主处理
23
68
  def filter(tag, time, record)
24
69
 
25
- if tag == 'app'
26
- return filter_app(tag, time, record)
70
+ if ['app', 'service'].include? tag
71
+ record = filter_app(tag, time, record)
72
+ return notice('app', record)
27
73
  end
28
74
 
29
75
  if ['lb', 'hub'].include? tag
30
- return filter_lb(tag, time, record)
76
+ record = filter_lb(tag, time, record)
77
+ return notice('lb', record)
31
78
  end
32
79
 
33
80
  if ['mongo', 'secondary', 'arbiter'].include? tag
34
- return filter_mongo(tag, time, record)
81
+ record = filter_mongo(tag, time, record)
82
+ return notice('mongo', record)
35
83
  end
36
84
 
37
85
  record
@@ -45,9 +93,9 @@ module Fluent
45
93
 
46
94
  # Set common items
47
95
  record['environment'] = Socket.gethostname.split('-')[0] # dev | prd
48
- record[:cid] = file[0] # container id
49
- record[:cname] = file[0].split('-')[1] # container name
50
- record[:ctime] = record['time'] # container time
96
+ record['cid'] = file[0] # container id
97
+ record['cname'] = file[0].split('-')[1] # container name
98
+ record['ctime'] = record['time'] # container time
51
99
 
52
100
  # Delete useless content
53
101
  record.delete('log')
@@ -59,12 +107,12 @@ module Fluent
59
107
 
60
108
  item = /^\[(?<time>[^\]]*)\] \[(?<component>[^\]]*)\] \[(?<levle>[^\]]*)\] (?<line>[^\ ]*) - - (?<uid>[^\ ]*) - (?<message>.*)$/.match(log)
61
109
 
62
- record[:time] = item[:time]
63
- record[:component] = item[:component]
64
- record[:levle] = item[:levle]
65
- record[:line] = item[:line]
66
- record[:uid] = item[:uid]
67
- record[:message] = item[:message]
110
+ record['time'] = item[:time]
111
+ record['component'] = item[:component]
112
+ record['levle'] = item[:levle]
113
+ record['line'] = item[:line]
114
+ record['uid'] = item[:uid]
115
+ record['message'] = item[:message]
68
116
 
69
117
  return record
70
118
  end
@@ -74,21 +122,21 @@ module Fluent
74
122
 
75
123
  item = /^\[(?<time>[^\]]*)\] \[(?<component>[^\]]*)\] \[(?<method>[^\]]*)\] (?<url>[^\ ]*) (?<status>[^\ ]*) (?<size>[^\ ]*) (?<uid>[^\ ]*) (?<elapsed>[^\ ]*) (?<addr>[^\ ]*)$/.match(log)
76
124
 
77
- record[:time] = item[:time]
78
- record[:component] = item[:component]
79
- record[:method] = item[:method]
80
- record[:url] = item[:url]
81
- record[:status] = item[:status]
82
- record[:size] = item[:size]
83
- record[:uid] = item[:uid]
84
- record[:elapsed] = item[:elapsed]
85
- record[:addr] = item[:addr].gsub(/\n$/, '')
125
+ record['time'] = item[:time]
126
+ record['component'] = item[:component]
127
+ record['method'] = item[:method]
128
+ record['url'] = item[:url]
129
+ record['status'] = item[:status]
130
+ record['size'] = format_str(item[:size])
131
+ record['uid'] = item[:uid]
132
+ record['elapsed'] = format_str(item[:elapsed])
133
+ record['addr'] = item[:addr].gsub(/\n$/, '')
86
134
 
87
135
  return record
88
136
  end
89
137
 
90
138
  # Console log
91
- record[:message] = log.gsub(/\n$/, '')
139
+ record['message'] = log.gsub(/\n$/, '')
92
140
  record
93
141
  end
94
142
 
@@ -99,9 +147,9 @@ module Fluent
99
147
  log = record['log']
100
148
 
101
149
  record['environment'] = Socket.gethostname.split('-')[0]
102
- record[:cid] = file[0]
103
- record[:cname] = tag
104
- record[:ctime] = record['time']
150
+ record['cid'] = file[0]
151
+ record['cname'] = tag
152
+ record['ctime'] = record['time']
105
153
 
106
154
  record.delete('log')
107
155
  record.delete('file')
@@ -109,19 +157,20 @@ module Fluent
109
157
 
110
158
  # access log
111
159
  if /^[^ ]+ [^ ]+ [^ ]+ \[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2}\]/.match(log)
112
- item = /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forwarder>[^\"]*)")?/.match(log)
113
-
114
- record[:remote] = item[:remote]
115
- record[:host] = item[:host]
116
- record[:user] = item[:user]
117
- record[:time] = item[:time]
118
- record[:method] = item[:method]
119
- record[:path] = item[:path]
120
- record[:code] = item[:code]
121
- record[:size] = item[:size]
122
- record[:referer] = item[:referer]
123
- record[:agent] = item[:agent]
124
- record[:forwarder] = item[:forwarder]
160
+ item = /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forwarder>[^\"]*)" "(?<elapsed>[^\"]*)")?/.match(log)
161
+
162
+ record['remote'] = item[:remote]
163
+ record['host'] = item[:host]
164
+ record['user'] = item[:user]
165
+ record['time'] = item[:time]
166
+ record['method'] = item[:method]
167
+ record['path'] = item[:path]
168
+ record['code'] = item[:code]
169
+ record['size'] = format_str(item[:size])
170
+ record['referer'] = item[:referer]
171
+ record['agent'] = item[:agent]
172
+ record['forwarder'] = item[:forwarder]
173
+ record['elapsed'] = format_str(item[:elapsed])
125
174
 
126
175
  return record
127
176
  end
@@ -130,29 +179,29 @@ module Fluent
130
179
  if /^\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2} \[error\]/.match(log)
131
180
  item = /^(?<time>[^ ]+ [^ ]+) \[(?<level>.*)\] (?<pid>\d*)#(?<tid>[^:]*): \*(?<cid>\d*) (?<message>.*)$/.match(log)
132
181
 
133
- record[:time] = item[:time]
134
- record[:level] = item[:level]
135
- record[:message] = item[:message]
136
- record[:process] = item[:pid] # process id
137
- record[:thread] = item[:tid] # thread id
138
- record[:counter] = item[:cid] # counter
182
+ record['time'] = item[:time]
183
+ record['level'] = item[:level]
184
+ record['message'] = item[:message]
185
+ record['process'] = item[:pid] # process id
186
+ record['thread'] = item[:tid] # thread id
187
+ record['counter'] = item[:cid] # counter
139
188
 
140
189
  detail = /request: "(?<method>[^ ]*) (?<path>[^"]*)"/.match(item[:message])
141
190
  unless detail.nil?
142
- record[:method] = detail[:method]
143
- record[:path] = detail[:path]
191
+ record['method'] = detail[:method]
192
+ record['path'] = detail[:path]
144
193
  end
145
194
 
146
195
  detail = /referrer: "(?<referrer>[^"]*)"/.match(item[:message])
147
196
  unless detail.nil?
148
- record[:referrer] = detail[:referrer]
197
+ record['referrer'] = detail[:referrer]
149
198
  end
150
199
 
151
200
  return record
152
201
  end
153
202
 
154
203
  # other log
155
- record[:message] = log.gsub(/\n$/, '')
204
+ record['message'] = log.gsub(/\n$/, '')
156
205
  record
157
206
  end
158
207
 
@@ -163,9 +212,9 @@ module Fluent
163
212
  log = record['log']
164
213
 
165
214
  record['environment'] = Socket.gethostname.split('-')[0]
166
- record[:cid] = file[0]
167
- record[:cname] = tag
168
- record[:ctime] = record['time']
215
+ record['cid'] = file[0]
216
+ record['cname'] = tag
217
+ record['ctime'] = record['time']
169
218
 
170
219
  record.delete('log')
171
220
  record.delete('file')
@@ -173,26 +222,29 @@ module Fluent
173
222
 
174
223
  if /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}\+\d{4} [A-Z]/.match(log)
175
224
 
176
- item = /^(?<time>[^ ]*) (?<severity>[A-Z])\s* (?<component>(-|([^ ]*)))\s* \[(?<context>[^\]]*)\]\s* ((?<query>.*) (?<querytime>[\d\.]+(?=ms))|(?<message>.*))/.match(log)
225
+ item = /^(?<time>[^ ]*) (?<severity>[A-Z])\s* (?<component>(-|([^ ]*)))\s* \[(?<context>[^\]]*)\]\s* ((?<query>.*) protocol:op_query (?<querytime>[\d\.]+(?=ms))|(?<message>.*))/.match(log)
177
226
 
178
- record[:time] = item[:time]
179
- record[:severity] = item[:severity]
180
- record[:component] = item[:component]
181
- record[:context] = item[:context]
227
+ record['time'] = item[:time]
228
+ record['severity'] = item[:severity]
229
+ record['component'] = item[:component]
230
+ record['context'] = item[:context]
182
231
 
183
232
  if item[:message]
184
- record[:message] = item[:message]
233
+ record['message'] = item[:message]
185
234
  return record
186
235
  end
187
236
 
188
237
  if item[:querytime]
189
- record[:querytime] = item[:querytime]
238
+ record['querytime'] = format_str(item[:querytime])
190
239
  end
191
240
 
192
241
  if item[:query]
242
+ record['command'] = item[:query]
193
243
  query = /^command\s* (?<collection>[^ ]*) (?<command>.*)$/.match(item[:query])
194
- record[:collection] = query[:collection]
195
- record[:command] = query[:command]
244
+ unless query.nil?
245
+ record['collection'] = query[:collection]
246
+ record['command'] = query[:command]
247
+ end
196
248
  end
197
249
 
198
250
  return record
@@ -201,6 +253,91 @@ module Fluent
201
253
  record
202
254
  end
203
255
 
256
+ # 确认是否发送通知
257
+ def notice(tag, record)
258
+
259
+ unless @notice
260
+ return record
261
+ end
262
+
263
+ if tag == 'app'
264
+ if @app_stream && record['stream']
265
+ send(record) if record['stream'] == @app_stream
266
+ end
267
+
268
+ if @app_message.length > 0 && record['message']
269
+ @app_message.each do |pattern|
270
+ if pattern.match(record['message'])
271
+ send(record)
272
+ break
273
+ end
274
+ end
275
+ end
276
+
277
+ if @app_status.length > 0 && record['status']
278
+ send(record) if @app_status.include?(record['status'])
279
+ end
280
+
281
+ if @app_elapsed > 0 && record['elapsed']
282
+ send(record) if record['elapsed'].to_f > @app_elapsed
283
+ end
284
+
285
+ return record
286
+ end
287
+
288
+ if tag == 'lb'
289
+ if @lb_stream && record['stream']
290
+ send(record) if record['stream'] == @lb_stream
291
+ end
292
+
293
+ if @lb_code.length > 0 && record['code']
294
+ send(record) if @lb_code.include?(record['code'])
295
+ end
296
+
297
+ if @lb_elapsed > 0 && record['elapsed']
298
+ send(record) if record['elapsed'].to_f > @lb_elapsed
299
+ end
300
+
301
+ return record
302
+ end
303
+
304
+ if tag == 'mongo'
305
+ if @mongo_severity.length > 0 && record['severity']
306
+ send(record) if @mongo_severity.include?(record['severity'])
307
+ end
308
+
309
+ if @mongo_querytime > 0 && record['querytime']
310
+ send(record) if record['querytime'].to_f > @mongo_querytime
311
+ end
312
+
313
+ return record
314
+ end
315
+
316
+ record
317
+
318
+ end
319
+
320
+ # 发送UDP请求
321
+ def send(record)
322
+
323
+ log.info('send udp notice', record)
324
+
325
+ data = {
326
+ :query => '/api/log/notice',
327
+ :params => {
328
+ :data => record
329
+ }
330
+ }
331
+ @udp.send(data.to_json, 0, Socket.pack_sockaddr_in(@port, @host))
332
+ end
333
+
334
+ # 转数字
335
+ def format_str(str)
336
+ return str.to_i if (str =~ /^\d+$/)
337
+ return str.to_f if (str =~ /^\d+\.\d+$/)
338
+ str
339
+ end
340
+
204
341
  end
205
342
  end
206
343
  end
@@ -21,12 +21,14 @@ Initialized empty Git repository in /Users/lilin/developer/light/fluent-plugin-l
21
21
  % gem signin
22
22
 
23
23
  - 发布
24
- rake release
24
+ 1. 删除pkg目录下的所有内容
25
+ 2. 修改 fluent-plugin-light-core.gemspec 中的 spec.version
26
+ 3. 提交所有的修改
27
+ 4. 执行打包发布 $ rake release
25
28
 
26
29
 
27
30
  ## 调试
28
31
  - 执行fluentd
29
32
 
30
- % cd sample
31
- % fluentd -c source.conf -p ../lib/fluent/plugin
32
-
33
+ % rm -f sample/*.pos
34
+ % fluentd -c sample/source.conf -p lib/fluent/plugin
@@ -0,0 +1,20 @@
1
+
2
+ require 'socket'
3
+ require 'json'
4
+
5
+ udp = UDPSocket.open()
6
+ udp.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1)
7
+ udp_addr = Socket.pack_sockaddr_in(7000, '255.255.255.255')
8
+
9
+ data = {
10
+ :query => '/api/log/notice',
11
+ :params => {
12
+ :data => {:A => 'A'}
13
+ }
14
+ }
15
+
16
+ params = data.to_json
17
+ params = "{\"query\":\"/api/log/notice\",\"params\":{\"data\":{\"stream\":\"stdout\",\"environment\":\"Mac\",\"cid\":\"app-0c1b728705d8-f5fc78bc8-8rjfl\",\"cname\":\"0c1b728705d8\",\"ctime\":\"2020-09-20T06:00:53.516987008Z\",\"time\":\"2020-09-20T06:00:53.516\",\"component\":\"I\",\"method\":\"GET\",\"url\":\"/api/app/last?id=xundianxb&os=android\",\"status\":\"200\",\"size\":\"349\",\"uid\":\"-\",\"elapsed\":\"76.078\",\"addr\":\"::ffff:10.244.4.86\"}}}"
18
+ udp.send(params, 0, udp_addr)
19
+
20
+ udp.close
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-light-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - LIN LI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-23 00:00:00.000000000 Z
11
+ date: 2021-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -89,6 +89,7 @@ files:
89
89
  - lib/fluent/plugin/filter_light_core.rb
90
90
  - sample/README.md
91
91
  - sample/source.conf
92
+ - sample/udpsample.rb
92
93
  - test/helper.rb
93
94
  - test/plugin/test_filter_light_core.rb
94
95
  homepage: https://git.alphabets.cn/light/fluent-plugin-light-core