oas-log-collector 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://secure.travis-ci.org/realmedia/oas-log-collector.png)]
|
2
|
-
|
1
|
+
OAS Log Collector [![Build Status](https://secure.travis-ci.org/realmedia/oas-log-collector.png)][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
|