remote_syslog 1.0.0 → 1.1.0

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 CHANGED
@@ -1,3 +1,3 @@
1
- gem 'daemons'
2
- gem 'eventmachine'
3
- gem 'eventmachine-tail'
1
+ source :rubygems
2
+
3
+ gemspec
data/README.md CHANGED
@@ -46,21 +46,26 @@ specified as arguments to the remote_syslog daemon. More below.
46
46
  -p, --dest-port PORT Destination syslog port (514)
47
47
  -P, --pid-dir DIRECTORY Directory to write .pid file in (/var/run/)
48
48
  -s, --severity SEVERITY Severity (notice)
49
+ --strip-color Strip color codes
49
50
  -h, --help Show this message
51
+
50
52
 
51
53
 
52
54
  ## Example
53
55
 
54
- Daemonize, collecting from files mentioned in ./config/logs.yml as well as
55
- /var/log/mysqld.log:
56
+ Daemonize, collecting from files mentioned in `./config/logs.yml` as well as
57
+ `/var/log/mysqld.log`:
58
+
56
59
  $ remote_syslog -c configs/logs.yml -p 12345 /var/log/mysqld.log
57
60
 
58
- Stay attached to the terminal, look for and use /etc/log_files.yml if it exists,
59
- write PID to /tmp/remote_syslog.pid, and send with facility local0:
61
+ Stay attached to the terminal, look for and use `/etc/log_files.yml` if it
62
+ exists, write PID to `/tmp/remote_syslog.pid`, and send with facility local0:
63
+
60
64
  $ remote_syslog -d a.server.com -f local0 -P /tmp /var/log/mysqld.log
61
65
 
62
66
  remote_syslog will daemonize by default. A sample init file is in the gem as
63
67
  remote_syslog.init.d. You may be able to:
68
+
64
69
  $ cp examples/remote_syslog.init.d /etc/init.d/remote_syslog
65
70
 
66
71
 
@@ -73,9 +78,11 @@ The gem comes with a sample config. Optionally:
73
78
  $ cp examples/log_files.yml.example /etc/log_files.yml
74
79
 
75
80
  log_files.yml has filenames to log from (as an array) and hostname and port
76
- to log to (as a hash). Only 1 destination server is supported; the command-line
77
- argument wins. Filenames given on the command line are additive to those
78
- in the config file.
81
+ to log to (as a hash). Wildcards are supported using * and standard shell
82
+ globbing. Filenames given on the command line are additive to those in
83
+ the config file.
84
+
85
+ Only 1 destination server is supported; the command-line argument wins.
79
86
 
80
87
  files: [/var/log/httpd/access_log, /var/log/httpd/error_log, /var/log/mysqld.log, /var/run/mysqld/mysqld-slow.log]
81
88
  destination:
@@ -85,7 +92,6 @@ in the config file.
85
92
 
86
93
  ## Reporting bugs
87
94
 
88
-
89
95
  1. See whether the issue has already been reported: <https://github.com/papertrail/remote_syslog/issues/>
90
96
  2. If you don't find one, create an issue with a repro case.
91
97
 
data/bin/remote_syslog CHANGED
@@ -14,18 +14,19 @@ require 'remote_syslog'
14
14
  def remote_syslog_daemon(args)
15
15
  options = {
16
16
  :configfile => '/etc/log_files.yml',
17
- :dest_host => 'logs.papertrailapp.com',
18
- :dest_port => 514
17
+ :dest_host => 'logs.papertrailapp.com',
18
+ :dest_port => 514
19
19
  }
20
20
  daemonize_options = {
21
- :app_name => File.basename($0) || "remote_syslog",
22
- :ARGV => ['start'],
23
- :dir_mode => :system,
24
- :multiple => false,
25
- :ontop => false,
26
- :mode => :exec,
27
- :backtrace => false,
28
- :monitor => false
21
+ :app_name => File.basename($0) || "remote_syslog",
22
+ :ARGV => ['start'],
23
+ :dir_mode => :system,
24
+ :multiple => false,
25
+ :ontop => false,
26
+ :mode => :exec,
27
+ :backtrace => false,
28
+ :monitor => false,
29
+ :strip_color => false
29
30
  }
30
31
 
31
32
  op = OptionParser.new do |opts|
@@ -61,6 +62,9 @@ def remote_syslog_daemon(args)
61
62
  opts.on("-s", "--severity SEVERITY", "Severity (notice)") do |v|
62
63
  options[:severity] = v.upcase
63
64
  end
65
+ opts.on("--strip-color", "Strip color codes") do
66
+ options[:strip_color] = true
67
+ end
64
68
  opts.on_tail("-h", "--help", "Show this message") do
65
69
  puts opts
66
70
  exit
@@ -97,9 +101,9 @@ def remote_syslog_daemon(args)
97
101
  files.each do |path|
98
102
  begin
