remote_syslog-gitlab 0.0.1

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.
@@ -0,0 +1,60 @@
1
+ require 'socket'
2
+ require 'syslog_protocol'
3
+
4
+ module RemoteSyslog
5
+ class MessageGenerator
6
+ COLORED_REGEXP = /\e\[(?:(?:[0-9]{1,3});){0,2}(?:[0-9]{1,3})m/
7
+
8
+ def initialize(socket, options = {})
9
+ @socket = socket
10
+
11
+ @parse_fields = options[:parse_fields]
12
+ @strip_color = options[:strip_color]
13
+ @exclude_pattern = options[:exclude_pattern]
14
+ @prepend = options[:prepend]
15
+ @max_message_size = options[:max_message_size] || 1024
16
+
17
+ @packet = SyslogProtocol::Packet.new
18
+
19
+ if options[:hostname] && options[:hostname] != ''
20
+ local_hostname = options[:hostname]
21
+ else
22
+ local_hostname = (Socket.gethostname rescue `hostname`.chomp)[/^([^\.]+)/, 1]
23
+
24
+ if local_hostname.nil? || local_hostname == ''
25
+ local_hostname = 'localhost'
26
+ end
27
+ end
28
+
29
+ @packet.hostname = local_hostname
30
+ @packet.facility = options[:facility] || 'user'
31
+ @packet.severity = options[:severity] || 'notice'
32
+ end
33
+
34
+ def transmit(tag, message)
35
+ return if @exclude_pattern && message =~ @exclude_pattern
36
+
37
+ message = message.gsub(COLORED_REGEXP, '') if @strip_color
38
+ message = @prepend + message if @prepend
39
+
40
+ packet = @packet.dup
41
+ packet.content = message
42
+
43
+ if @parse_fields && message =~ @parse_fields
44
+ packet.hostname = $2 if $2 && $2 != ''
45
+ tag = $3 if $3 && $3 != ''
46
+ packet.content = $4 if $4 && $4 != ''
47
+
48
+ if tag
49
+ packet.tag = tag.gsub(%r{[: \]\[\\]+}, '-')
50
+ end
51
+ end
52
+
53
+ unless packet.tag
54
+ packet.tag = tag
55
+ end
56
+
57
+ @socket.write(packet.assemble(@max_message_size))
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,87 @@
1
+ require 'eventmachine'
2
+
3
+ module RemoteSyslog
4
+ # Additional class that uses TCP but no TLS. Has the benefit of a greater max packet size
5
+ class TcpEndpoint
6
+ class Handler < EventMachine::Connection
7
+ def initialize(endpoint)
8
+ @endpoint = endpoint
9
+ super()
10
+ end
11
+
12
+ def connection_completed
13
+ @endpoint.connection = self
14
+ end
15
+
16
+ def unbind
17
+ @endpoint.unbind
18
+ end
19
+ end
20
+
21
+ attr_accessor :connection
22
+
23
+ attr_reader :logger
24
+
25
+ def initialize(address, port, options = {})
26
+ @address = address
27
+ @port = port.to_i
28
+ @queue_limit = options[:queue_limit] || 10_000
29
+ @logger = options[:logger] || Logger.new(STDERR)
30
+
31
+ # Try to resolve the address
32
+ resolve_address
33
+
34
+ # Every 60 seconds we'll see if the address has changed
35
+ EventMachine.add_periodic_timer(60) do
36
+ resolve_address
37
+ end
38
+
39
+ connect
40
+ end
41
+
42
+ def connection=(conn)
43
+ port, ip = Socket.unpack_sockaddr_in(conn.get_peername)
44
+ logger.debug "Connected to #{ip}:#{port}"
45
+ @connection = conn
46
+ end
47
+
48
+ def resolve_address
49
+ request = EventMachine::DnsResolver.resolve(@address)
50
+ request.callback do |addrs|
51
+ @cached_ip = addrs.first
52
+ end
53
+ end
54
+
55
+ def address
56
+ @cached_ip || @address
57
+ end
58
+
59
+ def connect
60
+ logger.debug "Connecting to #{address}:#{@port}"
61
+ EventMachine.connect(address, @port, TcpEndpoint::Handler, self)
62
+ end
63
+
64
+ def unbind
65
+ @connection = nil
66
+
67
+ EventMachine.add_timer(1) do
68
+ connect
69
+ end
70
+ end
71
+
72
+ def write(value)
73
+ if @connection
74
+ if @queue
75
+ @connection.send_data(@queue.join("\n") + "\n")
76
+ @queue = nil
77
+ end
78
+ @connection.send_data(value + "\n")
79
+ else
80
+ (@queue ||= []) << value
81
+
82
+ # Make sure our queue does not get to be too big
83
+ @queue.shift if @queue.length > @queue_limit
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,104 @@
1
+ require 'eventmachine'
2
+
3
+ module RemoteSyslog
4
+ class TlsEndpoint
5
+ class Handler < EventMachine::Connection
6
+ def initialize(endpoint)
7
+ @endpoint = endpoint
8
+ super()
9
+ end
10
+
11
+ def connection_completed
12
+ start_tls(:verify_peer => @endpoint.server_cert != nil,
13
+ :cert_chain_file => @endpoint.client_cert_chain,
14
+ :private_key_file => @endpoint.client_private_key)
15
+ end
16
+
17
+ def ssl_verify_peer(peer_cert)
18
+ peer_cert = OpenSSL::X509::Certificate.new(peer_cert)
19
+ peer_cert.verify(@endpoint.server_cert.public_key)
20
+ end
21
+
22
+ def ssl_handshake_completed
23
+ @endpoint.connection = self
24
+ end
25
+
26
+ def unbind
27
+ @endpoint.unbind
28
+ end
29
+ end
30
+
31
+ attr_accessor :connection
32
+ attr_reader :server_cert, :client_cert_chain, :client_private_key
33
+
34
+ attr_reader :logger
35
+
36
+ def initialize(address, port, options = {})
37
+ @address = address
38
+ @port = port.to_i
39
+ @client_cert_chain = options[:client_cert_chain]
40
+ @client_private_key = options[:client_private_key]
41
+ @queue_limit = options[:queue_limit] || 10_000
42
+ @logger = options[:logger] || Logger.new(STDERR)
43
+
44
+ if options[:server_cert]
45
+ @server_cert = OpenSSL::X509::Certificate.new(File.read(options[:server_cert]))
46
+ end
47
+
48
+ # Try to resolve the address
49
+ resolve_address
50
+
51
+ # Every 60 seconds we'll see if the address has changed
52
+ EventMachine.add_periodic_timer(60) do
53
+ resolve_address
54
+ end
55
+
56
+ connect
57
+ end
58
+
59
+ def connection=(conn)
60
+ port, ip = Socket.unpack_sockaddr_in(conn.get_peername)
61
+ logger.debug "Connected to #{ip}:#{port}"
62
+ @connection = conn
63
+ end
64
+
65
+ def resolve_address
66
+ request = EventMachine::DnsResolver.resolve(@address)
67
+ request.callback do |addrs|
68
+ @cached_ip = addrs.first
69
+ end
70
+ end
71
+
72
+ def address
73
+ @cached_ip || @address
74
+ end
75
+
76
+ def connect
77
+ logger.debug "Connecting to #{address}:#{@port}"
78
+ EventMachine.connect(address, @port, TlsEndpoint::Handler, self)
79
+ end
80
+
81
+ def unbind
82
+ @connection = nil
83
+
84
+ EventMachine.add_timer(1) do
85
+ connect
86
+ end
87
+ end
88
+
89
+ def write(value)
90
+ if @connection
91
+ if @queue
92
+ @connection.send_data(@queue.join("\n") + "\n")
93
+ @queue = nil
94
+ end
95
+ @connection.send_data(value + "\n")
96
+ else
97
+ (@queue ||= []) << value
98
+
99
+ # Make sure our queue does not get to be too big
100
+ @queue.shift if @queue.length > @queue_limit
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,37 @@
1
+ require 'eventmachine'
2
+
3
+ module RemoteSyslog
4
+ class UdpEndpoint
5
+ attr_reader :logger
6
+
7
+ def initialize(address, port, options = {})
8
+ @address = address
9
+ @port = port.to_i
10
+ @socket = EventMachine.open_datagram_socket('0.0.0.0', 0)
11
+ @logger = options[:logger] || Logger.new(STDERR)
12
+
13
+ # Try to resolve the address
14
+ resolve_address
15
+
16
+ # Every 60 seconds we'll see if the address has changed
17
+ EventMachine.add_periodic_timer(60) do
18
+ resolve_address
19
+ end
20
+ end
21
+
22
+ def resolve_address
23
+ request = EventMachine::DnsResolver.resolve(@address)
24
+ request.callback do |addrs|
25
+ @cached_ip = addrs.first
26
+ end
27
+ end
28
+
29
+ def address
30
+ @cached_ip || @address
31
+ end
32
+
33
+ def write(value)
34
+ @socket.send_datagram(value, address, @port)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,4 @@
1
+ module RemoteSyslog
2
+ VERSION = "0.0.1"
3
+ end
4
+
@@ -0,0 +1,88 @@
1
+ # https://github.com/mojombo/rakegem
2
+ Gem::Specification.new do |s|
3
+ s.specification_version = 2 if s.respond_to? :specification_version=
4
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
5
+ s.rubygems_version = '1.3.5'
6
+
7
+ ## Leave these as is they will be modified for you by the rake gemspec task.
8
+ ## If your rubyforge_project name is different, then edit it and comment out
9
+ ## the sub! line in the Rakefile
10
+ s.name = 'remote_syslog-gitlab'
11
+ s.version = '0.0.1'
12
+ s.date = '2025-03-28'
13
+ s.rubyforge_project = 'remote_syslog'
14
+
15
+ ## Make sure your summary is short. The description may be as long
16
+ ## as you like.
17
+ s.summary = 'Monitor plain text log file(s) for new entries and send to remote syslog collector'
18
+ s.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."
19
+
20
+ ## List the primary authors. If there are a bunch of authors, it's probably
21
+ ## better to set the email to an email list or something. If you don't have
22
+ ## a custom homepage, consider using your GitHub URL or the like.
23
+ s.authors = [ 'Troy Davis', 'Eric Lindvall' ]
24
+ s.email = [ 'troy@sevenscale.com', 'eric@sevenscale.com' ]
25
+ s.homepage = 'http://github.com/papertrail/remote_syslog'
26
+
27
+ ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
28
+ ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
29
+ s.require_paths = %w[lib]
30
+
31
+ ## If your gem includes any executables, list them here.
32
+ s.executables = ['remote_syslog']
33
+ s.default_executable = 'remote_syslog'
34
+
35
+ ## Specify any RDoc options here. You'll want to add your README and
36
+ ## LICENSE files to the extra_rdoc_files list.
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.extra_rdoc_files = %w[README.md LICENSE]
39
+
40
+ ## List your runtime dependencies here. Runtime dependencies are those
41
+ ## that are needed for an end user to actually USE your code.
42
+ #s.add_dependency('DEPNAME', [">= 1.1.0", "< 2.0.0"])
43
+ s.add_dependency 'servolux', [ '~> 0.10.0' ]
44
+ s.add_dependency 'file-tail'
45
+ s.add_dependency 'eventmachine', [ '>= 0.12.10', '< 1.1' ]
46
+ s.add_dependency 'eventmachine-tail', [ '>= 0.6.4' ]
47
+ s.add_dependency 'syslog_protocol', [ '~> 0.9.2' ]
48
+ s.add_dependency 'em-resolv-replace'
49
+
50
+ ## List your development dependencies here. Development dependencies are
51
+ ## those that are only needed during development
52
+ #s.add_development_dependency('DEVDEPNAME', [">= 1.1.0", "< 2.0.0"])
53
+
54
+ ## Leave this section as-is. It will be automatically generated from the
55
+ ## contents of your Git repository via the gemspec task. DO NOT REMOVE
56
+ ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
57
+ # = MANIFEST =
58
+ s.files = %w[
59
+ Gemfile
60
+ LICENSE
61
+ README.md
62
+ Rakefile
63
+ bin/remote_syslog
64
+ examples/com.papertrailapp.remote_syslog.plist
65
+ examples/log_files.yml.example
66
+ examples/log_files.yml.example.advanced
67
+ examples/remote_syslog.init.d
68
+ examples/remote_syslog.supervisor.conf
69
+ examples/remote_syslog.upstart.conf
70
+ lib/remote_syslog.rb
71
+ lib/remote_syslog/agent.rb
72
+ lib/remote_syslog/cli.rb
73
+ lib/remote_syslog/eventmachine_reader.rb
74
+ lib/remote_syslog/file_tail_reader.rb
75
+ lib/remote_syslog/glob_watch.rb
76
+ lib/remote_syslog/message_generator.rb
77
+ lib/remote_syslog/tcp_endpoint.rb
78
+ lib/remote_syslog/tls_endpoint.rb
79
+ lib/remote_syslog/udp_endpoint.rb
80
+ remote_syslog.gemspec
81
+ test/unit/message_generator_test.rb
82
+ ]
83
+ # = MANIFEST =
84
+
85
+ ## Test files will be grabbed from the file list. Make sure the path glob
86
+ ## matches what you actually use.
87
+ s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
88
+ end
@@ -0,0 +1,14 @@
1
+ require 'test/unit'
2
+ require 'remote_syslog/message_generator'
3
+
4
+ class MessageGeneratorTest < Test::Unit::TestCase
5
+ def test_prepend_prepend
6
+ socket = []
7
+ def socket.write(packet)
8
+ self << packet
9
+ end
10
+ generator = RemoteSyslog::MessageGenerator.new(socket, {:prepend => 'crazy_prefix '})
11
+ generator.transmit("tag", "message")
12
+ assert_match /crazy_prefix /, socket[0]
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remote_syslog-gitlab
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Troy Davis
8
+ - Eric Lindvall
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2025-03-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: servolux
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 0.10.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 0.10.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: file-tail
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: eventmachine
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: 0.12.10
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: '1.1'
52
+ type: :runtime
53
+ prerelease: false
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 0.12.10
59
+ - - "<"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ - !ruby/object:Gem::Dependency
63
+ name: eventmachine-tail
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.6.4
69
+ type: :runtime
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 0.6.4
76
+ - !ruby/object:Gem::Dependency
77
+ name: syslog_protocol
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.9.2
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.9.2
90
+ - !ruby/object:Gem::Dependency
91
+ name: em-resolv-replace
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ type: :runtime
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ description: Lightweight daemon to tail one or more log files and transmit UDP syslog
105
+ messages to a remote syslog host (centralized log aggregation). Generates UDP packets
106
+ itself instead of depending on a system syslog daemon, so it doesn't affect system-wide
107
+ logging configuration.
108
+ email:
109
+ - troy@sevenscale.com
110
+ - eric@sevenscale.com
111
+ executables:
112
+ - remote_syslog
113
+ extensions: []
114
+ extra_rdoc_files:
115
+ - README.md
116
+ - LICENSE
117
+ files:
118
+ - Gemfile
119
+ - LICENSE
120
+ - README.md
121
+ - Rakefile
122
+ - bin/remote_syslog
123
+ - examples/com.papertrailapp.remote_syslog.plist
124
+ - examples/log_files.yml.example
125
+ - examples/log_files.yml.example.advanced
126
+ - examples/remote_syslog.init.d
127
+ - examples/remote_syslog.supervisor.conf
128
+ - examples/remote_syslog.upstart.conf
129
+ - lib/remote_syslog.rb
130
+ - lib/remote_syslog/agent.rb
131
+ - lib/remote_syslog/cli.rb
132
+ - lib/remote_syslog/eventmachine_reader.rb
133
+ - lib/remote_syslog/file_tail_reader.rb
134
+ - lib/remote_syslog/glob_watch.rb
135
+ - lib/remote_syslog/message_generator.rb
136
+ - lib/remote_syslog/tcp_endpoint.rb
137
+ - lib/remote_syslog/tls_endpoint.rb
138
+ - lib/remote_syslog/udp_endpoint.rb
139
+ - remote_syslog.gemspec
140
+ - test/unit/message_generator_test.rb
141
+ homepage: http://github.com/papertrail/remote_syslog
142
+ licenses: []
143
+ metadata: {}
144
+ post_install_message:
145
+ rdoc_options:
146
+ - "--charset=UTF-8"
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubygems_version: 3.5.16
161
+ signing_key:
162
+ specification_version: 2
163
+ summary: Monitor plain text log file(s) for new entries and send to remote syslog
164
+ collector
165
+ test_files: []