remote_syslog_logger_tcp 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ec4c1adb99c415c2702bfc3252f05be8ce9d90e5
4
+ data.tar.gz: 954871cadbb3e2565b20a5920c6bdf874a0d910a
5
+ SHA512:
6
+ metadata.gz: a1974147e97b5909402378c2be6a479a4b6ae1ffd525e1188125a48de01c67d1ae165bdcdc01fa945e715088e91557f700be6f988bd36fa7c48c3c68bdcef572
7
+ data.tar.gz: 868d79cff45de6b4379e592784c86731c9223c9a75ba46c1d7f59d1cbe70ec9965fc471dc6c3225fe75d571c2d3a90a15fdb0fa23fc8debaedc0b59c56b97600
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ .bundle
3
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Eric Lindvall
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,133 @@
1
+ # Remote Syslog Logger
2
+
3
+ This library providers an [ActiveSupport][] compatible logger that logs
4
+ directly to a remote syslogd via UDP.
5
+
6
+ [ActiveSupport]: http://as.rubyonrails.org/
7
+
8
+
9
+ # Installation
10
+
11
+ The easiest way to install `remote_syslog_logger` is with Bundler. Add
12
+ `remote_syslog_logger` to your `Gemfile`.
13
+
14
+ If you are not using a `Gemfile`, run:
15
+
16
+ $ [sudo] gem install remote_syslog_logger
17
+
18
+
19
+ # Usage
20
+
21
+ Use from Rails:
22
+
23
+ config.logger = RemoteSyslogLogger.new('syslog.domain.com', 514,
24
+ :program => "rails-#{RAILS_ENV}",
25
+ :local_hostname => "optional_hostname")
26
+
27
+ With Rails 3+ if you want to use tagged logging wrap in a `TaggedLogging` instance:
28
+
29
+ config.logger = ActiveSupport::TaggedLogging.new(
30
+ RemoteSyslogLogger.new(
31
+ 'syslog.domain.com', 514,
32
+ :program => "rails-#{RAILS_ENV}",
33
+ :local_hostname => "optional_hostname"
34
+ )
35
+ )
36
+
37
+ Use from Ruby:
38
+
39
+ $logger = RemoteSyslogLogger.new('syslog.domain.com', 514)
40
+
41
+ To point the logs to your local system, use `localhost` and ensure that
42
+ the system's syslog daemon is bound to `127.0.0.1`.
43
+
44
+
45
+ # Source
46
+
47
+ Remote Syslog Logger is available on GitHub, which can be browsed at:
48
+
49
+ <http://github.com/papertrail/remote_syslog_logger>
50
+
51
+ and cloned with:
52
+
53
+ $ git clone git://github.com/papertrail/remote_syslog_logger.git
54
+
55
+
56
+ # Limitations
57
+
58
+ If the specified host cannot be resolved, `syslog.domain.com` in the
59
+ example under the usage section above, `remote_syslog_logger` will block
60
+ for approximately 20 seconds before displaying an error. This could
61
+ result in the application failing to start or even stopping responding.
62
+
63
+ Workarounds for this include:
64
+
65
+ * use an IP address instead of a hostname.
66
+ * put a hosts entry in `/etc/hosts` or equivalent, so that DNS is not
67
+ actually consulted
68
+ * instead of logging directly to the network, write to a file and
69
+ transmit new entries with a standalone daemon like
70
+ [remote_syslog](https://github.com/papertrail/remote_syslog),
71
+
72
+ ## Message length
73
+
74
+ All log lines are truncated to a maximum of 1024 characters. This restriction
75
+ comes from [RFC 3164 section 4.1][rfc-limit]:
76
+
77
+ > The total length of the packet MUST be 1024 bytes or less.
78
+
79
+ Additionally, the generally-accepted [MTU][] of the Internet is 1500 bytes, so
80
+ regardless of the RFC, UDP syslog packets longer than 1500 bytes would not
81
+ arrive. For details or to use TCP syslog for longer messages, see
82
+ [help.papertrailapp.com][troubleshoot].
83
+
84
+ [rfc-limit]: https://tools.ietf.org/html/rfc3164#section-4.1
85
+ [MTU]: (https://en.wikipedia.org/wiki/Maximum_transmission_unit)
86
+ [troubleshoot]: http://help.papertrailapp.com/kb/configuration/troubleshooting-remote-syslog-reachability/#message-length
87
+
88
+
89
+ ## Default program name
90
+
91
+ By default, the `program` value is set to the name and ID of the invoking
92
+ process. For example, `puma[12345]` or `rack[3456]`.
93
+
94
+ The `program` value is used to populate the syslog "tag" field, must be 32
95
+ or fewer characters. In a few cases, an artifact of how the app is launched
96
+ may lead to a default `program` value longer than 32 characters. For example,
97
+ the `thin` Web server may generate a default `program` value such
98
+ as:
99
+
100
+ thin server (0.0.0.0:3001)[11179]
101
+
102
+ If this occurs, the following exception will be raised when a
103
+ `RemoteSyslogLogger` is instantiated:
104
+
105
+ Tag must not be longer than 32 characters (ArgumentError)
106
+
107
+ To remedy this, explicitly provide a `program` argument which is shorter than
108
+ 32 characters. See [Usage](#usage).
109
+
110
+
111
+ # Contributing
112
+
113
+ Once you've made your great commits:
114
+
115
+ 1. [Fork][fk] `remote_syslog_logger`
116
+ 2. Create a topic branch - `git checkout -b my_branch`
117
+ 3. Push to your branch - `git push origin my_branch`
118
+ 4. Create a Pull Request or an [Issue][is] with a link to your branch
119
+ 5. That's it!
120
+
121
+ You might want to checkout Resque's [Contributing][cb] wiki page for information
122
+ on coding standards, new features, etc.
123
+
124
+
125
+ # License
126
+
127
+ Copyright (c) 2011-2016 Eric Lindvall. See [LICENSE][] for details.
128
+
129
+
130
+ [cb]: https://wiki.github.com/defunkt/resque/contributing
131
+ [fk]: http://help.github.com/forking/
132
+ [is]: https://github.com/papertrail/remote_syslog_logger/issues
133
+ [LICENSE]: https://github.com/papertrail/remote_syslog_logger/blob/master/LICENSE
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,17 @@
1
+
2
+ require 'remote_syslog_logger/udp_sender'
3
+ require 'remote_syslog_logger/tcp_sender'
4
+ require 'logger'
5
+
6
+ module RemoteSyslogLogger
7
+ VERSION = '1.0.3'
8
+
9
+ def self.new(remote_hostname, remote_port, options = {})
10
+ protocol = options.delete(:protocol)
11
+ if protocol && protocol.to_sym == :tcp
12
+ Logger.new(TcpSender.new(remote_hostname, remote_port, options))
13
+ else
14
+ Logger.new(UdpSender.new(remote_hostname, remote_port, options))
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,51 @@
1
+ require 'socket'
2
+ require 'syslog_protocol'
3
+
4
+ module RemoteSyslogLogger
5
+ class Sender
6
+ def initialize(remote_hostname, remote_port, options = {})
7
+ @remote_hostname = remote_hostname
8
+ @remote_port = remote_port
9
+ @whinyerrors = options[:whinyerrors]
10
+
11
+ @packet = SyslogProtocol::Packet.new
12
+
13
+ local_hostname = options[:local_hostname] || (Socket.gethostname rescue `hostname`.chomp)
14
+ local_hostname = 'localhost' if local_hostname.nil? || local_hostname.empty?
15
+ @packet.hostname = local_hostname
16
+
17
+ @packet.facility = options[:facility] || 'user'
18
+ @packet.severity = options[:severity] || 'notice'
19
+ @packet.tag = options[:program] || "#{File.basename($0)}[#{$$}]"
20
+
21
+ @socket = nil
22
+ end
23
+
24
+ def transmit(message)
25
+ message.split(/\r?\n/).each do |line|
26
+ begin
27
+ next if line =~ /^\s*$/
28
+ packet = @packet.dup
29
+ packet.content = line
30
+ send_msg(packet.assemble)
31
+ rescue
32
+ $stderr.puts "#{self.class} error: #{$!.class}: #{$!}\nOriginal message: #{line}"
33
+ raise if @whinyerrors
34
+ end
35
+ end
36
+ end
37
+
38
+ # Make this act a little bit like an `IO` object
39
+ alias_method :write, :transmit
40
+
41
+ def close
42
+ @socket.close
43
+ end
44
+
45
+ private
46
+
47
+ def send_msg(payload)
48
+ raise NotImplementedError, "please override"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,75 @@
1
+ require 'socket'
2
+ require 'syslog_protocol'
3
+ require 'remote_syslog_logger/sender'
4
+
5
+ module RemoteSyslogLogger
6
+ class TcpSender < Sender
7
+ def initialize(remote_hostname, remote_port, options = {})
8
+ super
9
+ @tls = options[:tls]
10
+ @retry_limit = options[:retry_limit] || 3
11
+ @remote_hostname = remote_hostname
12
+ @remote_port = remote_port
13
+ @ssl_method = options[:ssl_method] || 'TLSv1_2'
14
+ @ca_file = options[:ca_file]
15
+ @verify_mode = options[:verify_mode]
16
+ if [:SOL_SOCKET, :SO_KEEPALIVE, :IPPROTO_TCP, :TCP_KEEPIDLE].all? {|c| Socket.const_defined? c}
17
+ @keep_alive = options[:keep_alive]
18
+ end
19
+ if Socket.const_defined?(:TCP_KEEPIDLE)
20
+ @keep_alive_idle = options[:keep_alive_idle]
21
+ end
22
+ if Socket.const_defined?(:TCP_KEEPCNT)
23
+ @keep_alive_cnt = options[:keep_alive_cnt]
24
+ end
25
+ if Socket.const_defined?(:TCP_KEEPINTVL)
26
+ @keep_alive_intvl = options[:keep_alive_intvl]
27
+ end
28
+ connect
29
+ end
30
+
31
+ private
32
+
33
+ def connect
34
+ sock = TCPSocket.new(@remote_hostname, @remote_port)
35
+ if @keep_alive
36
+ sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
37
+ sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE, @keep_alive_idle) if @keep_alive_idle
38
+ sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT, @keep_alive_cnt) if @keep_alive_cnt
39
+ sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL, @keep_alive_intvl) if @keep_alive_intvl
40
+ end
41
+ if @tls
42
+ require 'openssl'
43
+ context = OpenSSL::SSL::SSLContext.new(@ssl_method)
44
+ context.ca_file = @ca_file if @ca_file
45
+ context.verify_mode = @verify_mode if @verify_mode
46
+ @socket = OpenSSL::SSL::SSLSocket.new(sock, context)
47
+ @socket.connect
48
+ @socket.post_connection_check(@remote_hostname)
49
+ raise "verification error" if @socket.verify_result != OpenSSL::X509::V_OK
50
+ else
51
+ @socket = sock
52
+ end
53
+ end
54
+
55
+ def send_msg(payload)
56
+ retry_limit = @retry_limit.to_i
57
+ retry_count = 0
58
+ sleep_time = 0.5
59
+
60
+ begin
61
+ @socket.puts(payload)
62
+ rescue
63
+ if retry_count < retry_limit
64
+ sleep sleep_time
65
+ retry_count += 1
66
+ sleep_time *= 2
67
+ connect
68
+ retry
69
+ else
70
+ raise
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,18 @@
1
+ require 'socket'
2
+ require 'syslog_protocol'
3
+ require 'remote_syslog_logger/sender'
4
+
5
+ module RemoteSyslogLogger
6
+ class UdpSender < Sender
7
+ def initialize(remote_hostname, remote_port, options = {})
8
+ super
9
+ @socket = UDPSocket.new
10
+ end
11
+
12
+ private
13
+
14
+ def send_msg(payload)
15
+ @socket.send(payload, 0, @remote_hostname, @remote_port)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'remote_syslog_logger_tcp'
3
+ s.version = '1.0.3'
4
+ s.summary = "Ruby Logger that sends directly to a remote syslog endpoint"
5
+ s.description = "A ruby Logger that sends UDP directly to a remote syslog endpoint"
6
+
7
+ s.authors = ["Eric Lindvall"]
8
+ s.email = 'eric@5stops.com'
9
+ s.homepage = 'https://github.com/papertrail/remote_syslog_logger'
10
+
11
+ s.files = `git ls-files -z`.split("\x0")
12
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
13
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
14
+ s.require_paths = %w[lib]
15
+
16
+ s.add_runtime_dependency 'syslog_protocol'
17
+
18
+ s.add_development_dependency "bundler", "~> 1.6"
19
+ s.add_development_dependency "rake"
20
+ s.add_development_dependency "test-unit"
21
+ end
@@ -0,0 +1,12 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ unless ENV['BUNDLE_GEMFILE']
4
+ require 'rubygems'
5
+ require 'bundler'
6
+ Bundler.setup
7
+ Bundler.require
8
+ end
9
+
10
+ require 'remote_syslog_logger'
11
+
12
+ require 'test/unit'
@@ -0,0 +1,28 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestRemoteSyslogLogger < Test::Unit::TestCase
4
+ def setup
5
+ @server_port = rand(50000) + 1024
6
+ @socket = UDPSocket.new
7
+ @socket.bind('127.0.0.1', @server_port)
8
+ end
9
+
10
+ def test_logger
11
+ @logger = RemoteSyslogLogger.new('127.0.0.1', @server_port)
12
+ @logger.info "This is a test"
13
+
14
+ message, addr = *@socket.recvfrom(1024)
15
+ assert_match /This is a test/, message
16
+ end
17
+
18
+ def test_logger_multiline
19
+ @logger = RemoteSyslogLogger.new('127.0.0.1', @server_port)
20
+ @logger.info "This is a test\nThis is the second line"
21
+
22
+ message, addr = *@socket.recvfrom(1024)
23
+ assert_match /This is a test/, message
24
+
25
+ message, addr = *@socket.recvfrom(1024)
26
+ assert_match /This is the second line/, message
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remote_syslog_logger_tcp
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Eric Lindvall
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-07-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: syslog_protocol
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A ruby Logger that sends UDP directly to a remote syslog endpoint
70
+ email: eric@5stops.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - Gemfile
77
+ - LICENSE
78
+ - README.md
79
+ - Rakefile
80
+ - lib/remote_syslog_logger.rb
81
+ - lib/remote_syslog_logger/sender.rb
82
+ - lib/remote_syslog_logger/tcp_sender.rb
83
+ - lib/remote_syslog_logger/udp_sender.rb
84
+ - remote_syslog_logger.gemspec
85
+ - test/helper.rb
86
+ - test/test_remote_syslog_logger.rb
87
+ homepage: https://github.com/papertrail/remote_syslog_logger
88
+ licenses: []
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.5.1
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Ruby Logger that sends directly to a remote syslog endpoint
110
+ test_files:
111
+ - test/helper.rb
112
+ - test/test_remote_syslog_logger.rb