rack-logstash-writer 1.1.1 → 1.2.0
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 +4 -4
- data/.rvmrc +1 -1
- data/.travis.yml +1 -0
- data/Gemfile.lock +20 -13
- data/LICENSE.txt +1 -1
- data/README.md +23 -10
- data/examples/rails-project/config.ru +11 -2
- data/examples/regular rack file/config.ru +12 -9
- data/examples/sinatra-project/config.ru +8 -3
- data/lib/rack/logstash-writer.rb +138 -54
- data/lib/rack/logstash-writer/version.rb +1 -1
- data/test/unit/logstash_writer_tests.rb +23 -39
- data/test/units_helper.rb +14 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aba065b11c7d708bf89e3be92f03d5feed690783
|
4
|
+
data.tar.gz: 6ad0e76d87d43936de0f1863679edc881151d0d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33f96ac175fd8d9cfb117dff41f96626a552150a22d1928dc08cf258a1a8f83271ad3afc12221e580bd5dafa7aaf952413f9b949f2c0f1643f8b8338d6835757
|
7
|
+
data.tar.gz: b12e45bb92ff0a3b04ca525938b006659cc4fd22bdbb342f68593f23b8484429af7ef96b67398c980fdd72e6dc89e350791ae745e96ae833aafb4427ab2d7f74
|
data/.rvmrc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rvm use ruby
|
1
|
+
rvm use ruby 2.2.2
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,28 +1,32 @@
|
|
1
1
|
GEM
|
2
2
|
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
|
-
builder (3.2.
|
5
|
-
faraday (0.
|
4
|
+
builder (3.2.3)
|
5
|
+
faraday (0.13.1)
|
6
6
|
multipart-post (>= 1.2, < 3)
|
7
|
-
geminabox (0.
|
7
|
+
geminabox (0.13.10)
|
8
8
|
builder
|
9
9
|
faraday
|
10
10
|
httpclient (>= 2.2.7)
|
11
11
|
nesty
|
12
|
+
reentrant_flock
|
12
13
|
sinatra (>= 1.2.7)
|
13
|
-
httpclient (2.
|
14
|
-
minitest (5.
|
14
|
+
httpclient (2.8.3)
|
15
|
+
minitest (5.10.3)
|
15
16
|
multipart-post (2.0.0)
|
17
|
+
mustermann (1.0.1)
|
16
18
|
nesty (1.0.2)
|
17
|
-
rack (
|
18
|
-
rack-protection (
|
19
|
+
rack (2.0.3)
|
20
|
+
rack-protection (2.0.0)
|
19
21
|
rack
|
20
|
-
rake (
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
rake (12.2.1)
|
23
|
+
reentrant_flock (0.1.0)
|
24
|
+
sinatra (2.0.0)
|
25
|
+
mustermann (~> 1.0)
|
26
|
+
rack (~> 2.0)
|
27
|
+
rack-protection (= 2.0.0)
|
28
|
+
tilt (~> 2.0)
|
29
|
+
tilt (2.0.8)
|
26
30
|
|
27
31
|
PLATFORMS
|
28
32
|
java
|
@@ -33,3 +37,6 @@ DEPENDENCIES
|
|
33
37
|
minitest
|
34
38
|
rack
|
35
39
|
rake
|
40
|
+
|
41
|
+
BUNDLED WITH
|
42
|
+
1.16.0
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -27,16 +27,29 @@ Add to the config.ru
|
|
27
27
|
```ruby
|
28
28
|
require 'rack/logstash-writer'
|
29
29
|
|
30
|
-
use Rack::LogstashWriter,{url: "tcp://localhost:5228"} # udp and files schemes are also avaliable.
|
31
|
-
|
32
|
-
use Rack::LogstashWriter , {
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
}
|
30
|
+
use Rack::LogstashWriter, {url: "tcp://localhost:5228"} # udp and files schemes are also avaliable.
|
31
|
+
|
32
|
+
use Rack::LogstashWriter , {
|
33
|
+
# {required} udp and files schemes are also avaliable.
|
34
|
+
url: "file:///home/org/Desktop/logsample",
|
35
|
+
# {optional} [Hash] parameters to add to the report from the request headers.
|
36
|
+
request_headers: {'head1' => 'head1'},
|
37
|
+
# {optional} [Hash] parame0ters to add to the report from the responce headers
|
38
|
+
response_headers: {'head1' => 'head1'},
|
39
|
+
# {optional} [Array<Fixnum>] send events to log stash only for those statuses. default: [*(500..600)]
|
40
|
+
statuses: [*(500..600)],
|
41
|
+
# {optional} [Fixnum] first chars of the body string. default: 1000
|
42
|
+
body_len: 50,
|
43
|
+
# {optional} [Hash] to extract data by regular expressions from the body {Symbol => Regexp}
|
44
|
+
body_regex: {name_to_show: 'regex'},
|
45
|
+
# {optional} [Proc] that gets the rack env as arg and return a Hash that will be merged into the event.
|
46
|
+
proc: -> env { {a_key: env[:a_key]} },
|
47
|
+
# {optional} [Boolean] add [:curl] to the log with *curl* script to mock the request that led to the event; default: false.
|
48
|
+
# aliased as :add_curl_command?
|
49
|
+
add_request_script?: true,
|
50
|
+
# {optional} [Hash] adds opts for altering the curl command generation. see doc of (Rack::LogStashWriter)#gen_curl_by_rack_env
|
51
|
+
curl_opts: {verbose: true, data_proc: proc(&:to_json)} # :to_json is the default behaviour of data processing
|
52
|
+
}
|
40
53
|
|
41
54
|
run Proc.new {[200, {"Content-Type" => "application/json"}, ['{ "message" : "Hello!" }']]}
|
42
55
|
```
|
@@ -3,6 +3,15 @@ require 'rack/logstash-writer'
|
|
3
3
|
# Rails.root/config.ru
|
4
4
|
require ::File.expand_path('../config/environment', __FILE__)
|
5
5
|
|
6
|
-
use Rack::LogstashWriter,
|
7
|
-
|
6
|
+
use Rack::LogstashWriter, {
|
7
|
+
url: "file:///home/org/Desktop/logsample",
|
8
|
+
statuses: [*(100..600)],
|
9
|
+
body_len: 100,
|
10
|
+
response_headers: {'message' => 'This-is-a-message-man'},
|
11
|
+
request_headers: {'User-agent' => 'ua-nimrod'},
|
12
|
+
body_regex: {service_name: 'service_namev:(.*).*[,]?.*}'},
|
13
|
+
proc: -> env { {service: Dir.pwd.split("/").last} },
|
14
|
+
add_curl_command?: true
|
15
|
+
}
|
16
|
+
|
8
17
|
run Rails.application
|
@@ -1,5 +1,5 @@
|
|
1
|
-
puts File.expand_path("../lib"
|
2
|
-
$:.unshift File.expand_path("../lib"
|
1
|
+
puts File.expand_path("../lib", __FILE__)
|
2
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
3
3
|
require 'rack/logstash-writer'
|
4
4
|
|
5
5
|
# Example for using this with rack
|
@@ -15,14 +15,17 @@ class JSONServerError
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
proc {|env| {service: Dir.pwd.split("/").last}}
|
18
|
+
proc { |env| {service: Dir.pwd.split("/").last} }
|
19
19
|
|
20
|
-
use Rack::LogstashWriter
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
use Rack::LogstashWriter, {
|
21
|
+
url: "file:///home/org/Desktop/logsample", # could also be another using protocol, e.g. : "udp://localhost:5228", "tcp://localhost:5228"
|
22
|
+
request_headers: {'head1' => 'head1'},
|
23
|
+
response_headers: {'head1' => 'head1'},
|
24
|
+
statuses: [*(500..600)],
|
25
|
+
body_len: 50,
|
26
|
+
body_regex: {service_name: 'service_namev:(.*).*[,]?.*}'},
|
27
|
+
proc: -> env { {service: Dir.pwd.split("/").last} },
|
28
|
+
add_curl_command?: true
|
26
29
|
}
|
27
30
|
|
28
31
|
map '/hello.json' do
|
@@ -8,9 +8,14 @@ require ::File.expand_path('../lib/sinatra', __FILE__)
|
|
8
8
|
# use Rails::Rack::Debugger
|
9
9
|
# use Rack::ContentLength
|
10
10
|
prc = Proc.new {|env| p env}
|
11
|
-
use Rack::LogstashWriter, {
|
12
|
-
|
13
|
-
|
11
|
+
use Rack::LogstashWriter, {
|
12
|
+
url: "tcp://localhost:5228" ,
|
13
|
+
statuses: [*(200..600)],
|
14
|
+
body_len: 100,
|
15
|
+
response_headers: {'message' => 'This-is-a-message-man'},
|
16
|
+
request_headers: {'User-agent'=>'ua-nimrod'}, # could also be using another protocol, e.g. : "udp://localhost:5228", "file:///home/org/Desktop/logsample"
|
17
|
+
body_regex: {service_name: 'service_namev:(.*).*[,]?.*}' , proc: Proc.new {|env| {service: Dir.pwd.split("/").last}}},
|
18
|
+
add_curl_command?: true
|
14
19
|
}
|
15
20
|
|
16
21
|
run Sinatra::Application
|
data/lib/rack/logstash-writer.rb
CHANGED
@@ -5,112 +5,196 @@ require 'socket'
|
|
5
5
|
|
6
6
|
module Rack
|
7
7
|
class LogstashWriter
|
8
|
+
DEFAULT_OPTIONS = {
|
9
|
+
request_headers: nil,
|
10
|
+
response_headers: nil,
|
11
|
+
statuses: [*(500..600)],
|
12
|
+
body_len: 1000,
|
13
|
+
add_curl_command?: false,
|
14
|
+
add_request_script?: false,
|
15
|
+
curl_opts: {}
|
16
|
+
}
|
17
|
+
CURL_DEFAULT_OPTS = {data_proc: proc(&:to_json), ignored_headers: [], verbose?: true}
|
18
|
+
REQUIRED_OPTIONS = [:url]
|
19
|
+
|
8
20
|
# Initialize a new Rack adapter, logstash writer
|
9
|
-
# @param [
|
10
|
-
# @
|
11
|
-
# @option options [
|
12
|
-
# @option options [Hash] :
|
13
|
-
# @option options [
|
14
|
-
# @option options [
|
15
|
-
# @option options [
|
16
|
-
|
21
|
+
# @param [Proc] app
|
22
|
+
# @param [Hash] options, defaults can be viewed at ::DEFAULT_OPTIONS
|
23
|
+
# @option options [String] :url: required, udp and files schemes are also available. no default values.
|
24
|
+
# @option options [Hash] :request_headers: optional, parameters to add to the report from the request headers. default nil
|
25
|
+
# @option options [Hash] :response_headers: optional, parameters to add to the report from the responce headers. default nil
|
26
|
+
# @option options [Fixnum] :body_len: optional, include the first given chars from the body. default 1000
|
27
|
+
# @option options [Array] :statuses: optional, send events to log stash only for those statuses. default [*(500..600)]
|
28
|
+
# @option options [Proc] :proc: optional, the function will call the proc with the env and call
|
29
|
+
# @option options [Boolean] :add_curl_command?: add [:curl] to the log with *curl* unix command string set to mock the request that led to the log
|
30
|
+
# @option options [Boolean] :add_request_script?: alias for the :curl: @option
|
31
|
+
def initialize app, options = {}
|
32
|
+
validate_options options
|
33
|
+
|
17
34
|
@app = app
|
18
|
-
@options =
|
35
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
19
36
|
@options[:url]= URI(@options[:url])
|
20
37
|
@proc = @options[:proc]
|
21
38
|
end
|
22
39
|
|
23
40
|
# Call to the app cal and log if the returned status is in the array of return data.
|
24
|
-
# @param [Hash] env : the
|
41
|
+
# @param [Hash] env : the environment
|
42
|
+
# @return [Array] [status:Fixnum, headers:Hash, body:Rack::BodyProxy]
|
25
43
|
def call env
|
26
44
|
began = Time.now
|
27
|
-
s, h, b = @app.call
|
28
|
-
b = BodyProxy.new(b) { log(env, s, h, began, b) } if @options[:statuses].include?
|
45
|
+
s, h, b = @app.call(env)
|
46
|
+
b = BodyProxy.new(b) { log(env, s, h, began, b) } if @options[:statuses].include?(s.to_i)
|
29
47
|
[s, h, b]
|
30
48
|
end
|
31
49
|
|
32
50
|
# Return the correct connection by the uri - udp/tcp/file
|
33
51
|
private
|
34
|
-
def defaults
|
35
|
-
{ request_headers: nil, response_headers: nil, statuses: [*(500..600)], body_len: 1000 }
|
36
|
-
end
|
37
52
|
|
38
|
-
def
|
39
|
-
|
53
|
+
def validate_options(options)
|
54
|
+
missing_required_options = REQUIRED_OPTIONS - options.keys
|
55
|
+
raise "#{missing_required_options} options must be given!" unless missing_required_options.empty?
|
40
56
|
end
|
41
57
|
|
58
|
+
# @return [File|UDPSocket|TCPSocket] new instance of socket of file for data writing/sending.
|
59
|
+
# raising an error if url-scheme could not be identified
|
42
60
|
def device
|
43
61
|
@device ||=
|
44
62
|
case @options[:url].scheme
|
45
|
-
when
|
46
|
-
::File.new(@options[:url].path,"a").tap {|f| f.sync=true}
|
47
|
-
when
|
48
|
-
UDPSocket.new.tap { |s| s.connect @options[:url].host, @options[:url].port}
|
49
|
-
when
|
50
|
-
TCPSocket.new @options[:url].host
|
63
|
+
when 'file' then
|
64
|
+
::File.new(@options[:url].path, "a").tap { |f| f.sync = true }
|
65
|
+
when 'udp' then
|
66
|
+
UDPSocket.new.tap { |s| s.connect @options[:url].host, @options[:url].port }
|
67
|
+
when 'tcp' then
|
68
|
+
TCPSocket.new @options[:url].host, @options[:url].port
|
51
69
|
else
|
52
70
|
raise "Unknown scheme #{@options[:url].scheme}"
|
53
71
|
end
|
54
72
|
end
|
55
73
|
|
56
|
-
#
|
57
|
-
|
74
|
+
# @param [Hash] env as given from Rack
|
75
|
+
# @param [Fixnum] status
|
76
|
+
# @param [Hash] response_headers
|
77
|
+
# @param [Time|DateTime|Date] began_at
|
78
|
+
# @param [Object] body of the request
|
79
|
+
# Log the data to the device
|
80
|
+
def log env, status, response_headers, began_at, body
|
58
81
|
data = {
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
67
|
-
:
|
68
|
-
|
82
|
+
method: env['REQUEST_METHOD'],
|
83
|
+
path: env['PATH_INFO'],
|
84
|
+
query_string: env['QUERY_STRING'],
|
85
|
+
host: Socket.gethostname,
|
86
|
+
status: status.to_i,
|
87
|
+
duration: (Time.now - began_at),
|
88
|
+
remote_addr: env['REMOTE_ADDR'],
|
89
|
+
request: request_line(env),
|
90
|
+
:'X-Forwarded-For' => response_headers['X-Forwarded-For']
|
69
91
|
}
|
70
92
|
|
71
93
|
# Added calling for the proc and merge the data if it exists
|
72
|
-
|
73
94
|
if @proc
|
74
95
|
begin
|
75
96
|
new_hash = @proc.call(env)
|
76
|
-
data = data.merge new_hash if new_hash.
|
97
|
+
data = data.merge new_hash if new_hash.is_a?(Hash)
|
77
98
|
rescue Exception => e
|
78
99
|
STDERR.puts "Exception in your proc : #{e.message}."
|
79
100
|
end
|
80
101
|
end
|
81
102
|
|
103
|
+
# add curl if users enables it
|
104
|
+
if @options[:add_curl_command?] || @options[:add_request_script?]
|
105
|
+
data[:curl] = gen_curl_by_rack_env(env, CURL_DEFAULT_OPTS.merge(@options[:curl_opts]))
|
106
|
+
end
|
107
|
+
|
82
108
|
# This just works for all body types (magic?)... see http://www.rubydoc.info/github/rack/rack/Rack/BodyProxy
|
83
|
-
body.each{|x| data[:body] = x[0..@options[:body_len]] }
|
84
|
-
@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?
|
85
|
-
@options[:response_headers].each { |header, log_key| data[log_key] = response_headers[header] if response_headers[header] } if !@options[:response_headers].nil?
|
109
|
+
body.each { |x| data[:body] = x[0..@options[:body_len]] }
|
86
110
|
|
87
|
-
|
111
|
+
unless @options[:request_headers].nil?
|
112
|
+
@options[:request_headers].each do |header, log_key|
|
113
|
+
env_key = "HTTP_#{header.upcase.gsub('-', '_')}"
|
114
|
+
data[log_key] = env[env_key] if env[env_key]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
unless @options[:response_headers].nil?
|
118
|
+
@options[:response_headers].each do |header, log_key|
|
119
|
+
data[log_key] = response_headers[header] if response_headers[header]
|
120
|
+
end
|
121
|
+
end
|
88
122
|
|
123
|
+
data[:error_msg] = env['sinatra.error'] if env.has_key?('sinatra.error')
|
89
124
|
|
125
|
+
unless @options[:body_regex].nil?
|
126
|
+
@options[:body_regex].each do |k, v|
|
127
|
+
data[k] = data[:body].to_s.match(/#{v}/).captures[0].gsub('\\', '').gsub('"', '') rescue data[k] = ''
|
128
|
+
end
|
129
|
+
end
|
90
130
|
|
91
|
-
|
131
|
+
severity = case status
|
132
|
+
when 300..399
|
133
|
+
'WARN'
|
134
|
+
when 400..599
|
135
|
+
'ERROR'
|
136
|
+
else
|
137
|
+
'DEBUG'
|
138
|
+
end
|
139
|
+
data = {severity: severity}.merge(data)
|
92
140
|
|
93
|
-
severity = "DEBUG"
|
94
|
-
case status
|
95
|
-
when 300..399 then severity = "WARN"
|
96
|
-
when 400..599 then severity = "ERROR"
|
97
|
-
end
|
98
|
-
event = {:severity => severity}.merge data
|
99
|
-
# TODO to include this lines
|
100
141
|
begin
|
101
|
-
device.puts
|
142
|
+
device.puts data.to_json
|
102
143
|
rescue Exception => e
|
103
144
|
STDERR.puts "Error : Failed to write log to : #{@options[:url]}, #{e.message}."
|
104
145
|
@device = nil
|
105
146
|
end
|
106
147
|
end
|
107
148
|
|
149
|
+
# @param [Hash] env rack env obj
|
150
|
+
# @return [String] e.g. "METHOD name/path/path?query=query protocol"
|
108
151
|
def request_line env
|
109
|
-
line = "#{env[
|
110
|
-
line << "?#{env[
|
111
|
-
line << " #{env[
|
112
|
-
line
|
152
|
+
line = "#{env['REQUEST_METHOD']} #{env['SCRIPT_NAME']}#{env['PATH_INFO']}"
|
153
|
+
line << "?#{env['QUERY_STRING']}" if env['QUERY_STRING'] && !env['QUERY_STRING'].empty?
|
154
|
+
line << " #{env['SERVER_PROTOCOL']}"
|
113
155
|
end
|
114
156
|
|
157
|
+
# @param [Hash] env as received from Rack
|
158
|
+
# @param [Hash] opts
|
159
|
+
# * @option [Proc] :data_proc: for processing the data prior for inserting it to query (by --data flag)
|
160
|
+
# * @option [Array<String>] :ignored_headers: to prevent inclusion to the query (by --header flag)
|
161
|
+
# * @option [Array<String>] :extra_arguments: string ot args to add to the query
|
162
|
+
# * @option [Boolean] :verbose?: add --verbose switch if true. default: true
|
163
|
+
# @return [String] of curl unix-command that will imitate the request to server/service
|
164
|
+
def gen_curl_by_rack_env env, opts
|
165
|
+
command_acc = ["curl #{url(env)} "]
|
166
|
+
|
167
|
+
command_acc << "--request #{env['REQUEST_METHOD']}"
|
168
|
+
|
169
|
+
# form-data will be processed by the proc sent by the user
|
170
|
+
data = opts[:data_proc].call(env['rack.request.form_hash']) rescue env['rack.request.form_hash']
|
171
|
+
command_acc << "--data #{data.inspect}" if data && !data.empty?
|
172
|
+
|
173
|
+
# add all headers to the query. do not add +ignore_headers+ specified by the user
|
174
|
+
|
175
|
+
env.keys.select { |env_key| env_key.to_s.start_with?('HTTP_') || env_key.to_s.start_with?('CONTENT_') }
|
176
|
+
.each do |env_key|
|
177
|
+
header_name = env_key.to_s.sub(/^HTTP_/i, '').split('_').map(&:capitalize).join('-')
|
178
|
+
next if opts[:ignored_headers].include?(header_name)
|
179
|
+
header_value = env[env_key].inspect[1...-1]
|
180
|
+
command_acc << "--header \"#{header_name}: #{header_value}\""
|
181
|
+
end
|
182
|
+
|
183
|
+
# the curl script is intended for debugging, therefore --verbose switch is added (unless specified by caller)
|
184
|
+
command_acc << '--verbose' if opts[:verbose]
|
185
|
+
|
186
|
+
# let user change the query as they desire
|
187
|
+
command_acc += opts[:extra_arguments] if opts[:extra_arguments]
|
188
|
+
|
189
|
+
|
190
|
+
command_acc.join " \\\n"
|
191
|
+
end
|
192
|
+
|
193
|
+
# @param [Hash] env rack env
|
194
|
+
# @return [String] url-scheme://prefix.name.suffix:port/uri/uri/uri?query=query:query=query
|
195
|
+
def url env
|
196
|
+
url = "#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{env['REQUEST_URI']}"
|
197
|
+
env['QUERY_STRING'] ? url << "?#{env['QUERY_STRING']}" : url
|
198
|
+
end
|
115
199
|
end
|
116
200
|
end
|
@@ -1,47 +1,31 @@
|
|
1
1
|
require_relative '../units_helper'
|
2
2
|
|
3
3
|
module Rack
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
4
|
+
class LogstashWriterTests < UnitsHelper
|
5
|
+
def test_general_working_no_error
|
6
|
+
logstash = LogstashWriter.new JSONServer.new, url: 'udp://localhost:8086'
|
7
|
+
s, h, b = logstash.call ENV
|
8
|
+
assert_equal s, 200
|
9
|
+
assert_equal h, {'Content-Type' => 'application/json'}
|
10
|
+
assert_equal b, ['{ "message" : "Hello!" }']
|
11
|
+
end
|
26
12
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
13
|
+
def test_udp
|
14
|
+
logstash = LogstashWriter.new JSONServerError.new, url: 'udp://localhost:8086'
|
15
|
+
s, h, b = logstash.call ENV
|
16
|
+
assert_equal s, 555
|
17
|
+
assert_equal h, {'Content-Type' => 'application/json'}
|
18
|
+
assert_equal b.class, Rack::BodyProxy
|
19
|
+
end
|
34
20
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
assert_includes(e.to_s , "No such file or directory @ rb_sysopen -")
|
43
|
-
end
|
21
|
+
def test_file
|
22
|
+
begin
|
23
|
+
logstash = LogstashWriter.new JSONServerError.new, url: 'file://not_existing_file'
|
24
|
+
s, h, b = logstash.call ENV
|
25
|
+
b.close
|
26
|
+
rescue => e
|
27
|
+
assert_includes e.to_s, 'No such file or directory @ rb_sysopen -'
|
44
28
|
end
|
45
|
-
|
46
29
|
end
|
30
|
+
end
|
47
31
|
end
|
data/test/units_helper.rb
CHANGED
@@ -1,12 +1,22 @@
|
|
1
1
|
$:.unshift File.expand_path("../../lib" , __FILE__)
|
2
2
|
require 'minitest'
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'minitest/mock'
|
5
|
+
require 'rack/logstash-writer'
|
6
6
|
require 'rack'
|
7
7
|
|
8
|
-
# TODO - is there a real need for this
|
9
8
|
module Rack
|
10
9
|
class UnitsHelper < Minitest::Test
|
10
|
+
class JSONServer
|
11
|
+
def call _env
|
12
|
+
[200, {'Content-Type' => 'application/json'}, ['{ "message" : "Hello!" }']]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class JSONServerError
|
17
|
+
def call _env
|
18
|
+
[555, {'Content-Type' => 'application/json'}, ['{ "message" : "Goodbye mr error, this is an error for sure." }']]
|
19
|
+
end
|
20
|
+
end
|
11
21
|
end
|
12
22
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-logstash-writer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- or garfunkel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -128,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
128
|
version: '0'
|
129
129
|
requirements: []
|
130
130
|
rubyforge_project:
|
131
|
-
rubygems_version: 2.4.
|
131
|
+
rubygems_version: 2.4.6
|
132
132
|
signing_key:
|
133
133
|
specification_version: 4
|
134
134
|
summary: Rack adapter for sending events to logstash server, from the chosen statuses
|