99
103
  EventMachine::file_tail(File.expand_path(path), RemoteSyslog::Reader,
100
- options[:dest_host], options[:dest_port],
101
- { :socket => socket, :facility => options[:facility],
102
- :severity => options[:severity] })
104
+ options[:dest_host], options[:dest_port],
105
+ :socket => socket, :facility => options[:facility],
106
+ :severity => options[:severity], :strip_color => options[:strip_color])
103
107
 
104
108
  rescue Errno::ENOENT => e
105
109
  puts "#{File.expand_path(path)} not found, continuing. (#{e.message})"
@@ -1,4 +1,4 @@
1
- files: [/var/log/httpd/access_log, /var/log/httpd/error_log, /var/log/mysqld.log, /var/run/mysqld/mysqld-slow.log]
1
+ files: [/var/log/httpd/access_log, /var/log/httpd/error_log, /opt/misc/*, /var/log/mysqld.log, /var/run/mysqld/mysqld-slow.log]
2
2
  destination:
3
3
  host: logs.papertrailapp.com
4
4
  port: 12345 # optional, defaults to 514
@@ -0,0 +1,9 @@
1
+ # Supervisor conf file for stock Ubuntu 11.04 install
2
+ [program:remote_syslog]
3
+
4
+ command=/var/lib/gems/1.8/bin/remote_syslog --no-detach
5
+ user=root
6
+ group=root
7
+ autostart=true
8
+ autorestart=true
9
+ redirect_stderr=true
@@ -1,57 +1,69 @@
1
+ require 'eventmachine'
2
+ require 'eventmachine-tail'
3
+ require 'em-dns-resolver'
4
+ require 'syslog_protocol'
5
+
1
6
  module RemoteSyslog
2
7
  class Reader < EventMachine::FileTail
3
- def initialize(path, dest_addr, dest_port, options = {})
4
- @dest_addr = dest_addr
5
- @dest_port = dest_port.to_i
6
-
8
+ COLORED_REGEXP = /\e\[(?:(?:[34][0-7]|[0-9]);){0,2}(?:[34][0-7]|[0-9])m/
9
+
10
+ def initialize(path, destination_address, destination_port, options = {})
11
+ super(path, -1)
12
+
13
+ @destination_address = destination_address
14
+ @destination_port = destination_port.to_i
15
+
16
+ @strip_color = options[:strip_color]
17
+
7
18
  @socket = options[:socket] || EventMachine.open_datagram_socket('0.0.0.0', 0)
8
- @program = options[:program] || File.basename(path) || 'remote_syslog'
9
- @hostname = options[:hostname] || `hostname`.strip
10
- @hostname = 'localhost' unless @hostname && @hostname != ''
11
-
12
- if options[:severity]
13
- @severity = severity_value(options[:severity]) || raise(ArgumentError, "Invalid severity: #{options[:severity]} (valid: #{severities.keys.join(', ')})")
14
- else
15
- @severity = severity_value(:notice)
19
+
20
+ @buffer = BufferedTokenizer.new
21
+
22
+ @packet = SyslogProtocol::Packet.new
23
+
24
+ local_hostname = options[:hostname] || (Socket.gethostname rescue `hostname`.chomp)
25
+ if local_hostname.nil? || local_hostname.empty?
26
+ local_hostname = 'localhost'
16
27
  end
17
-
18
- if options[:facility]
19
- @facility = facility_value(options[:facility]) || raise(ArgumentError, "Invalid facility: #{options[:facility]} (valid: #{facilities.keys.join(', ')}")
20
- else
21
- @facility = facility_value(:user)
28
+
29
+ @packet.hostname = local_hostname
30
+ @packet.facility = options[:facility] || 'user'
31
+ @packet.severity = options[:severity] || 'notice'
32
+ @packet.tag = options[:program] || File.basename(path) || File.basename($0)
33
+
34
+ # Try to resolve the destination address
35
+ resolve_destination_address
36
+
37
+ # Every 60 seconds we'll see if the address has changed
38
+ EventMachine.add_periodic_timer(60) do
39
+ resolve_destination_address
22
40
  end
41
+ end
23
42
 
24
- super(path, -1)
25
- @buffer = BufferedTokenizer.new
43
+ def resolve_destination_address
44
+ request = EventMachine::DnsResolver.resolve(@destination_address)
45
+ request.callback do |addrs|
46
+ @cached_destination_ip = addrs.first
47
+ end
26
48
  end
27
-
49
+
28
50
  def receive_data(data)
29
51
  @buffer.extract(data).each do |line|
30
52
  transmit(line)
31
53
  end
32
54
  end
33
55
 
56
+ def destination_address
57
+ @cached_destination_ip || @destination_address
58
+ end
59
+
34
60
  def transmit(message)
35
- time ||= Time.now
36
- day = time.strftime('%b %d').sub(/0(\d)/, ' \\1')
61
+ message = message.gsub(COLORED_REGEXP, '') if @strip_color
37
62
 
38
- @socket.send_datagram("<#{(@facility) + @severity}>#{day} #{time.strftime('%T')} #{@hostname} #{@program}: #{message}", @dest_addr, @dest_port)
39
- end
40
-
41
- def facility_value(f)
42
- f.is_a?(Integer) ? f*8 : facilities[f.to_sym]
43
- end
44
-
45
- def severity_value(s)
46
- s.is_a?(Integer) ? s : severities[s.to_sym]
47
- end
48
-
49
- def facilities
50
- Levels::FACILITIES
51
- end
52
-
53
- def severities
54
- Levels::SEVERITIES
63
+ packet = @packet.dup
64
+ packet.content = message
65
+
66
+ @socket.send_datagram(packet.assemble, destination_address, @destination_port)
55
67
  end
56
68
  end
57
69
  end
data/lib/remote_syslog.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module RemoteSyslog
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
4
4
 
5
5
  require 'remote_syslog/levels'
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
8
8
  ## If your rubyforge_project name is different, then edit it and comment out
9
9
  ## the sub! line in the Rakefile
10
10
  s.name = 'remote_syslog'
11
- s.version = '1.0.0'
12
- s.date = '2011-03-22'
11
+ s.version = '1.1.0'
12
+ s.date = '2011-05-26'
13
13
  s.rubyforge_project = 'remote_syslog'
14
14
 
15
15
  ## Make sure your summary is short. The description may be as long
@@ -20,18 +20,14 @@ Gem::Specification.new do |s|
20
20
  ## List the primary authors. If there are a bunch of authors, it's probably
21
21
  ## better to set the email to an email list or something. If you don't have
22
22
  ## a custom homepage, consider using your GitHub URL or the like.
23
- s.authors = ['Papertrail']
24
- s.email = 'troy@sevenscale.com'
23
+ s.authors = [ 'Troy Davis', 'Eric Lindvall' ]
24
+ s.email = [ 'troy@sevenscale.com', 'eric@sevenscale.com' ]
25
25
  s.homepage = 'http://github.com/papertrail/remote_syslog'
26
26
 
27
27
  ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
28
28
  ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
29
29
  s.require_paths = %w[lib]
30
30
 
31
- ## This sections is only necessary if you have C extensions.
32
- #s.require_paths << 'ext'
33
- #s.extensions = %w[ext/extconf.rb]
34
-
35
31
  ## If your gem includes any executables, list them here.
36
32
  s.executables = ['remote_syslog']
37
33
  s.default_executable = 'remote_syslog'
@@ -47,6 +43,8 @@ Gem::Specification.new do |s|
47
43
  s.add_dependency 'daemons'
48
44
  s.add_dependency 'eventmachine'
49
45
  s.add_dependency 'eventmachine-tail'
46
+ s.add_dependency 'syslog_protocol'
47
+ s.add_dependency 'em-resolv-replace'
50
48
 
51
49
  ## List your development dependencies here. Development dependencies are
52
50
  ## those that are only needed during development
@@ -64,6 +62,7 @@ Gem::Specification.new do |s|
64
62
  bin/remote_syslog
65
63
  examples/log_files.yml.example
66
64
  examples/remote_syslog.init.d
65
+ examples/remote_syslog.supervisor.conf
67
66
  lib/remote_syslog.rb
68
67
  lib/remote_syslog/levels.rb
69
68
  lib/remote_syslog/reader.rb
metadata CHANGED
@@ -1,21 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remote_syslog
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 0
10
- version: 1.0.0
10
+ version: 1.1.0
11
11
  platform: ruby
12
12
  authors:
13
- - Papertrail
13
+ - Troy Davis
14
+ - Eric Lindvall
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-03-22 00:00:00 -07:00
19
+ date: 2011-05-26 00:00:00 -07:00
19
20
  default_executable: remote_syslog
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
@@ -60,8 +61,38 @@ dependencies:
60
61
  version: "0"
61
62
  type: :runtime
62
63
  version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: syslog_protocol
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ type: :runtime
77
+ version_requirements: *id004
78
+ - !ruby/object:Gem::Dependency
79
+ name: em-resolv-replace
80
+ prerelease: false
81
+ requirement: &id005 !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ type: :runtime
91
+ version_requirements: *id005
63
92
  description: Lightweight daemon to tail one or more log files and transmit UDP syslog messages to a remote syslog host (centralized log aggregation). Generates UDP packets itself instead of depending on a system syslog daemon, so it doesn't affect system-wide logging configuration.
64
- email: troy@sevenscale.com
93
+ email:
94
+ - troy@sevenscale.com
95
+ - eric@sevenscale.com
65
96
  executables:
66
97
  - remote_syslog
67
98
  extensions: []
@@ -77,6 +108,7 @@ files:
77
108
  - bin/remote_syslog
78
109
  - examples/log_files.yml.example
79
110
  - examples/remote_syslog.init.d
111
+ - examples/remote_syslog.supervisor.conf
80
112
  - lib/remote_syslog.rb
81
113
  - lib/remote_syslog/levels.rb
82
114
  - lib/remote_syslog/reader.rb