rack-logstash-writer 1.0.3

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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +35 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +47 -0
  9. data/Rakefile +16 -0
  10. data/examples/rails-project/Gemfile +46 -0
  11. data/examples/rails-project/Gemfile.lock +155 -0
  12. data/examples/rails-project/README.rdoc +28 -0
  13. data/examples/rails-project/Rakefile +6 -0
  14. data/examples/rails-project/app/assets/images/.keep +0 -0
  15. data/examples/rails-project/app/assets/javascripts/application.js +16 -0
  16. data/examples/rails-project/app/assets/stylesheets/application.css +15 -0
  17. data/examples/rails-project/app/controllers/application_controller.rb +5 -0
  18. data/examples/rails-project/app/controllers/concerns/.keep +0 -0
  19. data/examples/rails-project/app/helpers/application_helper.rb +2 -0
  20. data/examples/rails-project/app/mailers/.keep +0 -0
  21. data/examples/rails-project/app/models/.keep +0 -0
  22. data/examples/rails-project/app/models/concerns/.keep +0 -0
  23. data/examples/rails-project/app/views/layouts/application.html.erb +14 -0
  24. data/examples/rails-project/bin/bundle +3 -0
  25. data/examples/rails-project/bin/rails +8 -0
  26. data/examples/rails-project/bin/rake +8 -0
  27. data/examples/rails-project/bin/setup +29 -0
  28. data/examples/rails-project/bin/spring +15 -0
  29. data/examples/rails-project/config/application.rb +26 -0
  30. data/examples/rails-project/config/boot.rb +3 -0
  31. data/examples/rails-project/config/database.yml +25 -0
  32. data/examples/rails-project/config/environment.rb +5 -0
  33. data/examples/rails-project/config/environments/development.rb +41 -0
  34. data/examples/rails-project/config/environments/production.rb +79 -0
  35. data/examples/rails-project/config/environments/test.rb +42 -0
  36. data/examples/rails-project/config/initializers/assets.rb +11 -0
  37. data/examples/rails-project/config/initializers/backtrace_silencers.rb +7 -0
  38. data/examples/rails-project/config/initializers/cookies_serializer.rb +3 -0
  39. data/examples/rails-project/config/initializers/filter_parameter_logging.rb +4 -0
  40. data/examples/rails-project/config/initializers/inflections.rb +16 -0
  41. data/examples/rails-project/config/initializers/mime_types.rb +4 -0
  42. data/examples/rails-project/config/initializers/session_store.rb +3 -0
  43. data/examples/rails-project/config/initializers/wrap_parameters.rb +14 -0
  44. data/examples/rails-project/config/locales/en.yml +23 -0
  45. data/examples/rails-project/config/routes.rb +56 -0
  46. data/examples/rails-project/config/secrets.yml +22 -0
  47. data/examples/rails-project/config.ru +8 -0
  48. data/examples/rails-project/db/development.sqlite3 +0 -0
  49. data/examples/rails-project/db/seeds.rb +7 -0
  50. data/examples/rails-project/lib/assets/.keep +0 -0
  51. data/examples/rails-project/lib/tasks/.keep +0 -0
  52. data/examples/rails-project/log/.keep +0 -0
  53. data/examples/rails-project/log/development.log +78 -0
  54. data/examples/rails-project/public/404.html +67 -0
  55. data/examples/rails-project/public/422.html +67 -0
  56. data/examples/rails-project/public/500.html +66 -0
  57. data/examples/rails-project/public/favicon.ico +0 -0
  58. data/examples/rails-project/public/robots.txt +5 -0
  59. data/examples/rails-project/test/controllers/.keep +0 -0
  60. data/examples/rails-project/test/fixtures/.keep +0 -0
  61. data/examples/rails-project/test/helpers/.keep +0 -0
  62. data/examples/rails-project/test/integration/.keep +0 -0
  63. data/examples/rails-project/test/mailers/.keep +0 -0
  64. data/examples/rails-project/test/models/.keep +0 -0
  65. data/examples/rails-project/test/test_helper.rb +10 -0
  66. data/examples/rails-project/vendor/assets/javascripts/.keep +0 -0
  67. data/examples/rails-project/vendor/assets/stylesheets/.keep +0 -0
  68. data/examples/regular rack file/config.ru +31 -0
  69. data/examples/sinatra-project/Gemfile +7 -0
  70. data/examples/sinatra-project/Gemfile.lock +24 -0
  71. data/examples/sinatra-project/config.ru +10 -0
  72. data/examples/sinatra-project/lib/sinatra.rb +15 -0
  73. data/lib/rack/logstash-writer/version.rb +5 -0
  74. data/lib/rack/logstash-writer.rb +100 -0
  75. data/rack-logstash-writer.gemspec +23 -0
  76. data/test/unit/logstash_writer_tests.rb +47 -0
  77. data/test/units_helper.rb +12 -0
  78. metadata +138 -0
