buffered_remote_syslog_logger 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 97a525c5cc52ca6b91f1cf5d0a7dd1cd52a47cda
4
+ data.tar.gz: 208ff7834713e68cd03379eee74cf4c0c6823493
5
+ SHA512:
6
+ metadata.gz: c5d298b56ca787cdc59bd563b4c43c5ddfde36375d64278de5fd024807d50995fca3ab301df9cddcc0277afa23840aac112ad06524689d069ff8bcc091513e6d
7
+ data.tar.gz: 37af117ebd30bd10581e82d708c0270ef3388fabdd9ed6c74b3640f6b5e1977acfaad4fb886fc553a357ff1ff4421a1173c6cbf95b8e18488faa7f54a5d372d0
data/.gitignore ADDED
@@ -0,0 +1,28 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+ .rspec
15
+
16
+ # YARD artifacts
17
+ .yardoc
18
+ _yardoc
19
+ doc/
20
+
21
+
22
+ # ignore eclipse
23
+ .buildpath
24
+ .project
25
+
26
+ # ignore rvm
27
+ .rvmrc
28
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in buffered_remote_syslog_logger.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ buffered_remote_syslog_logger (0.2.0)
5
+ activesupport (< 4.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (3.2.19)
11
+ i18n (~> 0.6, >= 0.6.4)
12
+ multi_json (~> 1.0)
13
+ byebug (3.1.2)
14
+ columnize (~> 0.8)
15
+ debugger-linecache (~> 1.2)
16
+ columnize (0.8.9)
17
+ debugger-linecache (1.2.0)
18
+ diff-lcs (1.2.5)
19
+ docile (1.1.5)
20
+ i18n (0.6.9)
21
+ multi_json (1.10.1)
22
+ rake (10.3.2)
23
+ rspec (3.0.0)
24
+ rspec-core (~> 3.0.0)
25
+ rspec-expectations (~> 3.0.0)
26
+ rspec-mocks (~> 3.0.0)
27
+ rspec-core (3.0.2)
28
+ rspec-support (~> 3.0.0)
29
+ rspec-expectations (3.0.2)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.0.0)
32
+ rspec-mocks (3.0.2)
33
+ rspec-support (~> 3.0.0)
34
+ rspec-support (3.0.2)
35
+ simplecov (0.8.2)
36
+ docile (~> 1.1.0)
37
+ multi_json
38
+ simplecov-html (~> 0.8.0)
39
+ simplecov-html (0.8.0)
40
+
41
+ PLATFORMS
42
+ ruby
43
+
44
+ DEPENDENCIES
45
+ buffered_remote_syslog_logger!
46
+ bundler (~> 1.6)
47
+ byebug
48
+ rake
49
+ rspec
50
+ simplecov
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 DailyDeal GmbH
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ buffered_remote_syslog_logger
2
+ =============================
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'buffered_remote_syslog_logger/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "buffered_remote_syslog_logger"
8
+ spec.version = BufferedRemoteSyslogLogger::VERSION
9
+ spec.authors = ["DailyDeal Development"]
10
+ spec.email = ["dev@dailydeal.de"]
11
+ spec.summary = %q{centralize logging without interleaving in a remote syslog}
12
+ spec.description = %q{centralize logging without interleaving in a remote syslog}
13
+ spec.homepage = "http://github.com/DailyDeal/buffered_remote_syslog_logger.git"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(spec)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6" # usability
22
+ spec.add_development_dependency "rake" # functionality
23
+ spec.add_development_dependency "rspec" # testability
24
+ spec.add_development_dependency "simplecov" # coverage, obviously
25
+ spec.add_development_dependency "byebug" # replacement for 'debugger' under 2.0+
26
+
27
+ spec.add_runtime_dependency 'activesupport', '< 4.0' # use buffered logger base implementation
28
+ end
29
+
@@ -0,0 +1,6 @@
1
+ require 'buffered_remote_syslog_logger/tcp_logger'
2
+ require 'buffered_remote_syslog_logger/middleware'
3
+
4
+ module BufferedRemoteSyslogLogger
5
+ end
6
+
@@ -0,0 +1,28 @@
1
+
2
+ module BufferedRemoteSyslogLogger
3
+
4
+ class Middleware
5
+
6
+ attr_accessor :app, :logger
7
+
8
+
9
+ def initialize(app, options = {})
10
+ @logger = Rails.logger
11
+ @app = app
12
+ end
13
+
14
+
15
+ def call(env)
16
+ request_id = env['HTTP_X_REQUEST_ID'] || rand(100000000)
17
+ request_id = sprintf("%08d", request_id)
18
+ Thread.current.thread_variable_set(:http_request_id, request_id)
19
+
20
+ @status, @headers, @response = app.call(env)
21
+ [@status, @headers, @response]
22
+ ensure
23
+ logger.flush
24
+ logger.close
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,214 @@
1
+ require 'socket'
2
+ require 'syslog'
3
+ require 'logger'
4
+ require 'timeout'
5
+ require 'active_support'
6
+
7
+ # BufferedRemoteSyslogLogger is used as a dead-simple replacement for
8
+ # syslog ruby libs. None of them is able to send logs
9
+ # to a remote server, and even less in TCP.
10
+ #
11
+ # Example:
12
+ #
13
+ # For rails (3.X) :
14
+ #
15
+ # config.logger = BufferedRemoteSyslogLogger::TcpLogger.new(:host => 'localhost')
16
+ #
17
+ # For more info about Syslog protocol, please refer to the RFC:
18
+ # http://www.faqs.org/rfcs/rfc3164.html
19
+ #
20
+ # Major Parts taken from TcpSyslog which in turn has Parts taken from SyslogLogger gem and ActiveSupport
21
+ #
22
+ module BufferedRemoteSyslogLogger
23
+ class TcpLogger < ::ActiveSupport::BufferedLogger
24
+ include Logger::Severity
25
+
26
+ # From 'man syslog.h':
27
+ # LOG_EMERG A panic condition was reported to all processes.
28
+ # LOG_ALERT A condition that should be corrected immediately.
29
+ # LOG_CRIT A critical condition.
30
+ # LOG_ERR An error message.
31
+ # LOG_WARNING A warning message.
32
+ # LOG_NOTICE A condition requiring special handling.
33
+ # LOG_INFO A general information message.
34
+ # LOG_DEBUG A message useful for debugging programs.
35
+
36
+ # From logger rdoc:
37
+ # FATAL: an unhandleable error that results in a program crash
38
+ # ERROR: a handleable error condition
39
+ # WARN: a warning
40
+ # INFO: generic (useful) information about system operation
41
+ # DEBUG: low-level information for developers
42
+
43
+ # Maps Logger warning types to syslog(3) warning types.
44
+ LOGGER_MAP = {
45
+ :unknown => Syslog::LOG_ALERT,
46
+ :fatal => Syslog::LOG_CRIT,
47
+ :error => Syslog::LOG_ERR,
48
+ :warn => Syslog::LOG_WARNING,
49
+ :info => Syslog::LOG_INFO,
50
+ :debug => Syslog::LOG_DEBUG
51
+ }
52
+
53
+ SOCKET_SEND_RETRY_ATTEMPTS = 2
54
+ class SocketTimeoutError < StandardError; end
55
+
56
+ # Maps Logger log levels to their values so we can silence.
57
+ LOGGER_LEVEL_MAP = {}
58
+
59
+ LOGGER_MAP.each_key do |key|
60
+ LOGGER_LEVEL_MAP[key] = Logger.const_get key.to_s.upcase
61
+ end
62
+
63
+
64
+ # Maps Logger log level values to syslog log levels.
65
+ LEVEL_LOGGER_MAP = {}
66
+
67
+ LOGGER_LEVEL_MAP.invert.each do |level, severity|
68
+ LEVEL_LOGGER_MAP[level] = LOGGER_MAP[severity]
69
+ end
70
+
71
+
72
+ OPTION_DEFAULTS = {
73
+ :level => Logger::DEBUG,
74
+ :host => '127.0.0.1',
75
+ :port => '514',
76
+ :facility => Syslog::LOG_USER,
77
+ :program_name => 'buffered_remote_syslog_logger',
78
+ :auto_flushing => 1,
79
+ :remove_ansi_colors => true
80
+ }
81
+
82
+
83
+ attr_accessor :host, :port, :program_name, :level, :facility, :auto_flushing, :remove_ansi_colors, :buffer, :socket, :hostname
84
+
85
+
86
+ # Usage :
87
+ # * +options+ : A hash with the following options
88
+ # ** +level+ : severity level, defaults to debug
89
+ # ** +host+ : syslog daemon host, defaults to 'localhost'
90
+ # ** +port+ : syslog daemon port, defaults to '514'
91
+ # ** +facility+ : used syslog facility, defaults to log_user
92
+ # ** +program_name+ : name of the application, defaults to 'OPTION_DEFAULTS'
93
+ # ** +auto_flushing+ : number of messages to buffer before flushing, defaults to 1 (always flush right away)
94
+ # ** +remove_ansi_colors+ : boolean to determine, whether or not to remove ansi colors, defaults to true
95
+ def initialize(options = {})
96
+ @buffer = []
97
+ @socket = {}
98
+
99
+ options = OPTION_DEFAULTS.merge(Hash[options.map{ |key, value| [key.to_sym, value] }])
100
+
101
+ [:host, :port, :facility, :program_name, :auto_flushing, :remove_ansi_colors].each do |key|
102
+ self.public_send("#{key}=", options[key])
103
+ end
104
+
105
+ @level = LEVEL_LOGGER_MAP[options[:level]]
106
+ @hostname = `hostname`
107
+
108
+ return if defined? SYSLOG
109
+ self.class.const_set :SYSLOG, true
110
+ end
111
+
112
+
113
+ # Almost duplicates Logger#add.
114
+ def add(severity, message, progname = nil, &block)
115
+ severity ||= Logger::UNKNOWN
116
+ return if @level < severity
117
+
118
+ message = clean(message || block.call)
119
+ @buffer << {:severity => severity, :body => clean(message)}
120
+ auto_flush
121
+ message
122
+ end
123
+
124
+
125
+ def auto_flush
126
+ flush if 0 == @auto_flushing || @auto_flushing <= @buffer.count
127
+ end
128
+
129
+
130
+ # In Logger, this dumps the raw message; the closest equivalent
131
+ # would be Logger::UNKNOWN
132
+ def <<(message)
133
+ add(Logger::UNKNOWN, message)
134
+ end
135
+
136
+
137
+ def close
138
+ # flush
139
+ # socket.close
140
+ # @socket[Thread.current] = nil
141
+ end
142
+
143
+
144
+ # Flush buffered logs to Syslog
145
+ def flush
146
+ @buffer.each do |message|
147
+ log(message[:severity], message[:body])
148
+ end
149
+ @buffer.clear
150
+ nil
151
+ end
152
+
153
+
154
+ def socket
155
+ @socket[Thread.current] ||= TCPSocket.new(host, port)
156
+ end
157
+
158
+
159
+ protected
160
+
161
+
162
+ # Clean up messages so they're nice and pretty.
163
+ def clean(message)
164
+ message = message.to_s.dup
165
+ message.strip!
166
+ message.gsub!(/%/, '%%') # syslog(3) freaks on % (printf)
167
+ message.gsub!(/\e\[[^m]*m/, '') if @remove_ansi_colors # remove useless ansi color codes
168
+ return message
169
+ end
170
+
171
+
172
+ def request_id
173
+ Thread.current.thread_variable_get(:http_request_id) || '1'
174
+ end
175
+
176
+
177
+ # send the message
178
+ def log(severity, message)
179
+ return if 0 == message.bytesize
180
+
181
+ retry_attempt ||= 0
182
+
183
+ message_chunks = self.format_message(severity, message)
184
+ Timeout::timeout(2, SocketTimeoutError) do
185
+ message_chunks.each do |chunk|
186
+ packet = chunk.rstrip + "\n"
187
+ socket.write(packet)
188
+ end
189
+ socket.flush
190
+ end
191
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EPIPE, SocketTimeoutError => e
192
+ retry_attempt += 1
193
+
194
+ @socket[Thread.current].close
195
+ @socket[Thread.current] = nil
196
+ retry if retry_attempt <= SOCKET_SEND_RETRY_ATTEMPTS
197
+ end
198
+
199
+
200
+ def format_message severity, message
201
+ message_marker = "<#{facility + LEVEL_LOGGER_MAP[severity]}>#{Time.now.strftime("%b %e %H:%M:%S")} #{hostname.rstrip} [#{program_name.rstrip}][#{request_id.rstrip}]: "
202
+ per_chunk_max_length = 1024 - (message_marker.bytesize + 1)
203
+
204
+ message.split("\n").inject([]) do |target_array, message_line|
205
+ message_line_chunk_count = (message_line.bytesize.to_f / per_chunk_max_length.to_f).ceil.to_i
206
+ message_line_chunk_count.times.each do |chunk_index|
207
+ target_array << message_marker + message_line.byteslice((chunk_index + 0) * per_chunk_max_length, per_chunk_max_length)
208
+ end
209
+ target_array
210
+ end
211
+ end
212
+ end
213
+ end
214
+
@@ -0,0 +1,3 @@
1
+ module BufferedRemoteSyslogLogger
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe BufferedRemoteSyslogLogger::TcpLogger do
4
+
5
+ describe '#format_message' do
6
+
7
+ context 'WHEN the message was longer than 1024 bytes' do
8
+ it 'should be sliced up into multible chunks' do
9
+ string = SecureRandom.hex(650)
10
+ chunks = BufferedRemoteSyslogLogger::TcpLogger.new.send(:format_message, 4, string)
11
+
12
+ prepend_length = `hostname`.rstrip.size + 57
13
+
14
+ chunks.size.should eq 2
15
+ chunks.first.size.should eq 1023
16
+ chunks[0].should =~ /#{string.byteslice(0, 1024 - prepend_length - 1)}/
17
+ chunks[1].should =~ /#{string.byteslice(1024 - prepend_length - 1, 1024 - prepend_length - 1)}/
18
+ end
19
+ end
20
+
21
+ context 'WHEN the text contains newline characters' do
22
+ it 'should generate seperate chunks for those' do
23
+ string = "foo\nbar"
24
+
25
+ chunks = BufferedRemoteSyslogLogger::TcpLogger.new.send(:format_message, 4, string)
26
+
27
+ chunks.size.should eq 2
28
+ chunks[0].should =~ /foo/
29
+ chunks[1].should =~ /bar/
30
+ end
31
+ end
32
+ end
33
+
34
+
35
+ describe '#log' do
36
+ it 'should send the message along' do
37
+ socket = TCPSocket.new('127.0.0.1', 514)
38
+ TCPSocket.stub(:new).and_return(socket)
39
+ socket.should_receive(:write).with("<14>#{Time.now.strftime("%b %e %H:%M:%S")} #{`hostname`.rstrip} [buffered_remote_syslog_logger][1]: foo\n")
40
+ socket.stub(:flush)
41
+ logger = BufferedRemoteSyslogLogger::TcpLogger.new
42
+ logger.info('foo')
43
+ end
44
+
45
+ context 'WHEN there was a connection error' do
46
+ it 'should retry several times' do
47
+ sockets = [TCPSocket.new('127.0.0.1', 514), TCPSocket.new('127.0.0.1', 514), TCPSocket.new('127.0.0.1', 514)]
48
+ TCPSocket.stub(:new) { sockets.shift }
49
+ sockets[0].should_receive(:write).with("<14>#{Time.now.strftime("%b %e %H:%M:%S")} #{`hostname`.rstrip} [buffered_remote_syslog_logger][1]: foo\n").and_raise(Errno::ECONNREFUSED.new)
50
+ sockets[1].should_receive(:write).with("<14>#{Time.now.strftime("%b %e %H:%M:%S")} #{`hostname`.rstrip} [buffered_remote_syslog_logger][1]: foo\n").and_raise(Errno::ECONNREFUSED.new)
51
+ sockets[2].should_receive(:write).with("<14>#{Time.now.strftime("%b %e %H:%M:%S")} #{`hostname`.rstrip} [buffered_remote_syslog_logger][1]: foo\n").and_raise(Errno::ECONNREFUSED.new)
52
+ Socket.any_instance.stub(:flush)
53
+ logger = BufferedRemoteSyslogLogger::TcpLogger.new
54
+ logger.info('foo')
55
+ end
56
+ end
57
+ end
58
+
59
+
60
+ describe '#<<' do
61
+ it 'should simply forward to add' do
62
+ logger = BufferedRemoteSyslogLogger::TcpLogger.new
63
+ logger.should_receive(:add).with(5, 'meh')
64
+ logger << 'meh'
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe BufferedRemoteSyslogLogger do
4
+ # no logic, no tests
5
+ end
6
+
@@ -0,0 +1,25 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ require 'simplecov'
4
+ SimpleCov.adapters.define 'gem' do
5
+ add_filter '/spec/'
6
+ end
7
+ SimpleCov.start 'gem'
8
+
9
+
10
+ # require code after simplecov
11
+ require 'buffered_remote_syslog_logger'
12
+
13
+ RSpec.configure do |config|
14
+
15
+ config.expect_with :rspec do |c|
16
+ c.syntax = :should
17
+ end
18
+ config.mock_with :rspec do |c|
19
+ c.syntax = :should
20
+ end
21
+
22
+ I18n.enforce_available_locales = false
23
+ config.mock_with :rspec
24
+ end
25
+
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: buffered_remote_syslog_logger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - DailyDeal Development
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
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: simplecov
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
+ - !ruby/object:Gem::Dependency
70
+ name: byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - <
88
+ - !ruby/object:Gem::Version
89
+ version: '4.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - <
95
+ - !ruby/object:Gem::Version
96
+ version: '4.0'
97
+ description: centralize logging without interleaving in a remote syslog
98
+ email:
99
+ - dev@dailydeal.de
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - Gemfile
106
+ - Gemfile.lock
107
+ - LICENSE
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - buffered_remote_syslog_logger.gemspec
112
+ - lib/buffered_remote_syslog_logger.rb
113
+ - lib/buffered_remote_syslog_logger/middleware.rb
114
+ - lib/buffered_remote_syslog_logger/tcp_logger.rb
115
+ - lib/buffered_remote_syslog_logger/version.rb
116
+ - spec/lib/buffered_remote_syslog_logger/tcp_logger_spec.rb
117
+ - spec/lib/buffered_remote_syslog_logger_spec.rb
118
+ - spec/spec_helper.rb
119
+ homepage: http://github.com/DailyDeal/buffered_remote_syslog_logger.git
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.2.2
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: centralize logging without interleaving in a remote syslog
143
+ test_files:
144
+ - spec/lib/buffered_remote_syslog_logger/tcp_logger_spec.rb
145
+ - spec/lib/buffered_remote_syslog_logger_spec.rb
146
+ - spec/spec_helper.rb