logfile_transfer 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c191ef37074b871c1e90c5fc651d0555b71ef665
4
+ data.tar.gz: 8dbe070c309ce9a13ce0df2d39ae1005083db6df
5
+ SHA512:
6
+ metadata.gz: 3bc2789385bea67f06efb976e4b2a57ecbe726e2592189dc78245d0363cb3d6a17bce5ff4da617e347af2d65e7bbe853c874529ae108534aea77979df13ef265
7
+ data.tar.gz: 777ccf8d2e186c46202e8fab4d1a1aa7e7824670e9c1804501c40a4d71a3090a065f23e2e131c6fd5e34c8e3534b406183de24f735b897b0e4bf9e0ba9e0ee2f
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ logfile transfer
2
+ ================
3
+
4
+ Ruby monitoring and transform logfiles daemon.
5
+
data/config.yaml ADDED
@@ -0,0 +1,26 @@
1
+ ---
2
+ - !ruby/object:LogfileTransfer::FileMonitorObj
3
+ absolute_path: /data/webroot/log
4
+ dir_disallow: []
5
+ file_disallow:
6
+ - .*
7
+ file_allow:
8
+ - \.log\.
9
+ patterns:
10
+ - - gamestart
11
+ - - !ruby/object:Test {}
12
+ - !ruby/object:Test1 {}
13
+ - - gameexit
14
+ - - !ruby/object:Test {}
15
+ - !ruby/object:Test1 {}
16
+ - !ruby/object:LogfileTransfer::FileMonitorObj
17
+ absolute_path: /data/webroot/tlog
18
+ dir_disallow: []
19
+ file_disallow:
20
+ - .*
21
+ file_allow:
22
+ - \.log\.
23
+ patterns:
24
+ - - gamestart
25
+ - - !ruby/object:Test {}
26
+ - !ruby/object:Test1 {}
data/example.rb ADDED
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ lib_dir = File.join File.dirname(__FILE__), 'lib'
4
+ $:.unshift lib_dir unless $:.include? lib_dir
5
+
6
+ require 'scribe'
7
+ require 'logfile_transfer.rb'
8
+
9
+ class Test < LogfileTransfer::Handler
10
+ def init
11
+ end
12
+ def handle log_path, log_fn, line, line_count, pattern
13
+ if (line_count % 2) == 0
14
+ puts '+++++++++++++++++++'
15
+ else
16
+ puts '-------------------'
17
+ end
18
+ puts "#{log_path}, #{log_fn}, #{line_count}, #{pattern}"
19
+ end
20
+ end
21
+
22
+ class Test1 < LogfileTransfer::Handler
23
+ def init
24
+ @scribe_client = Scribe.new('127.0.0.1:1463')
25
+ end
26
+ def handle log_path, log_fn, line, line_count, pattern
27
+ @scribe_client.log(line, pattern)
28
+ end
29
+ end
30
+
31
+ LogfileTransfer.run ARGV, 2001, File.expand_path(File.dirname(__FILE__))
@@ -0,0 +1,310 @@
1
+ # encoding: utf-8
2
+
3
+ require 'file-monitor'
4
+ require 'socket'
5
+ require 'yaml'
6
+
7
+ module LogfileTransfer
8
+ Stop_cmd_file_name = '.sync_cmd_stop'
9
+ Prompt_cmdline = 'ruby your.rb start [config.yaml]|stop|status'
10
+ Prompt_running = 'daemon is running.'
11
+ Prompt_exiting = 'daemon is exiting.'
12
+ Prompt_starting = 'daemon is starting.'
13
+ Prompt_no_running = 'daemon no running.'
14
+
15
+ @hostname = 'localhost'
16
+ @port = 2001
17
+ @files = {}
18
+ @threads = []
19
+ @daemon_log_file_name = 'daemon.log'
20
+
21
+ class Handler
22
+ def init
23
+ raise NotImplementedError.new("#{self.class.name}#init is abstract method.")
24
+ end
25
+ def handle
26
+ raise NotImplementedError.new("#{self.class.name}#handle is abstract method.")
27
+ end
28
+ end
29
+
30
+ class FileMonitorObj
31
+ attr_accessor :absolute_path, :dir_disallow, :file_disallow, :file_allow, :patterns
32
+ def initialize
33
+ @absolute_path = ''
34
+ @dir_disallow = []
35
+ @file_disallow = []
36
+ @file_allow = []
37
+ @patterns = []
38
+ end
39
+ end
40
+
41
+ def self.log msg
42
+ @daemon_log_file.puts msg
43
+ end
44
+
45
+ def self.daemonize_app working_directory
46
+ if RUBY_VERSION < "1.9"
47
+ exit if fork
48
+ Process.setsid
49
+ exit if fork
50
+ Dir.chdir working_directory
51
+ STDIN.reopen "/dev/null"
52
+ STDOUT.reopen "/dev/null", "a"
53
+ STDERR.reopen "/dev/null", "a"
54
+ else
55
+ Process.daemon
56
+ end
57
+ end
58
+
59
+ def self.conn cmd
60
+ s = TCPSocket.open(@hostname, @port)
61
+ s.puts cmd
62
+
63
+ while line = s.gets
64
+ puts line.chop
65
+ end
66
+
67
+ true
68
+ rescue =>e
69
+ # puts "#{e}"
70
+ false
71
+ ensure
72
+ s.close unless s==nil
73
+ end
74
+
75
+ def self.close_files curr_time = 0
76
+ if curr_time == 0
77
+ # puts 'close all of files'
78
+ @files.each do |log_file_name, log_files|
79
+ log_files[0].close
80
+ log_files[1].close
81
+ end
82
+ # puts 'empty file map'
83
+ @files = {}
84
+ @daemon_log_file.close
85
+ else
86
+ @files.each do |k, v|
87
+ if (curr_time - v[2]) > 86400000
88
+ puts "close #{k}"
89
+ v[0].close
90
+ v[1].close
91
+ @files[k] = []
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ def self.transfer log_file_name, obj
98
+ for pattern, handlers in obj.patterns
99
+ if log_file_name =~ /#{pattern}/
100
+ index = log_file_name.rindex('/')
101
+ index += 1
102
+ log_path = log_file_name[0, index]
103
+ log_fn = log_file_name[index..log_file_name.length]
104
+
105
+ loc_path = "#{log_path}.loc"
106
+ loc_file_name = "#{loc_path}/#{log_fn}"
107
+
108
+ log_file, loc_file, open_time, line_count = @files[log_file_name]
109
+
110
+ unless log_file
111
+ Dir.mkdir loc_path unless File.exist? loc_path
112
+
113
+ if File.exist? loc_file_name
114
+ loc_file = File.new(loc_file_name, 'r+')
115
+ else
116
+ loc_file = File.new(loc_file_name, 'w+')
117
+ end
118
+ loc_file.sync = true
119
+ line_count = 0
120
+ log_file = File.new(log_file_name, 'r')
121
+ open_time = Time.now.to_i
122
+ close_files open_time
123
+ end
124
+
125
+ while line = log_file.gets
126
+ line_count += 1
127
+ loc = loc_file.gets
128
+ if loc
129
+ next
130
+ end
131
+
132
+ fail = false
133
+ fail_handlers = []
134
+
135
+ handlers.each do |handler|
136
+ begin
137
+ handler.handle log_path, log_fn, line.chop, line_count, pattern
138
+ rescue => err
139
+ log "#{log_file_name}, #{line_count}, #{err}"
140
+ fail_handlers << handler.class
141
+ fail = true
142
+ end
143
+ end
144
+
145
+ if fail
146
+ loc_file.puts "#{line_count}, #{fail_handlers}"
147
+ else
148
+ loc_file.puts "#{line_count}"
149
+ end
150
+
151
+ end
152
+ @files[log_file_name] = [log_file, loc_file, open_time, line_count]
153
+ break
154
+ end
155
+ end
156
+ end
157
+
158
+ def self.daemon
159
+ YAML.load_file(@config_file_name).each do |obj|
160
+ log "absolute path: #{obj.absolute_path}"
161
+ log "dir disallow: #{obj.dir_disallow}"
162
+ log "file disallow: #{obj.file_disallow}"
163
+ log "file allow: #{obj.file_allow}"
164
+ obj.patterns.each do |pattern, handlers|
165
+ log "pattern: #{pattern}"
166
+ handlers.each do |handler|
167
+ handler.init
168
+ log "- -#{handler.class} initialized."
169
+ end
170
+ end
171
+
172
+ @threads << Thread.new do
173
+ begin
174
+ m = FileMonitor.new(obj.absolute_path)
175
+
176
+ m.filter_dirs do
177
+ obj.dir_disallow.each do |dir|
178
+ disallow /#{dir}/
179
+ end
180
+ disallow /loc$/
181
+ end
182
+
183
+ m.filter_files do
184
+ obj.file_disallow.each do |file|
185
+ disallow /#{file}/
186
+ end
187
+ obj.file_allow.each do |file|
188
+ allow /#{file}/
189
+ end
190
+ allow /#{Stop_cmd_file_name}$/
191
+ end
192
+
193
+ m.run do |events|
194
+ break if @exit_flag
195
+ events.each do |event|
196
+ flags = event.flags
197
+ if flags.include?(:modify) or flags.include?(:moved_to) or flags.include?(:create)
198
+ transfer event.absolute_name, obj
199
+ end
200
+ end
201
+ end
202
+
203
+ log "#{obj.absolute_path} file monitor thread exit."
204
+ rescue =>err
205
+ # puts err
206
+ log err
207
+ end
208
+ end
209
+ end
210
+
211
+ @threads << Thread.new do
212
+ server = TCPServer.open(@hostname, @port)
213
+
214
+ loop do
215
+ client = server.accept
216
+
217
+ cmd = client.gets
218
+
219
+ case cmd.chop
220
+ when 'stop'
221
+ client.puts(Prompt_exiting)
222
+ @exit_flag = true;
223
+
224
+ YAML.load_file(@config_file_name).each do |obj|
225
+ system "touch #{obj.absolute_path}/#{Stop_cmd_file_name}"
226
+ end
227
+
228
+ sleep 1
229
+
230
+ YAML.load_file(@config_file_name).each do |obj|
231
+ system "unlink #{obj.absolute_path}/#{Stop_cmd_file_name}"
232
+ end
233
+
234
+ # puts 'client.close'
235
+ client.close
236
+
237
+ break;
238
+ when 'status'
239
+ close_files Time.now.to_i
240
+ client.puts(Prompt_running)
241
+ client.puts(@config_file_title)
242
+ @files.each do |log_file_name, log_files|
243
+ client.puts "log file: #{log_file_name}, loc file: #{log_files[1].path}, open time: #{Time.at(log_files[2])}, lines: #{log_files[3]}"
244
+ end
245
+ end
246
+
247
+ # puts 'client.close'
248
+ client.close
249
+ end
250
+
251
+ close_files
252
+ # @files.each do |k, v|
253
+ # puts "#{k}: #{v}"
254
+ # end
255
+ unless server == nil
256
+ # puts 'server.close'
257
+ server.close
258
+ end
259
+ end
260
+
261
+ @threads.each { |t| t.join }
262
+ end
263
+
264
+ def self.run argv, port, working_directory
265
+ @port = port
266
+
267
+ if argv.length < 1
268
+ puts Prompt_cmdline
269
+ exit
270
+ end
271
+
272
+ cmd = argv[0]
273
+ # puts "cmd: #{cmd}"
274
+
275
+ @exit_flag = false;
276
+
277
+ case cmd
278
+ when 'start'
279
+ if argv.length < 2
280
+ @config_file_name = "#{working_directory}/config.yaml"
281
+ elsif argv[1][0] == '/'
282
+ @config_file_name = argv[1]
283
+ else
284
+ @config_file_name = "#{working_directory}/#{argv[1]}"
285
+ end
286
+
287
+ @config_file_title = "config file: #{@config_file_name}"
288
+
289
+ unless File.exist? @config_file_name
290
+ puts "#{@config_file_title} no exist!"
291
+ exit
292
+ end
293
+
294
+ exit if conn 'status'
295
+
296
+ puts Prompt_starting
297
+
298
+ daemonize_app working_directory
299
+ @daemon_log_file_name = "#{working_directory}/#{@daemon_log_file_name}"
300
+ @daemon_log_file = File.new @daemon_log_file_name, 'a'
301
+ @daemon_log_file.sync = true
302
+ log "-------------#{Time.now}-----------------"
303
+ daemon
304
+ when /stop|status/
305
+ puts Prompt_no_running unless conn cmd
306
+ else
307
+ puts Prompt_cmdline
308
+ end
309
+ end
310
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logfile_transfer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Cong Yan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-10 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby monitoring and transform logfiles daemon.
14
+ email: xiaoyaoyouzizai@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/logfile_transfer.rb
20
+ - example.rb
21
+ - config.yaml
22
+ - README.md
23
+ homepage: https://github.com/xiaoyaoyouzizai/logfile_transfer
24
+ licenses:
25
+ - Apache License, Version 2.0
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.1.4
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: logfile transfer
47
+ test_files: []