@@ -0,0 +1,31 @@
1
+ puts File.expand_path("../lib" , __FILE__)
2
+ $:.unshift File.expand_path("../lib" , __FILE__)
3
+ require 'rack/logstash-writer'
4
+
5
+ # Example for using this with rack
6
+ class JSONServer
7
+ def call(env)
8
+ [200, {"Content-Type" => "application/json"}, ['{ "message" : "Hello!" }']]
9
+ end
10
+ end
11
+
12
+ class JSONServerError
13
+ def call(env)
14
+ [555, {"Content-Type" => "application/json"}, ['{ "message" : "Goodbye mr error, this is an error for sure." }']]
15
+ end
16
+ end
17
+
18
+ use Rack::LogstashWriter , {url: "file:///home/org/Desktop/logsample", # or another examples "udp://localhost:5228" # "tcp://localhost:5228"
19
+ request_headers: {'head1'=>'head1'},
20
+ response_headers: {'head1'=>'head1'},
21
+ statuses: [*(500..600)] ,
22
+ body_len: 50 }
23
+
24
+ map '/hello.json' do
25
+ run JSONServer.new
26
+ end
27
+
28
+ map '/goodbye.json' do
29
+ run JSONServerError.new
30
+ end
31
+
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "rack-logstash-writer"
4
+ gem 'rake'
5
+ gem 'rack'
6
+ gem 'sinatra'
7
+
@@ -0,0 +1,24 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ remote: http://gems.kontera.com/
4
+ specs:
5
+ rack (1.6.1)
6
+ rack-logstash-writer (0.0.1)
7
+ rake (~> 10.0)
8
+ rack-protection (1.5.3)
9
+ rack
10
+ rake (10.4.2)
11
+ sinatra (1.4.6)
12
+ rack (~> 1.4)
13
+ rack-protection (~> 1.4)
14
+ tilt (>= 1.3, < 3)
15
+ tilt (2.0.1)
16
+
17
+ PLATFORMS
18
+ ruby
19
+
20
+ DEPENDENCIES
21
+ rack
22
+ rack-logstash-writer
23
+ rake
24
+ sinatra
@@ -0,0 +1,10 @@
1
+ require 'rack/logstash-writer'
2
+
3
+ # Rails.root/config.ru
4
+ require ::File.expand_path('../lib/sinatra', __FILE__)
5
+
6
+ # use Rails::Rack::Debugger
7
+ # use Rack::ContentLength
8
+ use Rack::LogstashWriter, {url: "file:///home/org/Desktop/logsample" ,statuses: [*(200..600)], body_len: 0, #response_headers: {'User-agent'=>'ua-nimrod'},
9
+ request_headers: {'User-agent'=>'ua-nimrod'}} #"udp://localhost:5228" # "udp://localhost:5228"
10
+ run Sinatra::Application
@@ -0,0 +1,15 @@
1
+ # myapp.rb
2
+ require 'sinatra'
3
+
4
+ get '/' do
5
+ 'Hello world!'
6
+ end
7
+
8
+ get '/hello/:name' do |n|
9
+ ssdaasdsdwads
10
+ # matches "GET /hello/foo" and "GET /hello/bar"
11
+ # params['name'] is 'foo' or 'bar'
12
+ # n stores params['name']
13
+ "Hello #{n}!"
14
+ end
15
+
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class LogstashWriter
3
+ VERSION = "1.0.3"
4
+ end
5
+ end
@@ -0,0 +1,100 @@
1
+ require 'socket'
2
+ require 'uri'
3
+ require 'json'
4
+
5
+ module Rack
6
+
7
+ class LogstashWriter
8
+
9
+ # Initialize a new Rack adapter, logstash writer
10
+ # @param [Hash] options
11
+ # @option options [String] :url: required, udp and files schemes are also avaliable. no default values.
12
+ # @option options [Hash] :request_headers,optional, parameters to add to the report from the request headers. default nil
13
+ # @option options [Hash] :response_headers, optional, parameters to add to the report from the responce headers. default nil
14
+ # @option options [Fixnum] :body_len, optional, include the first given chars from the body. default 1000
15
+ # @option options [Array] :statuses, optional, send events to log stash only for those statuses. default [*(500..600)]
16
+ def initialize app, options = {} #, statuses = [*(500..600)] , body_len = 1000 , url
17
+ @app = app
18
+ @options = validate defaults.merge options
19
+ @options[:url]= URI(@options[:url])
20
+ end
21
+
22
+ # Call to the app cal and log if the returned status is in the array of return data.
23
+ # @param [Hash] env : the enviroment
24
+ def call env
25
+ began = Time.now
26
+ s, h, b = @app.call env
27
+ b = BodyProxy.new(b) { log(env, s, h, began, b) } if @options[:statuses].include? s.to_i
28
+ [s, h, b]
29
+ end
30
+
31
+ # Return the correct connection by the uri - udp/tcp/file
32
+ private
33
+ def defaults
34
+ { request_headers: nil, response_headers: nil, statuses: [*(500..600)], body_len: 1000 }
35
+ end
36
+
37
+ def validate opt
38
+ opt.tap { raise ":url is required" unless opt[:url] }
39
+ end
40
+
41
+ def device
42
+ @device ||=
43
+ case @options[:url].scheme
44
+ when "file" then
45
+ ::File.new(@options[:url].path,"a").tap {|f| f.sync=true}
46
+ when "udp" then
47
+ UDPSocket.new.tap { |s| s.connect @options[:url].host, @options[:url].port}
48
+ when "tcp" then
49
+ TCPSocket.new @options[:url].host,@options[:url].port
50
+ else
51
+ raise "Unknown scheme #{@options[:url].scheme}"
52
+ end
53
+ end
54
+
55
+ # Log to the device the data
56
+ def log(env, status, response_headers, began_at, body)
57
+ data = {
58
+ :method => env["REQUEST_METHOD"],
59
+ :path => env["PATH_INFO"],
60
+ :query_string => env["QUERY_STRING"],
61
+ :status => status.to_i,
62
+ :duration => (Time.now - began_at),
63
+ :remote_addr => env['REMOTE_ADDR'],
64
+ :request => request_line(env),
65
+ :length => extract_content_length(response_headers),
66
+ :"X-Forwarded-For" => response_headers['X-Forwarded-For']
67
+ }
68
+
69
+ if(body.is_a? String)
70
+ data[:body] = body.join[0..@options[:body_len]]
71
+ elsif body.is_a? BodyProxy
72
+ (body.respond_to?(:body) ? data[:body] = body.body: data[:body] = body)
73
+ data[:body] = data[:body].join[0..@options[:body_len]]
74
+ end
75
+ @options[:request_headers].each { |header, log_key| env_key = "HTTP_#{header.upcase.gsub('-', '_')}" ; data[log_key] = env[env_key] if env[env_key]} if !@options[:request_headers].nil?
76
+ @options[:response_headers].each { |header, log_key| data[log_key] = response_headers[header] if response_headers[header] } if !@options[:response_headers].nil?
77
+
78
+ data[:error_msg] = env["sinatra.error"] if env.has_key?("sinatra.error")
79
+
80
+ event = {'@fields' => data, '@tags' => ['request'], '@timestamp' => ::Time.now.utc, '@version' => 1}
81
+ begin
82
+ device.puts( event.to_json + '\n' )
83
+ rescue Errno::EPIPE, Errno::EINVAL
84
+ @device = nil
85
+ end
86
+ end
87
+
88
+ def request_line env
89
+ line = "#{env["REQUEST_METHOD"]} #{env["SCRIPT_NAME"]}#{env['PATH_INFO']}"
90
+ line << "?#{env["QUERY_STRING"]}" if env["QUERY_STRING"] and ! env["QUERY_STRING"].empty?
91
+ line << " #{env["SERVER_PROTOCOL"]}"
92
+ line
93
+ end
94
+
95
+ def extract_content_length headers
96
+ value = headers[CONTENT_LENGTH] or return '-'
97
+ value.to_s == '0' ? '-' : value
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ $:.unshift File.expand_path('../lib', __FILE__)
3
+
4
+ require 'rack/logstash-writer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rack-logstash-writer"
8
+ spec.version = Rack::LogstashWriter::VERSION
9
+ spec.authors = ["or garfunkel"]
10
+ spec.email = ["or@amobee.com"]
11
+ spec.summary = %q{Rack adapter for sending events to logstash server, from the chosen statuses code.}
12
+ spec.description = %q{Rack adapter for sending events to logstash server, from the chosen statuses code, can send event to file/udp/tcp servers.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "rake", "~> 10.0"
22
+
23
+ end
@@ -0,0 +1,47 @@
1
+ require_relative '../units_helper'
2
+
3
+ module Rack
4
+ class LogstashWriterTests < UnitsHelper
5
+
6
+ class JSONServer
7
+ def call(env)
8
+ [200, {"Content-Type" => "application/json"}, ['{ "message" : "Hello!" }']]
9
+ end
10
+ end
11
+
12
+ class JSONServerError
13
+ def call(env)
14
+ [555, {"Content-Type" => "application/json"}, ['{ "message" : "Goodbye mr error, this is an error for sure." }']]
15
+ end
16
+ end
17
+
18
+
19
+ def test_general_working_no_error
20
+ logstash = LogstashWriter.new JSONServer.new, url: "udp://localhost:8086"
21
+ s,h,b = logstash.call ENV
22
+ assert_equal(s , 200)
23
+ assert_equal(h , {"Content-Type" => "application/json"})
24
+ assert_equal(b , ['{ "message" : "Hello!" }'])
25
+ end
26
+
27
+ def test_udp
28
+ logstash = LogstashWriter.new JSONServerError.new, url:"udp://localhost:8086"
29
+ s, h, b = logstash.call ENV
30
+ assert_equal(s , 555)
31
+ assert_equal(h , {"Content-Type" => "application/json"})
32
+ assert_equal( b.class.to_s ,"Rack::BodyProxy" )
33
+ end
34
+
35
+ def test_file
36
+ begin
37
+ logstash = LogstashWriter.new JSONServerError.new, url:"file://not_existing_file"
38
+ s, h, b = logstash.call ENV
39
+ b.close
40
+ rescue Exception => e
41
+ puts e
42
+ assert_includes(e.to_s , "No such file or directory @ rb_sysopen -")
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,12 @@
1
+ $:.unshift File.expand_path("../../lib" , __FILE__)
2
+ require 'minitest'
3
+ require "minitest/autorun"
4
+ require "minitest/mock"
5
+ require "rack/logstash-writer"
6
+ require 'rack'
7
+
8
+ # TODO - is there a real need for this
9
+ module Rack
10
+ class UnitsHelper < Minitest::Test
11
+ end
12
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-logstash-writer
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - or garfunkel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10.0'
27
+ description: Rack adapter for sending events to logstash server, from the chosen statuses
28
+ code, can send event to file/udp/tcp servers.
29
+ email:
30
+ - or@amobee.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - ".rvmrc"
37
+ - ".travis.yml"
38
+ - Gemfile
39
+ - Gemfile.lock
40
+ - LICENSE.txt
41
+ - README.md
42
+ - Rakefile
43
+ - examples/rails-project/Gemfile
44
+ - examples/rails-project/Gemfile.lock
45
+ - examples/rails-project/README.rdoc
46
+ - examples/rails-project/Rakefile
47
+ - examples/rails-project/app/assets/images/.keep
48
+ - examples/rails-project/app/assets/javascripts/application.js
49
+ - examples/rails-project/app/assets/stylesheets/application.css
50
+ - examples/rails-project/app/controllers/application_controller.rb
51
+ - examples/rails-project/app/controllers/concerns/.keep
52
+ - examples/rails-project/app/helpers/application_helper.rb
53
+ - examples/rails-project/app/mailers/.keep
54
+ - examples/rails-project/app/models/.keep
55
+ - examples/rails-project/app/models/concerns/.keep
56
+ - examples/rails-project/app/views/layouts/application.html.erb
57
+ - examples/rails-project/bin/bundle
58
+ - examples/rails-project/bin/rails
59
+ - examples/rails-project/bin/rake
60
+ - examples/rails-project/bin/setup
61
+ - examples/rails-project/bin/spring
62
+ - examples/rails-project/config.ru
63
+ - examples/rails-project/config/application.rb
64
+ - examples/rails-project/config/boot.rb
65
+ - examples/rails-project/config/database.yml
66
+ - examples/rails-project/config/environment.rb
67
+ - examples/rails-project/config/environments/development.rb
68
+ - examples/rails-project/config/environments/production.rb
69
+ - examples/rails-project/config/environments/test.rb
70
+ - examples/rails-project/config/initializers/assets.rb
71
+ - examples/rails-project/config/initializers/backtrace_silencers.rb
72
+ - examples/rails-project/config/initializers/cookies_serializer.rb
73
+ - examples/rails-project/config/initializers/filter_parameter_logging.rb
74
+ - examples/rails-project/config/initializers/inflections.rb
75
+ - examples/rails-project/config/initializers/mime_types.rb
76
+ - examples/rails-project/config/initializers/session_store.rb
77
+ - examples/rails-project/config/initializers/wrap_parameters.rb
78
+ - examples/rails-project/config/locales/en.yml
79
+ - examples/rails-project/config/routes.rb
80
+ - examples/rails-project/config/secrets.yml
81
+ - examples/rails-project/db/development.sqlite3
82
+ - examples/rails-project/db/seeds.rb
83
+ - examples/rails-project/lib/assets/.keep
84
+ - examples/rails-project/lib/tasks/.keep
85
+ - examples/rails-project/log/.keep
86
+ - examples/rails-project/log/development.log
87
+ - examples/rails-project/public/404.html
88
+ - examples/rails-project/public/422.html
89
+ - examples/rails-project/public/500.html
90
+ - examples/rails-project/public/favicon.ico
91
+ - examples/rails-project/public/robots.txt
92
+ - examples/rails-project/test/controllers/.keep
93
+ - examples/rails-project/test/fixtures/.keep
94
+ - examples/rails-project/test/helpers/.keep
95
+ - examples/rails-project/test/integration/.keep
96
+ - examples/rails-project/test/mailers/.keep
97
+ - examples/rails-project/test/models/.keep
98
+ - examples/rails-project/test/test_helper.rb
99
+ - examples/rails-project/vendor/assets/javascripts/.keep
100
+ - examples/rails-project/vendor/assets/stylesheets/.keep
101
+ - examples/regular rack file/config.ru
102
+ - examples/sinatra-project/Gemfile
103
+ - examples/sinatra-project/Gemfile.lock
104
+ - examples/sinatra-project/config.ru
105
+ - examples/sinatra-project/lib/sinatra.rb
106
+ - lib/rack/logstash-writer.rb
107
+ - lib/rack/logstash-writer/version.rb
108
+ - rack-logstash-writer.gemspec
109
+ - test/unit/logstash_writer_tests.rb
110
+ - test/units_helper.rb
111
+ homepage: ''
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.4.5
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Rack adapter for sending events to logstash server, from the chosen statuses
135
+ code.
136
+ test_files:
137
+ - test/unit/logstash_writer_tests.rb
138
+ - test/units_helper.rb