remote_syslog_sender_tls 1.2.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5f65bb8417e45e163a189b81438aa271edcc9a6d35e7237ca99c7a7ad2dcd161
4
+ data.tar.gz: c7b86ded80d26bfb06c3535a78d60e18507e5164e96fbeee6cbc52b8aba9a2ae
5
+ SHA512:
6
+ metadata.gz: 739353beef9a0bf79c90fc10939fc304e72ea974aade7099dd38e10c4bf2b8c62d89748594ab1654b91da7fa85da3698327cad4d3e7a9c2f0f9fa537bfee0cde
7
+ data.tar.gz: f71c0aea8565a4202ffba8537c73c228912f49873051810df638a1e70ce7a5f9ece7800b651bc56bd345c139469536507c9e67e5b99df7c6e3b40d8fe0f316c4
data/.gitignore ADDED
@@ -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,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2017 joker1007
4
+ Original Copyright (c) 2011 Eric Lindvall
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # Remote Syslog Sender
2
+
3
+ This gem is syslog sender that is extracted from [papertrail/remote_syslog_logger](https://github.com/papertrail/remote_syslog_logger)
4
+
5
+ This can send message to remote syslog server via UDP, TCP, TCP+TLS.
6
+ (Original does not support TCP, TCP+TLS protocol).
7
+
8
+ ## Installation
9
+
10
+ The easiest way to install `remote_syslog_sender` is with Bundler. Add
11
+ `remote_syslog_sender` to your `Gemfile`.
12
+
13
+ If you are not using a `Gemfile`, run:
14
+
15
+ $ [sudo] gem install remote_syslog_sender
16
+
17
+
18
+ ## Usage
19
+
20
+ ```ruby
21
+ sender = RemoteSyslogSender.new('syslog.domain.com', 514) # default protocol is UDP
22
+ sender.transmit("message body")
23
+ # or
24
+ sender.write("message body")
25
+
26
+
27
+ ## TCP
28
+ sender = RemoteSyslogSender.new('syslog.domain.com', 514, protocol: :tcp)
29
+ sender.transmit("message body")
30
+
31
+ ## TCP+TLS
32
+ sender = RemoteSyslogSender.new('syslog.domain.com', 514, protocol: :tcp, tls: true, ca_file: "custom_ca.pem")
33
+ sender.transmit("message body")
34
+ ```
35
+
36
+ To point the logs to your local system, use `localhost` and ensure that
37
+ the system's syslog daemon is bound to `127.0.0.1`.
38
+
39
+
40
+ ## Limitations
41
+
42
+ If the specified host cannot be resolved, `syslog.domain.com` in the
43
+ example under the usage section above, `remote_syslog_sender` will block
44
+ for approximately 20 seconds before displaying an error. This could
45
+ result in the application failing to start or even stopping responding.
46
+
47
+ Workarounds for this include:
48
+
49
+ * use an IP address instead of a hostname.
50
+ * put a hosts entry in `/etc/hosts` or equivalent, so that DNS is not
51
+ actually consulted
52
+ * instead of logging directly to the network, write to a file and
53
+ transmit new entries with a standalone daemon like
54
+ [remote_syslog](https://github.com/papertrail/remote_syslog),
55
+
56
+ ## Message length
57
+
58
+ All log lines are truncated to a maximum of 1024 characters. This restriction
59
+ comes from [RFC 3164 section 4.1][rfc-limit]:
60
+
61
+ > The total length of the packet MUST be 1024 bytes or less.
62
+
63
+ Additionally, the generally-accepted [MTU][] of the Internet is 1500 bytes, so
64
+ regardless of the RFC, UDP syslog packets longer than 1500 bytes would not
65
+ arrive. For details or to use TCP syslog for longer messages, see
66
+ [help.papertrailapp.com][troubleshoot].
67
+
68
+ [rfc-limit]: https://tools.ietf.org/html/rfc3164#section-4.1
69
+ [MTU]: (https://en.wikipedia.org/wiki/Maximum_transmission_unit)
70
+ [troubleshoot]: http://help.papertrailapp.com/kb/configuration/troubleshooting-remote-syslog-reachability/#message-length
71
+
72
+
73
+ ## Default program name
74
+
75
+ By default, the `program` value is set to the name and ID of the invoking
76
+ process. For example, `puma[12345]` or `rack[3456]`.
77
+
78
+ The `program` value is used to populate the syslog "tag" field, must be 32
79
+ or fewer characters. In a few cases, an artifact of how the app is launched
80
+ may lead to a default `program` value longer than 32 characters. For example,
81
+ the `thin` Web server may generate a default `program` value such
82
+ as:
83
+
84
+ thin server (0.0.0.0:3001)[11179]
85
+
86
+ If this occurs, the following exception will be raised when a
87
+ `RemoteSyslogSender` is instantiated:
88
+
89
+ Tag must not be longer than 32 characters (ArgumentError)
90
+
91
+ To remedy this, explicitly provide a `program` argument which is shorter than
92
+ 32 characters. See [Usage](#usage).
93
+
94
+
95
+ ## Contributing
96
+
97
+ Bug reports and pull requests are welcome on GitHub at https://github.com/reproio/remote_syslog_sender.
98
+
99
+
100
+ ## License
101
+
102
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -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,16 @@
1
+
2
+ require 'remote_syslog_sender/udp_sender'
3
+ require 'remote_syslog_sender/tcp_sender'
4
+
5
+ module RemoteSyslogSender
6
+ VERSION = '1.0.3'
7
+
8
+ def self.new(remote_hostname, remote_port, options = {})
9
+ protocol = options.delete(:protocol)
10
+ if protocol && protocol.to_sym == :tcp
11
+ TcpSender.new(remote_hostname, remote_port, options)
12
+ else
13
+ UdpSender.new(remote_hostname, remote_port, options)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,73 @@
1
+ require 'socket'
2
+ require 'syslog_protocol'
3
+
4
+ module RemoteSyslogSender
5
+ class Sender
6
+ # To suppress initialize warning
7
+ class Packet < SyslogProtocol::Packet
8
+ def initialize(*)
9
+ super
10
+ @time = nil
11
+ end
12
+ end
13
+
14
+ attr_reader :socket
15
+ attr_accessor :packet
16
+
17
+ def initialize(remote_hostname, remote_port, options = {})
18
+ @remote_hostname = remote_hostname
19
+ @remote_port = remote_port
20
+ @whinyerrors = options[:whinyerrors]
21
+ @packet_size = options[:packet_size] || 1024
22
+
23
+ @packet = Packet.new
24
+
25
+ local_hostname = options[:hostname] || options[:local_hostname] || (Socket.gethostname rescue `hostname`.chomp)
26
+ local_hostname = 'localhost' if local_hostname.nil? || local_hostname.empty?
27
+ @packet.hostname = local_hostname
28
+
29
+ @packet.facility = options[:facility] || 'user'
30
+ @packet.severity = options[:severity] || 'notice'
31
+ @packet.tag = options[:tag] || options[:program] || "#{File.basename($0)}[#{$$}]"
32
+
33
+ @socket = nil
34
+ end
35
+
36
+ def transmit(message, packet_options = nil)
37
+ message.split(/\r?\n/).each do |line|
38
+ begin
39
+ next if line =~ /^\s*$/
40
+ packet = @packet.dup
41
+ if packet_options
42
+ packet.tag = packet_options[:program] if packet_options[:program]
43
+ packet.hostname = packet_options[:local_hostname] if packet_options[:local_hostname]
44
+ %i(hostname facility severity tag).each do |key|
45
+ packet.send("#{key}=", packet_options[key]) if packet_options[key]
46
+ end
47
+ end
48
+ packet.content = line
49
+ send_msg(packet.assemble(@packet_size))
50
+ rescue
51
+ if @whinyerrors
52
+ raise
53
+ else
54
+ $stderr.puts "#{self.class} error: #{$!.class}: #{$!}\nOriginal message: #{line}"
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ # Make this act a little bit like an `IO` object
61
+ alias_method :write, :transmit
62
+
63
+ def close
64
+ @socket.close
65
+ end
66
+
67
+ private
68
+
69
+ def send_msg(payload)
70
+ raise NotImplementedError, "please override"
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,163 @@
1
+ require 'socket'
2
+ require 'syslog_protocol'
3
+ require 'remote_syslog_sender/sender'
4
+
5
+ module RemoteSyslogSender
6
+ class TcpSender < Sender
7
+ class NonBlockingTimeout < StandardError; end
8
+
9
+ def initialize(remote_hostname, remote_port, options = {})
10
+ super
11
+ @tls = options[:tls]
12
+ @retry_limit = options[:retry_limit] || 3
13
+ @retry_interval = options[:retry_interval] || 0.5
14
+ @remote_hostname = remote_hostname
15
+ @remote_port = remote_port
16
+ @ssl_method = options[:ssl_method] || 'TLSv1_2'
17
+ @ca_file = options[:ca_file]
18
+ @verify_mode = options[:verify_mode]
19
+ @client_cert = options[:client_cert]
20
+ @client_cert_key = options[:client_cert_key]
21
+ @client_cert_key_pass = options[:client_cert_key_pass]
22
+ @timeout = options[:timeout] || 600
23
+ @timeout_exception = !!options[:timeout_exception]
24
+ @exponential_backoff = !!options[:exponential_backoff]
25
+
26
+ @mutex = Mutex.new
27
+ @tcp_socket = nil
28
+
29
+ if [:SOL_SOCKET, :SO_KEEPALIVE, :IPPROTO_TCP, :TCP_KEEPIDLE].all? {|c| Socket.const_defined? c}
30
+ @keep_alive = options[:keep_alive]
31
+ end
32
+ if Socket.const_defined?(:TCP_KEEPIDLE)
33
+ @keep_alive_idle = options[:keep_alive_idle]
34
+ end
35
+ if Socket.const_defined?(:TCP_KEEPCNT)
36
+ @keep_alive_cnt = options[:keep_alive_cnt]
37
+ end
38
+ if Socket.const_defined?(:TCP_KEEPINTVL)
39
+ @keep_alive_intvl = options[:keep_alive_intvl]
40
+ end
41
+ connect
42
+ end
43
+
44
+ def close
45
+ @socket.close if @socket
46
+ @tcp_socket.close if @tcp_socket
47
+ end
48
+
49
+ private
50
+
51
+ def connect
52
+ connect_retry_count = 0
53
+ connect_retry_limit = 3
54
+ connect_retry_interval = 1
55
+ @mutex.synchronize do
56
+ begin
57
+ close
58
+
59
+ @tcp_socket = TCPSocket.new(@remote_hostname, @remote_port)
60
+
61
+ if @keep_alive
62
+ @tcp_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
63
+ @tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE, @keep_alive_idle) if @keep_alive_idle
64
+ @tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT, @keep_alive_cnt) if @keep_alive_cnt
65
+ @tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL, @keep_alive_intvl) if @keep_alive_intvl
66
+ end
67
+ if @tls
68
+ require 'openssl'
69
+ context = OpenSSL::SSL::SSLContext.new(@ssl_method)
70
+ context.verify_mode = @verify_mode if @verify_mode
71
+ context.cert = OpenSSL::X509::Certificate.new(File.open(@client_cert) { |f| f.read }) if @client_cert
72
+ context.key = OpenSSL::PKey::RSA.new(File.open(@client_cert_key) { |f| f.read }, @client_cert_key_pass) if @client_cert_key
73
+ context.ca_file = @ca_file if @ca_file
74
+
75
+ cert_store = OpenSSL::X509::Store.new
76
+ cert_store.set_default_paths
77
+ cert_store.add_file(@ca_file) if @ca_file
78
+ context.cert_store = cert_store
79
+
80
+ @socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
81
+ @socket.connect
82
+ else
83
+ @socket = @tcp_socket
84
+ end
85
+ rescue
86
+ if connect_retry_count < connect_retry_limit
87
+ sleep connect_retry_interval
88
+ connect_retry_count += 1
89
+ retry
90
+ else
91
+ raise
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ def send_msg(payload)
98
+ if @timeout && @timeout >= 0
99
+ method = :write_nonblock
100
+ else
101
+ method = :write
102
+ end
103
+
104
+ retry_limit = @retry_limit.to_i
105
+ retry_interval = @retry_interval.to_f
106
+ retry_count = 0
107
+
108
+ payload << "\n"
109
+ payload.force_encoding(Encoding::ASCII_8BIT)
110
+ payload_size = payload.bytesize
111
+
112
+ until payload_size <= 0
113
+ start = get_time
114
+ begin
115
+ result = @mutex.synchronize { @socket.__send__(method, payload) }
116
+ payload_size -= result
117
+ payload.slice!(0, result) if payload_size > 0
118
+ rescue IO::WaitReadable
119
+ timeout_wait = @timeout - (get_time - start)
120
+ retry if IO.select([@socket], nil, nil, timeout_wait)
121
+
122
+ raise NonBlockingTimeout if @timeout_exception
123
+ break
124
+ rescue IO::WaitWritable
125
+ timeout_wait = @timeout - (get_time - start)
126
+ retry if IO.select(nil, [@socket], nil, timeout_wait)
127
+
128
+ raise NonBlockingTimeout if @timeout_exception
129
+ break
130
+ rescue
131
+ if retry_count < retry_limit
132
+ sleep retry_interval
133
+ retry_count += 1
134
+ retry_interval *= 2 if @exponential_backoff
135
+ connect
136
+ retry
137
+ else
138
+ raise
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ POSIX_CLOCK =
145
+ if defined?(Process::CLOCK_MONOTONIC_COARSE)
146
+ Process::CLOCK_MONOTONIC_COARSE
147
+ elsif defined?(Process::CLOCK_MONOTONIC)
148
+ Process::CLOCK_MONOTONIC
149
+ elsif defined?(Process::CLOCK_REALTIME_COARSE)
150
+ Process::CLOCK_REALTIME_COARSE
151
+ elsif defined?(Process::CLOCK_REALTIME)
152
+ Process::CLOCK_REALTIME
153
+ end
154
+
155
+ def get_time
156
+ if POSIX_CLOCK
157
+ Process.clock_gettime(POSIX_CLOCK)
158
+ else
159
+ Time.now.to_f
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,18 @@
1
+ require 'socket'
2
+ require 'syslog_protocol'
3
+ require 'remote_syslog_sender/sender'
4
+
5
+ module RemoteSyslogSender
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_sender_tls'
3
+ s.version = '1.2.5'
4
+ s.summary = "Message sender that sends directly to a remote syslog endpoint"
5
+ s.description = "Message sender that sends directly to a remote syslog endpoint (Support UDP, TCP, TCP+TLS)"
6
+
7
+ s.authors = ["Michelia Feng", "Tomohiro Hashidate", "Eric Lindvall"]
8
+ s.email = 'michelia.feng@gmail.com'
9
+ s.homepage = 'https://github.com/aiwantaozi/remote_syslog_sender'
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
data/test/helper.rb ADDED
@@ -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_sender'
11
+
12
+ require 'test/unit'
@@ -0,0 +1,66 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestRemoteSyslogSender < 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
+
9
+ @tcp_server = TCPServer.open('127.0.0.1', 0)
10
+ @tcp_server_port = @tcp_server.addr[1]
11
+
12
+ @tcp_server_wait_thread = Thread.start do
13
+ @tcp_server.accept
14
+ end
15
+ end
16
+
17
+ def teardown
18
+ @socket.close
19
+ @tcp_server.close
20
+ end
21
+
22
+ def test_sender
23
+ @sender = RemoteSyslogSender.new('127.0.0.1', @server_port)
24
+ @sender.write "This is a test"
25
+
26
+ message, _ = *@socket.recvfrom(1024)
27
+ assert_match(/This is a test/, message)
28
+ end
29
+
30
+ def test_sender_long_payload
31
+ @sender = RemoteSyslogSender.new('127.0.0.1', @server_port, packet_size: 10240)
32
+ @sender.write "abcdefgh" * 1000
33
+
34
+ message, _ = *@socket.recvfrom(10240)
35
+ assert_match(/#{"abcdefgh" * 1000}/, message)
36
+ end
37
+
38
+ def test_sender_tcp
39
+ @sender = RemoteSyslogSender.new('127.0.0.1', @tcp_server_port, protocol: :tcp)
40
+ @sender.write "This is a test"
41
+ sock = @tcp_server_wait_thread.value
42
+
43
+ message, _ = *sock.recvfrom(1024)
44
+ assert_match(/This is a test/, message)
45
+ end
46
+
47
+ def test_sender_tcp_nonblock
48
+ @sender = RemoteSyslogSender.new('127.0.0.1', @tcp_server_port, protocol: :tcp, timeout: 20)
49
+ @sender.write "This is a test"
50
+ sock = @tcp_server_wait_thread.value
51
+
52
+ message, _ = *sock.recvfrom(1024)
53
+ assert_match(/This is a test/, message)
54
+ end
55
+
56
+ def test_sender_multiline
57
+ @sender = RemoteSyslogSender.new('127.0.0.1', @server_port)
58
+ @sender.write "This is a test\nThis is the second line"
59
+
60
+ message, _ = *@socket.recvfrom(1024)
61
+ assert_match(/This is a test/, message)
62
+
63
+ message, _ = *@socket.recvfrom(1024)
64
+ assert_match(/This is the second line/, message)
65
+ end
66
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remote_syslog_sender_tls
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.5
5
+ platform: ruby
6
+ authors:
7
+ - Michelia Feng
8
+ - Tomohiro Hashidate
9
+ - Eric Lindvall
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2018-07-19 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: syslog_protocol
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: bundler
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '1.6'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '1.6'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rake
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: test-unit
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ description: Message sender that sends directly to a remote syslog endpoint (Support
72
+ UDP, TCP, TCP+TLS)
73
+ email: michelia.feng@gmail.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - Gemfile
80
+ - LICENSE
81
+ - README.md
82
+ - Rakefile
83
+ - lib/remote_syslog_sender.rb
84
+ - lib/remote_syslog_sender/sender.rb
85
+ - lib/remote_syslog_sender/tcp_sender.rb
86
+ - lib/remote_syslog_sender/udp_sender.rb
87
+ - remote_syslog_sender.gemspec
88
+ - test/helper.rb
89
+ - test/test_remote_syslog_logger.rb
90
+ homepage: https://github.com/aiwantaozi/remote_syslog_sender
91
+ licenses: []
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.7.3
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Message sender that sends directly to a remote syslog endpoint
113
+ test_files:
114
+ - test/helper.rb
115
+ - test/test_remote_syslog_logger.rb