haproxy2rpm 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -2
- data/Rakefile +2 -0
- data/bin/haproxy2rpm +11 -12
- data/haproxy2rpm.gemspec +1 -0
- data/lib/haproxy2rpm/rpm.rb +13 -0
- data/lib/haproxy2rpm/syslog.rb +50 -0
- data/lib/haproxy2rpm/version.rb +1 -1
- data/lib/haproxy2rpm.rb +54 -8
- metadata +16 -3
data/README.md
CHANGED
@@ -4,11 +4,13 @@ such as erlang or node.js based applications
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
+
gem install haproxy2rpm or clone it
|
8
|
+
|
7
9
|
* copy your newrelic.yml file to $HOME/.newrelic/newrelic.yml
|
8
10
|
* or set $NRCONFIG to point to your newrelic.yml file
|
9
11
|
|
10
12
|
## Running it
|
11
|
-
haproxy2rpm /path/to/logfile
|
13
|
+
haproxy2rpm /path/to/logfile or ./bin/haproxy2rpm /path/to/log/file
|
12
14
|
|
13
15
|
## Analyzing it
|
14
16
|
|
@@ -28,5 +30,5 @@ At the moment, it only works with custom views
|
|
28
30
|
## Roadmap
|
29
31
|
|
30
32
|
* daemonize option
|
31
|
-
* syslog (udp maybe tcp) server with https://github.com/
|
33
|
+
* syslog (udp maybe tcp) server with https://github.com/loggly/logporter and then point HaProxy to that port. Why touch the disk if we don't have to?
|
32
34
|
* Figure out how to report rpms and response times so that they show up inside the newrelic application view and not only as a custom metric
|
data/Rakefile
CHANGED
data/bin/haproxy2rpm
CHANGED
@@ -16,14 +16,17 @@ Basic Command Line Usage:
|
|
16
16
|
Coniguration for newrelic is read from #{NEW_RELIC_CONFIG_PATH}
|
17
17
|
HELP
|
18
18
|
|
19
|
-
options = { :daemonize => false, :version => false }
|
19
|
+
options = { :daemonize => false, :version => false, :syslog => false }
|
20
20
|
|
21
21
|
opts = OptionParser.new do |opts|
|
22
22
|
opts.banner = help
|
23
23
|
opts.on("-D", "--daemonize", "Daemonize") do
|
24
24
|
options[:daemonize] = true
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
|
+
opts.on("-s", "--syslog", "Run syslog server") do
|
28
|
+
options[:syslog] = true
|
29
|
+
end
|
27
30
|
opts.on("-v", "--version", "Print the version number and exit") do
|
28
31
|
options[:version] = true
|
29
32
|
end
|
@@ -40,7 +43,7 @@ if(options[:version])
|
|
40
43
|
exit(0)
|
41
44
|
end
|
42
45
|
|
43
|
-
unless File.exists?(log_file)
|
46
|
+
unless options[:syslog] || File.exists?(log_file)
|
44
47
|
puts 'please proivde a valid path to a haproxy log file'
|
45
48
|
puts ''
|
46
49
|
puts help
|
@@ -52,12 +55,8 @@ unless File.exists?(NEW_RELIC_CONFIG_PATH)
|
|
52
55
|
exit(1)
|
53
56
|
end
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
exit(0)
|
61
|
-
}
|
62
|
-
Haproxy2Rpm.run(log_file)
|
63
|
-
end
|
58
|
+
trap("SIGINT") {
|
59
|
+
Haproxy2Rpm.stop
|
60
|
+
exit(0)
|
61
|
+
}
|
62
|
+
Haproxy2Rpm.run(log_file, options)
|
data/haproxy2rpm.gemspec
CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.description = "Sending haproxy logs to new relic rpm"
|
13
13
|
s.add_dependency "newrelic_rpm"
|
14
14
|
s.add_dependency "eventmachine-tail"
|
15
|
+
s.add_development_dependency "rake"
|
15
16
|
s.add_development_dependency "shoulda-context"
|
16
17
|
|
17
18
|
s.files = `git ls-files`.split("\n")
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Haproxy2Rpm
|
2
|
+
class Rpm
|
3
|
+
def initialize()
|
4
|
+
NewRelic::Agent.manual_start
|
5
|
+
@stats_engine = NewRelic::Agent.agent.stats_engine
|
6
|
+
end
|
7
|
+
|
8
|
+
def send(line)
|
9
|
+
request = LineParser.new(line)
|
10
|
+
@stats_engine.get_stats('Custom/HAProxy/response_times',false).record_data_point(request.tr)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Taken from
|
2
|
+
# https://raw.github.com/jordansissel/experiments/master/ruby/eventmachine-speed/basic.rb
|
3
|
+
module Haproxy2Rpm
|
4
|
+
class SyslogHandler < EventMachine::Connection
|
5
|
+
def initialize
|
6
|
+
@rpm = Rpm.new
|
7
|
+
@count = 0
|
8
|
+
@buffer = BufferedTokenizer.new
|
9
|
+
@start = Time.now
|
10
|
+
|
11
|
+
# The syslog parsing stuff here taken from the 'logporter' gem.
|
12
|
+
pri = "(?:<(?<pri>[0-9]{1,3})>)?"
|
13
|
+
month = "(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"
|
14
|
+
day = "(?: [1-9]|[12][0-9]|3[01])"
|
15
|
+
hour = "(?:[01][0-9]|2[0-4])"
|
16
|
+
minute = "(?:[0-5][0-9])"
|
17
|
+
second = "(?:[0-5][0-9])"
|
18
|
+
time = [hour, minute, second].join(":")
|
19
|
+
timestamp = "(?<timestamp>#{month} #{day} #{time})"
|
20
|
+
hostname = "(?<hostname>[A-Za-z0-9_.:]+)"
|
21
|
+
header = timestamp + " " + hostname
|
22
|
+
message = "(?<message>[ -~]+)" # ascii 32 to 126
|
23
|
+
re = "^#{pri}#{header} #{message}$"
|
24
|
+
|
25
|
+
if RUBY_VERSION =~ /^1\.8/
|
26
|
+
# Ruby 1.8 doesn't support named captures
|
27
|
+
# replace (?<foo> with (
|
28
|
+
re = re.gsub(/\(\?<[^>]+>/, "(")
|
29
|
+
end
|
30
|
+
|
31
|
+
@syslog3164_re = Regexp.new(re)
|
32
|
+
end # def initialize
|
33
|
+
|
34
|
+
def receive_data(data)
|
35
|
+
# In jruby+netty, we probaby should use the DelimiterBasedFrameDecoder
|
36
|
+
# But for the sake of simplicity, we'll use EM's BufferedTokenizer for
|
37
|
+
# all implementations.
|
38
|
+
@buffer.extract(data).each do |line|
|
39
|
+
receive_line(line.chomp)
|
40
|
+
end
|
41
|
+
end # def receive_event
|
42
|
+
|
43
|
+
def receive_line(line)
|
44
|
+
@count += 1
|
45
|
+
# Just try matching, don't need to do anything with it for this benchmark.
|
46
|
+
m = @syslog3164_re.match(line)
|
47
|
+
@rpm.send(m[:message])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/haproxy2rpm/version.rb
CHANGED
data/lib/haproxy2rpm.rb
CHANGED
@@ -6,15 +6,20 @@ require "eventmachine-tail"
|
|
6
6
|
require "haproxy2rpm/version"
|
7
7
|
require "haproxy2rpm/file_parser"
|
8
8
|
require "haproxy2rpm/line_parser"
|
9
|
+
require "haproxy2rpm/syslog"
|
10
|
+
require "haproxy2rpm/rpm"
|
9
11
|
|
10
12
|
module Haproxy2Rpm
|
11
|
-
def self.run(log_file)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
def self.run(log_file, options)
|
14
|
+
@rpm = Rpm.new
|
15
|
+
if(options[:daemonize])
|
16
|
+
puts 'daemonizing'
|
17
|
+
run_daemonized(log_file, options)
|
18
|
+
else
|
19
|
+
if(options[:syslog])
|
20
|
+
run_syslog_server(options)
|
21
|
+
else
|
22
|
+
default_run(log_file, options)
|
18
23
|
end
|
19
24
|
end
|
20
25
|
end
|
@@ -23,4 +28,45 @@ module Haproxy2Rpm
|
|
23
28
|
puts 'stopping new relic agent'
|
24
29
|
NewRelic::Agent.shutdown
|
25
30
|
end
|
26
|
-
|
31
|
+
|
32
|
+
def self.run_syslog_server(options)
|
33
|
+
NewRelic::Agent.manual_start
|
34
|
+
EventMachine::run do
|
35
|
+
EventMachine.start_server("0.0.0.0", 3333, SyslogHandler)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.default_run(log_file,options)
|
40
|
+
EventMachine.run do
|
41
|
+
EventMachine::file_tail(log_file) do |filetail, line|
|
42
|
+
@rpm.send(line)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.run_daemonized(log_file, options)
|
48
|
+
Signal.trap('HUP') {}
|
49
|
+
|
50
|
+
pid = fork do
|
51
|
+
begin
|
52
|
+
if(options[:syslog])
|
53
|
+
run_syslog_server(options)
|
54
|
+
else
|
55
|
+
default_run(log_file, options)
|
56
|
+
end
|
57
|
+
rescue => e
|
58
|
+
puts e.message
|
59
|
+
puts e.backtrace.join("\n")
|
60
|
+
abort "There was a fatal system error while starting haproxy2rpm"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
if options[:pid]
|
65
|
+
File.open(options[:pid], 'w') { |f| f.write pid }
|
66
|
+
end
|
67
|
+
|
68
|
+
::Process.detach pid
|
69
|
+
|
70
|
+
exit
|
71
|
+
end
|
72
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: haproxy2rpm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Patrick Huesler
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-07-
|
13
|
+
date: 2011-07-09 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
type: :runtime
|
37
37
|
version_requirements: *id002
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
|
-
name:
|
39
|
+
name: rake
|
40
40
|
prerelease: false
|
41
41
|
requirement: &id003 !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
@@ -46,6 +46,17 @@ dependencies:
|
|
46
46
|
version: "0"
|
47
47
|
type: :development
|
48
48
|
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: shoulda-context
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
49
60
|
description: Sending haproxy logs to new relic rpm
|
50
61
|
email:
|
51
62
|
- patrick.huesler@gmail.com
|
@@ -65,6 +76,8 @@ files:
|
|
65
76
|
- lib/haproxy2rpm.rb
|
66
77
|
- lib/haproxy2rpm/file_parser.rb
|
67
78
|
- lib/haproxy2rpm/line_parser.rb
|
79
|
+
- lib/haproxy2rpm/rpm.rb
|
80
|
+
- lib/haproxy2rpm/syslog.rb
|
68
81
|
- lib/haproxy2rpm/version.rb
|
69
82
|
- test/fixtures/haproxy.log
|
70
83
|
- test/haproxy2pm_test.rb
|