haproxy2rpm 0.0.10 → 0.1.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.
- data/CHANGELOG.md +6 -0
- data/README.md +5 -0
- data/examples/connect_middleware.js +35 -0
- data/examples/connect_middleware_config.rb +72 -0
- data/lib/haproxy2rpm/line_parser.rb +5 -11
- data/lib/haproxy2rpm/syslog.rb +36 -3
- data/lib/haproxy2rpm/version.rb +1 -1
- data/test/syslog_test.rb +33 -0
- data/test/test_helper.rb +19 -1
- metadata +100 -62
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -27,6 +27,10 @@ Tell haproxy to log to syslog. e.g:
|
|
27
27
|
|
28
28
|
Check the examples folder
|
29
29
|
|
30
|
+
## Node.js support
|
31
|
+
|
32
|
+
Check the examples folder
|
33
|
+
|
30
34
|
## Supported RPM features
|
31
35
|
|
32
36
|
* Response times in application server
|
@@ -46,6 +50,7 @@ Tested in production
|
|
46
50
|
|
47
51
|
Passing manual integration test with test logs
|
48
52
|
|
53
|
+
* mri-1.9.3
|
49
54
|
* mri-1.9.2-p180
|
50
55
|
* ree-1.8.7-2011.03
|
51
56
|
* mri-1.8.7-p33
|
@@ -0,0 +1,35 @@
|
|
1
|
+
/**
|
2
|
+
* Profile the duration of a request.
|
3
|
+
*
|
4
|
+
* Example Output:
|
5
|
+
*
|
6
|
+
* GET / 200 2
|
7
|
+
*
|
8
|
+
*
|
9
|
+
* Example usage:
|
10
|
+
*
|
11
|
+
* npm install ain2
|
12
|
+
*
|
13
|
+
* var SysLogger = require('ain2');
|
14
|
+
* var profiler = require('./connect_middleware.js');
|
15
|
+
* app.use(profiler(new SysLogger({ tag : "newrelic", facility : 'local0' })));
|
16
|
+
*
|
17
|
+
*
|
18
|
+
* @api public
|
19
|
+
*/
|
20
|
+
module.exports = function profiler(_logger){
|
21
|
+
return function(req, res, next){
|
22
|
+
var end = res.end
|
23
|
+
, start = new Date()
|
24
|
+
, logger = _logger || console;
|
25
|
+
|
26
|
+
// proxy res.end()
|
27
|
+
res.end = function(data, encoding){
|
28
|
+
res.end = end;
|
29
|
+
res.end(data, encoding);
|
30
|
+
logger.log(req.method, req.url, res.statusCode, ((new Date) - start));
|
31
|
+
};
|
32
|
+
|
33
|
+
next();
|
34
|
+
}
|
35
|
+
};
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#
|
2
|
+
# Expected format: Method Uri Status Time
|
3
|
+
#
|
4
|
+
# GET /test 200 2
|
5
|
+
#
|
6
|
+
class NodeJsLineParser
|
7
|
+
|
8
|
+
def initialize(line)
|
9
|
+
@parts = line.split("\s")
|
10
|
+
end
|
11
|
+
|
12
|
+
def response_time
|
13
|
+
@response_time ||= @parts[3].to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def status_code
|
18
|
+
@status_code ||= @parts[2].to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
def http_method
|
22
|
+
@http_method ||= @parts[0]
|
23
|
+
end
|
24
|
+
|
25
|
+
def uri
|
26
|
+
@uri ||= URI.parse(@parts[1])
|
27
|
+
end
|
28
|
+
|
29
|
+
def http_path
|
30
|
+
uri.path
|
31
|
+
end
|
32
|
+
|
33
|
+
def http_query
|
34
|
+
uri.query
|
35
|
+
end
|
36
|
+
|
37
|
+
def is_error?
|
38
|
+
status_code >= 500
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
config.message_parser = lambda do |line|
|
44
|
+
NodeJsLineParser.new(line)
|
45
|
+
end
|
46
|
+
|
47
|
+
config.request_recorder = lambda do |request|
|
48
|
+
rpm_number_unit = 1000.0
|
49
|
+
params = {
|
50
|
+
'metric' => "Controller#{route_for(request.http_path)}"
|
51
|
+
}
|
52
|
+
|
53
|
+
if request.is_error?
|
54
|
+
params['is_error'] = true
|
55
|
+
params['error_message'] = "#{request.uri} : Status code #{request.status_code}"
|
56
|
+
end
|
57
|
+
|
58
|
+
record_transaction(request.response_time / rpm_number_unit, params)
|
59
|
+
Haproxy2Rpm.logger.debug "RECORDING (transaction) #{request.http_path}: #{params.inspect}"
|
60
|
+
end
|
61
|
+
|
62
|
+
config.routes = [
|
63
|
+
{
|
64
|
+
:pattern => %r{^/$},
|
65
|
+
:target => '/index'
|
66
|
+
},
|
67
|
+
{
|
68
|
+
:pattern => %r{(\.[a-zA-Z_]{2,4})$},
|
69
|
+
:target => '/static'
|
70
|
+
}
|
71
|
+
]
|
72
|
+
|
@@ -2,13 +2,7 @@ module Haproxy2Rpm
|
|
2
2
|
class LineParser
|
3
3
|
|
4
4
|
def initialize(line)
|
5
|
-
@
|
6
|
-
|
7
|
-
if @line.match "haproxy"
|
8
|
-
@parts = @line.split("haproxy")[1].split("\s")
|
9
|
-
else
|
10
|
-
@parts = @line.split("\s")
|
11
|
-
end
|
5
|
+
@parts = line.split("\s")
|
12
6
|
end
|
13
7
|
|
14
8
|
def tq
|
@@ -32,16 +26,16 @@ module Haproxy2Rpm
|
|
32
26
|
end
|
33
27
|
|
34
28
|
def status_code
|
35
|
-
@status_code ||= @parts[
|
29
|
+
@status_code ||= @parts[5].to_i
|
36
30
|
end
|
37
31
|
|
38
32
|
# we need to chop \"
|
39
33
|
def http_method
|
40
|
-
@http_method ||= @parts[
|
34
|
+
@http_method ||= @parts[12][1..-1]
|
41
35
|
end
|
42
36
|
|
43
37
|
def uri
|
44
|
-
@uri ||= URI.parse(@parts[
|
38
|
+
@uri ||= URI.parse(@parts[13])
|
45
39
|
end
|
46
40
|
|
47
41
|
def http_path
|
@@ -59,7 +53,7 @@ module Haproxy2Rpm
|
|
59
53
|
private
|
60
54
|
|
61
55
|
def response_times
|
62
|
-
@response_times ||= @parts[
|
56
|
+
@response_times ||= @parts[4].split("/")
|
63
57
|
end
|
64
58
|
end
|
65
59
|
end
|
data/lib/haproxy2rpm/syslog.rb
CHANGED
@@ -1,12 +1,45 @@
|
|
1
1
|
# Taken from
|
2
2
|
# https://raw.github.com/jordansissel/experiments/master/ruby/eventmachine-speed/basic.rb
|
3
|
+
#
|
3
4
|
module Haproxy2Rpm
|
4
5
|
class SyslogHandler < EventMachine::Connection
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
# The syslog parsing stuff here taken from the 'logporter' gem.
|
9
|
+
pri = "(?:<(?<pri>[0-9]{1,3})>)?"
|
10
|
+
month = "(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"
|
11
|
+
day = "(?: [1-9]|[12][0-9]|3[01])"
|
12
|
+
hour = "(?:[01][0-9]|2[0-4])"
|
13
|
+
minute = "(?:[0-5][0-9])"
|
14
|
+
second = "(?:[0-5][0-9])"
|
15
|
+
time = [hour, minute, second].join(":")
|
16
|
+
timestamp = "(?<timestamp>#{month} #{day} #{time})"
|
17
|
+
hostname = "(?<hostname>[A-Za-z0-9_.:]+)"
|
18
|
+
header = timestamp + " " + hostname
|
19
|
+
tag = '(?<tag>[a-zA-Z_\-\/\.0-9\[\]]+)'
|
20
|
+
message = "(?<message>[ -~]+)" # ascii 32 to 126
|
21
|
+
re = "^#{pri}#{header} #{tag}:\s*#{message}"
|
22
|
+
|
23
|
+
if RUBY_VERSION =~ /^1\.8/
|
24
|
+
# Ruby 1.8 doesn't support named captures
|
25
|
+
# replace (?<foo> with (
|
26
|
+
re = re.gsub(/\(\?<[^>]+>/, "(")
|
27
|
+
end
|
28
|
+
|
29
|
+
@syslog3164_re = Regexp.new(re)
|
30
|
+
end
|
31
|
+
|
5
32
|
def receive_data(data)
|
6
|
-
|
7
|
-
|
8
|
-
|
33
|
+
match = parse_data(data)
|
34
|
+
puts match.inspect
|
35
|
+
message = match ? match[5] : ""
|
36
|
+
Haproxy2Rpm.logger.debug "RECEIVED (syslog): #{data}"
|
9
37
|
Haproxy2Rpm.rpm.process_and_send(message)
|
10
38
|
end
|
39
|
+
|
40
|
+
def parse_data(data)
|
41
|
+
@syslog3164_re.match(data)
|
42
|
+
end
|
43
|
+
|
11
44
|
end
|
12
45
|
end
|
data/lib/haproxy2rpm/version.rb
CHANGED
data/test/syslog_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
$LOAD_PATH.unshift( File.dirname(__FILE__) )
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
FIXTURE_SYSLOG_MESSAGE = "<12>Jan 3 16:18:58 rechenschieber.local nodejs[36180]: message"
|
6
|
+
|
7
|
+
class RpmTest < Test::Unit::TestCase
|
8
|
+
context 'regex maching' do
|
9
|
+
setup do
|
10
|
+
@match = Haproxy2Rpm::SyslogHandler.new(self).parse_data(FIXTURE_SYSLOG_MESSAGE)
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'match the priority' do
|
14
|
+
assert_equal '12', @match[1]
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'match timestamp' do
|
18
|
+
assert_equal "Jan 3 16:18:58", @match[2]
|
19
|
+
end
|
20
|
+
|
21
|
+
should 'match the hostname' do
|
22
|
+
assert_equal "rechenschieber.local", @match[3]
|
23
|
+
end
|
24
|
+
|
25
|
+
should 'match the tag name' do
|
26
|
+
assert_equal 'nodejs[36180]', @match[4]
|
27
|
+
end
|
28
|
+
|
29
|
+
should 'match the message' do
|
30
|
+
assert_equal 'message', @match[5]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -17,7 +17,7 @@ class DummyLogger
|
|
17
17
|
end
|
18
18
|
Haproxy2Rpm.logger = DummyLogger.new
|
19
19
|
|
20
|
-
def
|
20
|
+
def syslog_entry(options = {})
|
21
21
|
defaults = {
|
22
22
|
:tq => 6559,
|
23
23
|
:tw => 100,
|
@@ -34,3 +34,21 @@ def log_entry(options = {})
|
|
34
34
|
Aug 1 15:28:03 ip-10-58-122-30.eu-west-1.compute.internal haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 #{defaults[:tq]}/#{defaults[:tw]}/#{defaults[:tc]}/#{defaults[:tr]}/#{defaults[:tt]} #{defaults[:status_code]} 243 - - ---- 1/3/5 0/0 "#{defaults[:http_method]} #{defaults[:http_path]}#{defaults[:http_query] ? "?#{defaults[:http_query]}" : ''} HTTP/1.0"
|
35
35
|
LOG_LINE
|
36
36
|
end
|
37
|
+
|
38
|
+
def log_entry(options = {})
|
39
|
+
defaults = {
|
40
|
+
:tq => 6559,
|
41
|
+
:tw => 100,
|
42
|
+
:tc => 7,
|
43
|
+
:tr => 147,
|
44
|
+
:tt => 6723,
|
45
|
+
:status_code => 200,
|
46
|
+
:http_path => '/',
|
47
|
+
:http_method => 'GET',
|
48
|
+
:http_query => 'example_param=test',
|
49
|
+
}
|
50
|
+
defaults.merge!(options)
|
51
|
+
log_line = <<LOG_LINE
|
52
|
+
127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 #{defaults[:tq]}/#{defaults[:tw]}/#{defaults[:tc]}/#{defaults[:tr]}/#{defaults[:tt]} #{defaults[:status_code]} 243 - - ---- 1/3/5 0/0 "#{defaults[:http_method]} #{defaults[:http_path]}#{defaults[:http_query] ? "?#{defaults[:http_query]}" : ''} HTTP/1.0"
|
53
|
+
LOG_LINE
|
54
|
+
end
|
metadata
CHANGED
@@ -1,81 +1,105 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: haproxy2rpm
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Patrick Huesler
|
9
14
|
- Martin Rehfeld
|
10
15
|
autorequire:
|
11
16
|
bindir: bin
|
12
17
|
cert_chain: []
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
|
19
|
+
date: 2012-01-03 00:00:00 +01:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
16
23
|
name: newrelic_rpm
|
17
|
-
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
18
26
|
none: false
|
19
|
-
requirements:
|
20
|
-
- -
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
23
34
|
type: :runtime
|
24
|
-
|
25
|
-
|
26
|
-
- !ruby/object:Gem::Dependency
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
27
37
|
name: eventmachine-tail
|
28
|
-
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
29
40
|
none: false
|
30
|
-
requirements:
|
31
|
-
- -
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
34
48
|
type: :runtime
|
35
|
-
|
36
|
-
|
37
|
-
- !ruby/object:Gem::Dependency
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
38
51
|
name: rake
|
39
|
-
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
40
54
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
45
62
|
type: :development
|
46
|
-
|
47
|
-
|
48
|
-
- !ruby/object:Gem::Dependency
|
63
|
+
version_requirements: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
49
65
|
name: shoulda-context
|
50
|
-
|
66
|
+
prerelease: false
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
51
68
|
none: false
|
52
|
-
requirements:
|
53
|
-
- -
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
56
76
|
type: :development
|
57
|
-
|
58
|
-
|
59
|
-
- !ruby/object:Gem::Dependency
|
77
|
+
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
60
79
|
name: mocha
|
61
|
-
|
80
|
+
prerelease: false
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
62
82
|
none: false
|
63
|
-
requirements:
|
64
|
-
- -
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
67
90
|
type: :development
|
68
|
-
|
69
|
-
version_requirements: *70241929467720
|
91
|
+
version_requirements: *id005
|
70
92
|
description: Sending haproxy logs to new relic rpm
|
71
|
-
email:
|
93
|
+
email:
|
72
94
|
- patrick.huesler@wooga.com
|
73
95
|
- martin.rehfeld@wooga.com
|
74
|
-
executables:
|
96
|
+
executables:
|
75
97
|
- haproxy2rpm
|
76
98
|
extensions: []
|
99
|
+
|
77
100
|
extra_rdoc_files: []
|
78
|
-
|
101
|
+
|
102
|
+
files:
|
79
103
|
- .gitignore
|
80
104
|
- .travis.yml
|
81
105
|
- CHANGELOG.md
|
@@ -85,6 +109,8 @@ files:
|
|
85
109
|
- Research.md
|
86
110
|
- bin/haproxy2rpm
|
87
111
|
- config/newrelic.yml.example
|
112
|
+
- examples/connect_middleware.js
|
113
|
+
- examples/connect_middleware_config.rb
|
88
114
|
- examples/haproxy2rpm.monitrc
|
89
115
|
- examples/routes.rb
|
90
116
|
- examples/simple_config.rb
|
@@ -98,33 +124,45 @@ files:
|
|
98
124
|
- test/fixtures/config.rb
|
99
125
|
- test/haproxy2pm_test.rb
|
100
126
|
- test/rpm_test.rb
|
127
|
+
- test/syslog_test.rb
|
101
128
|
- test/test_helper.rb
|
129
|
+
has_rdoc: true
|
102
130
|
homepage: https://github.com/wooga/haproxy2rpm
|
103
131
|
licenses: []
|
132
|
+
|
104
133
|
post_install_message:
|
105
134
|
rdoc_options: []
|
106
|
-
|
135
|
+
|
136
|
+
require_paths:
|
107
137
|
- lib
|
108
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
139
|
none: false
|
110
|
-
requirements:
|
111
|
-
- -
|
112
|
-
- !ruby/object:Gem::Version
|
113
|
-
|
114
|
-
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
hash: 3
|
144
|
+
segments:
|
145
|
+
- 0
|
146
|
+
version: "0"
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
148
|
none: false
|
116
|
-
requirements:
|
117
|
-
- -
|
118
|
-
- !ruby/object:Gem::Version
|
119
|
-
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
hash: 3
|
153
|
+
segments:
|
154
|
+
- 0
|
155
|
+
version: "0"
|
120
156
|
requirements: []
|
157
|
+
|
121
158
|
rubyforge_project:
|
122
|
-
rubygems_version: 1.
|
159
|
+
rubygems_version: 1.6.2
|
123
160
|
signing_key:
|
124
161
|
specification_version: 3
|
125
162
|
summary: Sending haproxy logs to new relic rpm
|
126
|
-
test_files:
|
163
|
+
test_files:
|
127
164
|
- test/fixtures/config.rb
|
128
165
|
- test/haproxy2pm_test.rb
|
129
166
|
- test/rpm_test.rb
|
167
|
+
- test/syslog_test.rb
|
130
168
|
- test/test_helper.rb
|