├── .DS_Store ├── .travis ├── Gemfile ├── Gemfile.lock ├── Guardfile ├── LICENSE ├── README ├── Rakefile ├── bin └── syslog-shipper ├── features └── client.feature ├── lib ├── syslog_shipper.rb └── syslog_shipper │ ├── client.rb │ └── tls_wrapper.rb ├── spec ├── client_spec.rb └── spec_helper.rb ├── syslog-shipper.gemspec └── test_certs ├── ca.crt ├── server.crt ├── server.csr └── server.key /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordansissel/syslog-shipper/54d8dac261051c75e63d704eff8e61a9b125482d/.DS_Store -------------------------------------------------------------------------------- /.travis: -------------------------------------------------------------------------------- 1 | rvm: 2 | - 1.8.7 # (current default) 3 | - 1.9.2 4 | - 1.9.3 5 | - ruby-head 6 | - ree 7 | - jruby 8 | - rbx-2.0 9 | 10 | notifications: 11 | email: 12 | - neil.matatall@gmail.com -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "jruby-openssl", :platform => :jruby 4 | 5 | group :development, :test do 6 | gem 'rake' 7 | gem 'guard' 8 | gem 'guard-test' 9 | gem 'guard-rspec' 10 | gem 'rspec' 11 | gem 'guard-cucumber' 12 | gem 'cucumber' 13 | gem 'aruba' 14 | gem 'eventmachine' 15 | gem 'eventmachine-tail' 16 | 17 | if RUBY_PLATFORM.downcase.include?("darwin") 18 | gem "rb-fsevent" 19 | gem "growl" 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | aruba (0.4.9) 5 | childprocess (>= 0.2.3) 6 | cucumber (>= 1.1.1) 7 | ffi (= 1.0.11) 8 | rspec (>= 2.7.0) 9 | builder (3.0.0) 10 | childprocess (0.2.3) 11 | ffi (~> 1.0.6) 12 | cucumber (1.1.4) 13 | builder (>= 2.1.2) 14 | diff-lcs (>= 1.1.2) 15 | gherkin (~> 2.7.1) 16 | json (>= 1.4.6) 17 | term-ansicolor (>= 1.0.6) 18 | diff-lcs (1.1.3) 19 | eventmachine (0.12.10) 20 | eventmachine-tail (0.6.3) 21 | eventmachine 22 | ffi (1.0.11) 23 | gherkin (2.7.1) 24 | json (>= 1.4.6) 25 | growl (1.0.3) 26 | guard (0.9.1) 27 | ffi (>= 0.5.0) 28 | thor (~> 0.14.6) 29 | guard-cucumber (0.7.4) 30 | cucumber (>= 0.10) 31 | guard (>= 0.8.3) 32 | guard-rspec (0.5.9) 33 | guard (>= 0.8.4) 34 | guard-test (0.4.3) 35 | guard (>= 0.4) 36 | test-unit (~> 2.2) 37 | json (1.6.3) 38 | rake (0.9.2.2) 39 | rb-fsevent (0.4.3.1) 40 | rspec (2.7.0) 41 | rspec-core (~> 2.7.0) 42 | rspec-expectations (~> 2.7.0) 43 | rspec-mocks (~> 2.7.0) 44 | rspec-core (2.7.1) 45 | rspec-expectations (2.7.0) 46 | diff-lcs (~> 1.1.2) 47 | rspec-mocks (2.7.0) 48 | term-ansicolor (1.0.7) 49 | test-unit (2.4.3) 50 | thor (0.14.6) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | aruba 57 | cucumber 58 | eventmachine 59 | eventmachine-tail 60 | growl 61 | guard 62 | guard-cucumber 63 | guard-rspec 64 | guard-test 65 | jruby-openssl 66 | rake 67 | rb-fsevent 68 | rspec 69 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | guard :test do 2 | watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" } 3 | watch(%r{^test/.+_test\.rb$}) 4 | watch('test/test_helper.rb') { "test" } 5 | end 6 | 7 | guard 'rspec', :version => 2, :cli => "--color --format nested" do 8 | watch(%r{^spec/.+_spec\.rb$}) 9 | watch(%r{^lib/syslog_shipper/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } 10 | watch('spec/spec_helper.rb') { "spec" } 11 | end 12 | 13 | guard 'cucumber', :all_after_pass => false, :cli => "--no-profile --color --format pretty --strict" do 14 | watch(%r{^features/.+\.feature$}) 15 | watch(%r{^features/support/.+$}) { 'features' } 16 | watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' } 17 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This software is licensed under the BSD license as here: 2 | http://www.opensource.org/licenses/bsd-license.php 3 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Ship logs to a syslog server 2 | ---------------------------- 3 | 4 | Usage: bin/syslog-shipper [options] -s HOST:PORT [path_or_glob2] [...] 5 | If a path begins with '+' each line is sent unmodified to the syslog server. 6 | Otherwise, this tool will prefix each line read from the file with a syslog 7 | header. 8 | 9 | For example: syslog-shipper -s somehost:514 +/var/log/messages /var/log/apache2/access.log -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "rake" 2 | require "rake/testtask" 3 | require "rspec/core/rake_task" 4 | require "cucumber/rake/task" 5 | require "syslog_shipper" 6 | require "benchmark" 7 | require "tmpdir" 8 | 9 | task :default => [:test, :spec, :cukes] 10 | 11 | Rake::TestTask.new(:test) do |t| 12 | t.libs << "lib" 13 | t.libs << "test" 14 | t.test_files = FileList['test/*_test.rb'] 15 | t.verbose = true 16 | end 17 | 18 | RSpec::Core::RakeTask.new(:spec) do |t| 19 | t.fail_on_error = false 20 | t.verbose = true 21 | end 22 | 23 | Cucumber::Rake::Task.new(:cukes) do |t| 24 | t.cucumber_opts = %w{--format pretty} 25 | end -------------------------------------------------------------------------------- /bin/syslog-shipper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "rubygems" 4 | require "optparse" 5 | require File.expand_path('../../lib/syslog_shipper', __FILE__) 6 | 7 | def main(args) 8 | globcheck_interval = 5 9 | exclude_patterns = [] 10 | hostarg = nil 11 | verbose = false 12 | 13 | opts = OptionParser.new do |opts| 14 | opts.banner = [ 15 | "Usage: #{$0} [options] -s HOST:PORT [path_or_glob2] [...]", 16 | " If a path begins with '+' each line is sent unmodified to the syslog server.", 17 | " Otherwise, this tool will prefix each line read from the file with a syslog", 18 | " header. ", 19 | "", 20 | " For example: #{$0} -s somehost:514 +/var/log/messages /var/log/apache2/access.log", 21 | ].join("\n") 22 | 23 | opts.on("-i SECONDS", "--check-interval SECONDS", 24 | "How frequently, in seconds, to check the glob patterns" \ 25 | "for new files") do |x| 26 | globcheck_interval = x.to_f 27 | end # -i SECONDS 28 | 29 | opts.on("-x EXCLUDE", "--exclude EXCLUDE", 30 | "A pattern to ignore. Wildcard/globs accepted." \ 31 | " Can be specified multiple times") do |pattern| 32 | exclude_patterns << pattern_to_regexp(pattern) 33 | end 34 | 35 | opts.on("-s HOST:PORT", "--server HOST:PORT", 36 | "What syslog server to ship to (uses TCP)") do |arg| 37 | hostarg = arg 38 | end 39 | 40 | opts.on("-v", "--verbose", "verbose (outputs each log line as seen)") do |arg| 41 | verbose = true 42 | end 43 | 44 | opts.on("-c CERT_PATH", "--ca-cert CERT_PATH", "Certificate authority PEM file to use") do |arg| 45 | SyslogShipper::Client.ca_cert = arg 46 | end 47 | end # OptionParser 48 | 49 | opts.parse!(args) 50 | 51 | if args.length == 0 or hostarg == nil 52 | puts opts.banner 53 | return 1 54 | end 55 | 56 | EventMachine.run do 57 | Signal.trap("INT") do 58 | EventMachine.schedule do 59 | $stderr.puts "Got SIGINT" 60 | exit 128 + (Signal.list["INT"]) 61 | end 62 | end 63 | 64 | host, port = hostarg.split(":") 65 | port = 514 if port == nil 66 | 67 | connection = EventMachine::connect(host, port, SyslogShipper::TlsWrapper) 68 | 69 | args.each do |path| 70 | if path.start_with?("+") 71 | raw = true 72 | path = path[1..-1] 73 | else 74 | raw = false 75 | end 76 | EventMachine::FileGlobWatchTail.new(path, SyslogShipper::Client, 77 | interval = globcheck_interval, 78 | exclude = exclude_patterns, 79 | start_pos = -1, 80 | connection = connection, 81 | raw = raw, 82 | verbose = verbose 83 | ) 84 | end # args.each 85 | end # EventMachine.run 86 | end # def main 87 | 88 | exit(main(ARGV)) 89 | 90 | private 91 | 92 | def pattern_to_regexp(pattern) 93 | pattern.gsub!(".", "\\.") # fix literal . 94 | pattern.gsub!("*", ".+") # * becomes .+ 95 | pattern.gsub!("?", ".") # ? becomes . 96 | return Regexp.new(pattern) 97 | end # def pattern_to_regexp 98 | -------------------------------------------------------------------------------- /features/client.feature: -------------------------------------------------------------------------------- 1 | Feature: Sends log data securely 2 | 3 | Scenario: When I connect to an invalid host 4 | Given I have an invalid TLS endpoint 5 | When I connect to that endpoint 6 | Then the connection should fail due peer verification failure 7 | 8 | Scenario: When I connect to a valid host 9 | Given I have a valid TLS endpoint 10 | When I connect to that endpoint 11 | Then the connection should fail due peer verification failure -------------------------------------------------------------------------------- /lib/syslog_shipper.rb: -------------------------------------------------------------------------------- 1 | require "eventmachine" 2 | require "eventmachine-tail" 3 | require File.expand_path('../syslog_shipper/client.rb', __FILE__) 4 | require File.expand_path('../syslog_shipper/tls_wrapper.rb', __FILE__) 5 | 6 | module SyslogShipper; end 7 | -------------------------------------------------------------------------------- /lib/syslog_shipper/client.rb: -------------------------------------------------------------------------------- 1 | require "socket" 2 | 3 | module SyslogShipper 4 | class Client < EventMachine::FileTail 5 | class << self 6 | attr_accessor :ca_cert 7 | end 8 | 9 | def initialize(path, startpos=-1, connection=nil, raw=false, verbose=false) 10 | super(path, startpos) 11 | @buffer = BufferedTokenizer.new 12 | @hostname = Socket.gethostname 13 | @connection = connection 14 | @raw = raw 15 | @verbose = verbose 16 | end 17 | 18 | def receive_data(data) 19 | @buffer.extract(data).each do |line| 20 | line = if @raw 21 | "#{line}\n" 22 | else 23 | "#{Time.now.strftime("%b %d %H:%M:%S")} #{@hostname} #{path}: #{line}\n" 24 | end 25 | 26 | print line if @verbose 27 | send_data(line) 28 | end 29 | end 30 | 31 | private 32 | 33 | def send_data line 34 | @connection.send_data line 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/syslog_shipper/tls_wrapper.rb: -------------------------------------------------------------------------------- 1 | require 'openssl' 2 | 3 | module SyslogShipper::TlsWrapper 4 | def post_init 5 | start_tls(:verify_peer => true) 6 | end 7 | 8 | def connection_completed 9 | 10 | end 11 | 12 | def ssl_verify_peer cert 13 | ca_cert = OpenSSL::X509::Certificate.new File.read(SyslogShipper::Client.ca_cert) 14 | server_cert = OpenSSL::X509::Certificate.new cert 15 | server_cert.verify ca_cert.public_key 16 | end 17 | 18 | def ssl_handshake_completed 19 | $server_handshake_completed = true 20 | end 21 | 22 | def unbind 23 | 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/client_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe SyslogShipper::Client do 4 | describe '#receive_data' do 5 | before(:each) do 6 | 7 | end 8 | 9 | context "sending data" do 10 | it "sends over TLS" 11 | end 12 | end 13 | end -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'syslog_shipper' -------------------------------------------------------------------------------- /syslog-shipper.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |spec| 2 | spec.files = %w( README.md LICENSE EXAMPLES.md History.txt ) 3 | spec.files += Dir.glob("lib/**/*") 4 | spec.files += Dir.glob("bin/**/*") 5 | spec.files += Dir.glob("test/**/*") 6 | spec.files += Dir.glob("spec/**/*") 7 | spec.bindir = "bin" 8 | spec.executables = %w{syslog-shipper} 9 | 10 | rev = Time.now.strftime("%Y%m%d%H%M%S") 11 | spec.name = "syslog-shipper" 12 | spec.version = "1.0.#{rev}" 13 | spec.summary = "syslog-shipper - a tool for streaming logs from files to a remote syslog server" 14 | spec.description = "Ship logs from files to a remote syslog server over TCP" 15 | 16 | spec.author = "Jordan Sissel" 17 | spec.email = "jordan@loggly.com" 18 | spec.homepage = "https://github.com/jordansissel/syslog-shipper" 19 | spec.add_dependency "eventmachine-tail" 20 | end 21 | 22 | -------------------------------------------------------------------------------- /test_certs/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | 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 32 | PPxE/0jf3vU+sYbjGy6jzEi++kxNWixu/g== 33 | -----END CERTIFICATE----- 34 | -------------------------------------------------------------------------------- /test_certs/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIE/jCCAuYCAQEwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV 3 | BAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 4 | ZDAeFw0xMTEyMjgwMjMzMTNaFw0xMjEyMjcwMjMzMTNaMEUxCzAJBgNVBAYTAkFV 5 | MRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRz 6 | IFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC8rz2Kqoy0 7 | DwQfsUXQgDqNC4TTU1aRPzmNl7x1K50ryQtTHsN6XcZ2camF66OM3zTnNBm/qcFL 8 | DXuopuDU/8nAgb7T7yO6vvhFg7g89dnt0C2sRHvcrIh12Vl75QrTlmYiiDirHl21 9 | G5LZ4HOsfSY2YswQoQXHEjYcAXv2goKwSaNP1us0ft8Qd1rVSOxGSh/+SDsRh+Z4 10 | syG2lSzGS+6CYq1cUXAbgdRGBLy51w7SX2BQtM9ZFBTgzcEGxRMtMJxtD7JV+RWf 11 | fD+s8DSWIZtLS6RPwkS9MwG/QB2WC7Mm8Ff6eGmfxU4M3Q3gLA0cFLzq/c3OlQXN 12 | lHdsRrF5sBL6iwmQmZJWv0yj3/rC/WOa0wUHJ9t/FBwLbaVL6V8mND7/DJ9Mok0n 13 | nKc9d8h1I+vHeNSY4WBSzlPvEKxEdTmeeL4tbcnxUF+vQ0CB++7EUW7sWU2X+Bxb 14 | SlsFOF+fJUEgTi/Dt0aLVLPwAXJswVd7vJeHilRbvbgtcZjHGh+5PGGjYwvvlV11 15 | wiPsyLpVYyguIff8s5lVC77NwCrtBl5+XHuuB3evNn0UZM7i9IATIp91kmFRZcp3 16 | T/LSm2hfn5uXw0bPZHj5Ig7ko1gRCSGsXI1pwm42fi3fkHMzub2DfPYvOttkE+tD 17 | QqCf465sL2GdJ0XtGR6LAwe36ZbJK2TvxQIDAQABMA0GCSqGSIb3DQEBBQUAA4IC 18 | AQC4TjY3ESxJQJNoCBs8ufhpvrADzNpXl2ANECYsq9FgNY4/kzDxHLzg6s7mE/PR 19 | k5uI+U2rvYZOva+h/QTvP8XlpAG+Z4pycrq7ppsv5G8tSrJt+SiSYbIHWDGEzbyG 20 | jbIIitLXXQo3rouA4XIFeX/2r2UD2OaGX4tzNsytPgvyInxB2/jOvomQXNjpS56R 21 | pN7dJGrRYMl0K05rN/wIz8YT2HQOcmoBbIEgIXwvD8Aad2CBpZaKHdf33usPQZwE 22 | Z9IJ0Yq63s63a3vZQWJXHWngFZrfnUcfDOjsAuiZkpuXI1RxGpTBqk0v73vdSAcJ 23 | wWFjk2eZWCpjkF3Hus7zBD9TQqEzhONdVz9p0SHXojudYoLP/BxENmf9xIPsrfEa 24 | hW+LTaPhHnGPxDJRReO4tuEJ3qk0j5tGs9oqnCyW0JInJnFfXyKSO7roSrsp6IDn 25 | jx9jtNRoHlZLlwZlffdZlh7KiwgFepdeLUX5JZ73dIHk4Qt8Do1RCibqB6CzKV3b 26 | 6ZgrZSFvbvS9oKkGvycxtNrqqnn3ZSCDtd4QBUoRsIZ6IsknNOF8yx+SRnHxTucY 27 | V4O/RMeusezuBWhrHzEpTUtjekQbrbEyV8uKNzw1xFu88aLxWLQNU616xDHT530Y 28 | Bc+8hFqF0q1fB4GpiOcvNPX2LFflfiv4iHfe4bHB/3Q4hQ== 29 | -----END CERTIFICATE----- 30 | -------------------------------------------------------------------------------- /test_certs/server.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIEijCCAnICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx 3 | ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCAiIwDQYJKoZIhvcN 4 | AQEBBQADggIPADCCAgoCggIBALyvPYqqjLQPBB+xRdCAOo0LhNNTVpE/OY2XvHUr 5 | nSvJC1Mew3pdxnZxqYXro4zfNOc0Gb+pwUsNe6im4NT/ycCBvtPvI7q++EWDuDz1 6 | 2e3QLaxEe9ysiHXZWXvlCtOWZiKIOKseXbUbktngc6x9JjZizBChBccSNhwBe/aC 7 | grBJo0/W6zR+3xB3WtVI7EZKH/5IOxGH5nizIbaVLMZL7oJirVxRcBuB1EYEvLnX 8 | DtJfYFC0z1kUFODNwQbFEy0wnG0PslX5FZ98P6zwNJYhm0tLpE/CRL0zAb9AHZYL 9 | sybwV/p4aZ/FTgzdDeAsDRwUvOr9zc6VBc2Ud2xGsXmwEvqLCZCZkla/TKPf+sL9 10 | Y5rTBQcn238UHAttpUvpXyY0Pv8Mn0yiTSecpz13yHUj68d41JjhYFLOU+8QrER1 11 | OZ54vi1tyfFQX69DQIH77sRRbuxZTZf4HFtKWwU4X58lQSBOL8O3RotUs/ABcmzB 12 | V3u8l4eKVFu9uC1xmMcaH7k8YaNjC++VXXXCI+zIulVjKC4h9/yzmVULvs3AKu0G 13 | Xn5ce64Hd682fRRkzuL0gBMin3WSYVFlyndP8tKbaF+fm5fDRs9kePkiDuSjWBEJ 14 | IaxcjWnCbjZ+Ld+QczO5vYN89i8622QT60NCoJ/jrmwvYZ0nRe0ZHosDB7fplskr 15 | ZO/FAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAgEAaIvEGDgkjVUxfL9A9FGl5eFq 16 | OPzaJyPhfylZm83Ha8jakDJ9U1dpSNMqlM5u40w4Tzc5QWNnBBpoiV5XReRhSAIz 17 | WiBCUUZBVnRlz3MV1j4ZstiMS2eRzS1ODzWPTVciTT1EsAi5PMoalbAVCvCmANIu 18 | jAuc8e+nf3oHIION84nJ9HfXaDL4ZKKzk1IkuBafdDqhjYtizSKzOtPuoM0qDSd9 19 | xybyZpYXPA4w18HZcm4QC0FfybFXI7VAQykP07NfjNY0a4BbzySHsfALNgMp08kN 20 | ib32H/LHyQYHoNPtaDMmjL8+UcktKdTsw6fQO3v7MtloyO9s+kCcScx1TJOtfTuT 21 | NYw9gfEYDVaPvdGJTh9ezXMMPMxPoGowf2g5dUkIf0hreiKVL1czk8eDqssDjAPB 22 | RxArzTTjxmg/ogwGJJ8SwTHOEojJ3aHyMtqPisVrYJwaFqECAA1Ubn0ZgvxAP09n 23 | lLRN4dnB1qW7Nsh/igDKk6Md/nrknFYoqzlmuFd1V8AC+YdAepVCTGx5yhB/G5dT 24 | nkmV5oJzOfZCCy+FJw18qUjhB1XClX9PuAd4gPtgVzEIMVIhb8RLleI418xzilr/ 25 | 8aVr6jIAM8Hdfe9DNP5NvoPEMYHnBmI3zySwG05rOMHYwHt7Ixr2lC8evO4z3wJE 26 | elsyMVWsixYwlahxg0A= 27 | -----END CERTIFICATE REQUEST----- 28 | -------------------------------------------------------------------------------- /test_certs/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,4CE5438A2B27C951 4 | 5 | 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 54 | -----END RSA PRIVATE KEY----- 55 | --------------------------------------------------------------------------------