oas-log-collector 0.1.4 → 0.1.5
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.
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.md +30 -5
- data/bin/oas-log-collector +3 -3
- data/examples/config.yml +9 -8
- data/lib/oas/log_collector.rb +1 -1
- data/lib/oas/log_collector/log_file.rb +30 -0
- data/lib/oas/log_collector/manager.rb +37 -8
- data/lib/oas/log_collector/source.rb +4 -6
- data/lib/oas/log_collector/version.rb +1 -1
- data/test/test_log_file.rb +17 -0
- data/test/test_manager.rb +20 -12
- metadata +6 -5
- data/lib/oas/log_collector/cli.rb +0 -41
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,35 @@
|
|
1
|
-
OAS Log Collector []
|
2
|
-
|
1
|
+
OAS Log Collector [][travis]
|
2
|
+
=====================
|
3
3
|
|
4
|
+
Simple Open Adstream log collector tool.
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
[travis]: http://travis-ci.org/realmedia/oas-log-collector
|
7
|
+
|
8
|
+
Requirements
|
9
|
+
-----------------
|
10
|
+
|
11
|
+
* Ruby 1.8.7, 1.9.2 or 1.9.3.
|
12
|
+
* Redis 2.0 or greater.
|
7
13
|
|
8
|
-
|
14
|
+
Installation
|
15
|
+
-----------------
|
9
16
|
|
10
17
|
gem install oas-log-collector
|
18
|
+
|
19
|
+
Usage
|
20
|
+
-----------------
|
21
|
+
|
22
|
+
Starting. There is an sample file under the `examples/` directory.
|
23
|
+
|
24
|
+
oas-log-collector -C config.yml -P /var/run/oas-log-collector.pid -l /var/log/oas-log-collector.log -d
|
25
|
+
|
26
|
+
Stopping
|
27
|
+
|
28
|
+
oas-log-collector -k -P /var/run/oas-log-collector.pid
|
29
|
+
|
30
|
+
**Important:** Make sure you have passwordless authentication to the servers were the logs are located.
|
31
|
+
|
32
|
+
Copyright
|
33
|
+
----------------
|
34
|
+
|
35
|
+
Copyright © 2012 Realmedia Latin America LLC. See [LICENSE](https://github.com/realmedia/oas-log-collector/blob/master/LICENSE) for details.
|
data/bin/oas-log-collector
CHANGED
@@ -6,7 +6,7 @@ $:.unshift(path) if File.directory?(path) && !$:.include?(path)
|
|
6
6
|
|
7
7
|
require 'dante'
|
8
8
|
require 'yaml'
|
9
|
-
require 'oas/log_collector/
|
9
|
+
require 'oas/log_collector/manager'
|
10
10
|
|
11
11
|
runner = Dante::Runner.new('oas-log-collector')
|
12
12
|
runner.description = "OAS Log Collector"
|
@@ -18,8 +18,8 @@ end
|
|
18
18
|
|
19
19
|
runner.execute do |options|
|
20
20
|
begin
|
21
|
-
|
22
|
-
|
21
|
+
manager = OAS::LogCollector::Manager.new(YAML.load_file(options[:config_file]))
|
22
|
+
manager.start!
|
23
23
|
rescue Interrupt
|
24
24
|
# shutdown
|
25
25
|
end
|
data/examples/config.yml
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# Sample configuration file for OAS Log Collector.
|
2
2
|
# oas-log-collector -C config.yml
|
3
3
|
---
|
4
|
-
:
|
5
|
-
:
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
|
11
|
-
- ['
|
4
|
+
:redis_url: 'redis://localhost:6379/0' # Redis url.
|
5
|
+
:days_to_search: 10 # Search files which were modified n*24 hs ago.
|
6
|
+
:files_to_copy: 90 # Collect at max n files per run.
|
7
|
+
:sleep_seconds: 900 # Time in seconds to wait betweetn runs.
|
8
|
+
:logs_path: '~/oas-log-collector' # Directory were the collected logs are going to be saved.
|
9
|
+
:source_logs_path: '/path/to/logs/directory' # Directory in remote servers were the logs are located.
|
10
|
+
:sources: # Array of log servers.
|
11
|
+
- ['server1', 'appuser'] # [host, user, port] - Port is optional, defaults to 22.
|
12
|
+
- ['server2', 'appuser']
|
data/lib/oas/log_collector.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module OAS
|
2
|
+
module LogCollector
|
3
|
+
class LogFile
|
4
|
+
|
5
|
+
attr_reader :name, :time
|
6
|
+
|
7
|
+
def initialize(file_path)
|
8
|
+
@name = File.basename(file_path)
|
9
|
+
@time = Time.at(name[/.*\.log\.([0-9]+)\.?(.+)?$/, 1].to_i)
|
10
|
+
end
|
11
|
+
|
12
|
+
def timestamp
|
13
|
+
@time.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
def year
|
17
|
+
@time.strftime("%Y")
|
18
|
+
end
|
19
|
+
|
20
|
+
def month
|
21
|
+
@time.strftime("%m")
|
22
|
+
end
|
23
|
+
|
24
|
+
def day
|
25
|
+
@time.strftime("%d")
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,30 +1,59 @@
|
|
1
|
+
require 'oas/log_collector'
|
2
|
+
require 'oas/log_collector/log_file'
|
3
|
+
require 'oas/log_collector/source'
|
4
|
+
|
1
5
|
module OAS
|
2
6
|
module LogCollector
|
3
7
|
class Manager
|
4
8
|
|
9
|
+
def initialize(opts = {})
|
10
|
+
sources = opts.delete(:sources) || []
|
11
|
+
sources.each { |host, user, port| (opts[:sources] ||= []) << OAS::LogCollector::Source.new(host, user, port || 22) }
|
12
|
+
|
13
|
+
options.merge!(opts)
|
14
|
+
end
|
15
|
+
|
16
|
+
def start!
|
17
|
+
loop do
|
18
|
+
threads = []
|
19
|
+
options[:sources].each do |source|
|
20
|
+
threads << Thread.new do
|
21
|
+
collect(source)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
threads.each(&:join)
|
25
|
+
|
26
|
+
sleep options[:sleep_seconds]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def options
|
31
|
+
OAS::LogCollector.options
|
32
|
+
end
|
33
|
+
|
5
34
|
def collect(source)
|
6
35
|
hostname = source.host
|
7
36
|
|
8
|
-
result = source.find(
|
9
|
-
:mtime => "-#{
|
37
|
+
result = source.find(options[:source_logs_path], {
|
38
|
+
:mtime => "-#{options[:days_to_search]}",
|
10
39
|
:type => 'f',
|
11
40
|
:regex => '.*\.log\.[0-9]+\.bz2'
|
12
41
|
})
|
13
42
|
|
14
|
-
files =
|
43
|
+
files = Hash.new
|
15
44
|
total = 0
|
16
45
|
last_timestamp = last_run = get_last_run(hostname)
|
17
46
|
result.sort!.each do |path|
|
18
|
-
|
19
|
-
if timestamp > Integer(last_run) && total <
|
20
|
-
files
|
47
|
+
log_file = OAS::LogCollector::LogFile.new(path)
|
48
|
+
if log_file.timestamp > Integer(last_run) && total < options[:files_to_copy]
|
49
|
+
files[path] = File.join(options[:logs_path], hostname, log_file.year, log_file.month, log_file.day, log_file.name)
|
50
|
+
last_timestamp = log_file.timestamp
|
21
51
|
total += 1
|
22
|
-
last_timestamp = timestamp
|
23
52
|
end
|
24
53
|
end
|
25
54
|
|
26
55
|
if files.any?
|
27
|
-
source.
|
56
|
+
source.download(files)
|
28
57
|
set_last_run(hostname, last_timestamp)
|
29
58
|
end
|
30
59
|
end
|
@@ -24,13 +24,11 @@ module OAS
|
|
24
24
|
out.split("\n")
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
dest_path = File.join(logs_path, host)
|
29
|
-
FileUtils.mkdir_p(dest_path)
|
30
|
-
|
27
|
+
def download(files)
|
31
28
|
Net::SCP.start(host, user, :port => port) do |scp|
|
32
|
-
files.each do |
|
33
|
-
|
29
|
+
files.each do |remote_path, dest_path|
|
30
|
+
FileUtils.mkdir_p(File.dirname(dest_path))
|
31
|
+
scp.download!(remote_path, dest_path)
|
34
32
|
end
|
35
33
|
end
|
36
34
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'oas/log_collector/log_file'
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
class TestLogFile < MiniTest::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@timestamp = DateTime.new(2012,8,1,15,30).to_time.to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_parse_on_initialize
|
11
|
+
logfile = OAS::LogCollector::LogFile.new("adstream.log.#{@timestamp}.bz2")
|
12
|
+
assert_equal @timestamp, logfile.timestamp
|
13
|
+
assert_equal "2012", logfile.year
|
14
|
+
assert_equal "08", logfile.month
|
15
|
+
assert_equal "01", logfile.day
|
16
|
+
end
|
17
|
+
end
|
data/test/test_manager.rb
CHANGED
@@ -3,16 +3,17 @@ require 'oas/log_collector/manager'
|
|
3
3
|
|
4
4
|
class TestManager < MiniTest::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
|
6
|
+
@timestamp = DateTime.new(2012,8,1,15,30).to_time.to_i
|
7
|
+
@hostname = 'remote1'
|
8
|
+
@result = ["adstream.log.#{@timestamp}.bz2", "adstream.log.#{@timestamp + 60}.bz2", "adstream.log.#{@timestamp + 120}.bz2"]
|
9
|
+
@manager = OAS::LogCollector::Manager.new({
|
7
10
|
:source_logs_path => "/tmp",
|
8
11
|
:files_to_copy => 90,
|
9
12
|
:days_to_search => 10,
|
10
13
|
:logs_path => "/tmp/logs"
|
11
14
|
})
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@source = Minitest::Mock.new
|
15
|
-
@source.expect :host, 'localhost'
|
15
|
+
@source = Minitest::Mock.new
|
16
|
+
@source.expect :host, @hostname
|
16
17
|
@source.expect :find, @result, ["/tmp", { :mtime => '-10', :type => 'f', :regex => '.*\.log\.[0-9]+\.bz2' }]
|
17
18
|
|
18
19
|
OAS::LogCollector.redis = REDIS
|
@@ -20,29 +21,36 @@ class TestManager < MiniTest::Unit::TestCase
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def test_set_last_run_to_the_last_downloaded_file
|
23
|
-
|
24
|
+
files = Hash.new
|
25
|
+
@result.each { |p| files[p] = build_destination_path(p) }
|
26
|
+
@source.expect :download, nil, [files]
|
24
27
|
@manager.collect(@source)
|
25
28
|
@source.verify
|
26
|
-
assert_equal
|
29
|
+
assert_equal @timestamp + 120, @manager.get_last_run(@hostname).to_i
|
27
30
|
end
|
28
31
|
|
29
32
|
def test_do_not_select_more_files_than_allowed
|
30
|
-
@manager.set_last_run(
|
33
|
+
@manager.set_last_run(@hostname, @timestamp)
|
31
34
|
|
32
35
|
OAS::LogCollector.options.merge!({
|
33
36
|
:files_to_copy => 1,
|
34
37
|
})
|
35
|
-
|
36
|
-
@source.expect :
|
38
|
+
path = "adstream.log.#{@timestamp + 60}.bz2"
|
39
|
+
@source.expect :download, nil, [Hash[path, build_destination_path(path)]]
|
37
40
|
@manager.collect(@source)
|
38
41
|
@source.verify
|
39
42
|
end
|
40
43
|
|
41
44
|
def test_select_files_with_timestamp_greater_than_last_run
|
42
|
-
@manager.set_last_run(
|
45
|
+
@manager.set_last_run(@hostname, @timestamp + 60)
|
43
46
|
|
44
|
-
|
47
|
+
path = "adstream.log.#{@timestamp + 120}.bz2"
|
48
|
+
@source.expect :download, nil, [Hash[path, build_destination_path(path)]]
|
45
49
|
@manager.collect(@source)
|
46
50
|
@source.verify
|
47
51
|
end
|
52
|
+
|
53
|
+
def build_destination_path(path)
|
54
|
+
File.join("/tmp/logs", @hostname, "2012", "08", "01", File.basename(path))
|
55
|
+
end
|
48
56
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oas-log-collector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dante
|
@@ -158,12 +158,13 @@ files:
|
|
158
158
|
- examples/config.yml
|
159
159
|
- lib/oas-log-collector.rb
|
160
160
|
- lib/oas/log_collector.rb
|
161
|
-
- lib/oas/log_collector/
|
161
|
+
- lib/oas/log_collector/log_file.rb
|
162
162
|
- lib/oas/log_collector/manager.rb
|
163
163
|
- lib/oas/log_collector/source.rb
|
164
164
|
- lib/oas/log_collector/version.rb
|
165
165
|
- oas-log-collector.gemspec
|
166
166
|
- test/helper.rb
|
167
|
+
- test/test_log_file.rb
|
167
168
|
- test/test_manager.rb
|
168
169
|
- test/test_source.rb
|
169
170
|
homepage: http://github.com/realmedia/oas-log-collector
|
@@ -180,7 +181,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
180
181
|
version: '0'
|
181
182
|
segments:
|
182
183
|
- 0
|
183
|
-
hash:
|
184
|
+
hash: -1912528220465064973
|
184
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
186
|
none: false
|
186
187
|
requirements:
|
@@ -189,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
190
|
version: '0'
|
190
191
|
segments:
|
191
192
|
- 0
|
192
|
-
hash:
|
193
|
+
hash: -1912528220465064973
|
193
194
|
requirements: []
|
194
195
|
rubyforge_project: oas-ivc
|
195
196
|
rubygems_version: 1.8.24
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'oas/log_collector'
|
2
|
-
require 'oas/log_collector/manager'
|
3
|
-
require 'oas/log_collector/source'
|
4
|
-
|
5
|
-
module OAS
|
6
|
-
module LogCollector
|
7
|
-
class CLI
|
8
|
-
attr_writer :manager
|
9
|
-
|
10
|
-
def initialize(opts = {})
|
11
|
-
sources = opts.delete(:sources) || []
|
12
|
-
sources.each { |host, user, port| (opts[:sources] ||= []) << OAS::LogCollector::Source.new(host, user, port || 22) }
|
13
|
-
|
14
|
-
options.merge!(opts)
|
15
|
-
end
|
16
|
-
|
17
|
-
def manager
|
18
|
-
@manager ||= OAS::LogCollector::Manager.new
|
19
|
-
end
|
20
|
-
|
21
|
-
def options
|
22
|
-
OAS::LogCollector.options
|
23
|
-
end
|
24
|
-
|
25
|
-
def run
|
26
|
-
loop do
|
27
|
-
threads = []
|
28
|
-
options[:sources].each do |source|
|
29
|
-
threads << Thread.new do
|
30
|
-
manager.collect(source)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
threads.each(&:join)
|
34
|
-
|
35
|
-
sleep options[:sleep_seconds]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|