haproxy2rpm 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ log/*
6
+ config/newrelic.yml
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in haproxy2rpm.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Push haproxy logs to newrelic rpm
2
+ This is useful for languages where newrelic does not provide an agent,
3
+ such as erlang or node.js based applications
4
+
5
+ ## Installation
6
+
7
+ * copy your newrelic.yml file to $HOME/.newrelic/newrelic.yml
8
+ * or set $NRCONFIG to point to your newrelic.yml file
9
+
10
+ ## Running it
11
+ haproxy2rpm /path/to/logfile
12
+
13
+ ## Analyzing it
14
+
15
+ At the moment, it only works with custom views
16
+
17
+ <verbatim>
18
+ <h3>Charts</h3>
19
+ <table width='100%'>
20
+ <tr>
21
+ <td>line_chart {% line_chart value:'average_value' title:'Test' metric:'Custom/HAProxy/response_times' %}</td>
22
+ </tr>
23
+
24
+ </table>
25
+ </verbatim/>
26
+
27
+
28
+ ## Roadmap
29
+
30
+ * daemonize option
31
+ * syslog (udp maybe tcp) server with https://github.com/melito/em-syslog and then point HaProxy to that port. Why touch the disk if we don't have to?
32
+ * 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 ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rake/testtask'
4
+
5
+ namespace :test do
6
+ Rake::TestTask.new(:units) do |t|
7
+ t.libs << "test"
8
+ t.test_files = FileList['test/*_test.rb']
9
+
10
+ t.verbose = true
11
+ end
12
+ end
data/bin/haproxy2rpm ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require 'rubygems'
6
+ require 'optparse'
7
+
8
+ NEW_RELIC_CONFIG_PATH = File.join(ENV['HOME'], '.newrelic', 'newrelic.yml')
9
+
10
+ help = <<HELP
11
+ haproxy2rpm
12
+
13
+ Basic Command Line Usage:
14
+ haproxy2rpm <haproxy log file to parse>
15
+
16
+ Coniguration for newrelic is read from #{NEW_RELIC_CONFIG_PATH}
17
+ HELP
18
+
19
+ options = { :daemonize => false, :version => false }
20
+
21
+ opts = OptionParser.new do |opts|
22
+ opts.banner = help
23
+ opts.on("-D", "--daemonize", "Daemonize") do
24
+ options[:daemonize] = true
25
+ end
26
+
27
+ opts.on("-v", "--version", "Print the version number and exit") do
28
+ options[:version] = true
29
+ end
30
+ end
31
+
32
+ opts.parse!
33
+
34
+ require 'haproxy2rpm'
35
+
36
+ log_file = ARGV[0] || ''
37
+
38
+ if(options[:version])
39
+ puts "Haproxy2Rpm version: #{Haproxy2Rpm::VERSION}"
40
+ exit(0)
41
+ end
42
+
43
+ unless File.exists?(log_file)
44
+ puts 'please proivde a valid path to a haproxy log file'
45
+ puts ''
46
+ puts help
47
+ exit(1)
48
+ end
49
+
50
+ unless File.exists?(NEW_RELIC_CONFIG_PATH)
51
+ puts "please copy your newrelic agent configuration to #{NEW_RELIC_CONFIG_PATH}"
52
+ exit(1)
53
+ end
54
+
55
+ if(options[:daemonize])
56
+ puts 'dameon mode not implemented yet'
57
+ else
58
+ trap("SIGINT") {
59
+ Haproxy2Rpm.stop
60
+ exit(0)
61
+ }
62
+ Haproxy2Rpm.run(log_file)
63
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "haproxy2rpm/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "haproxy2rpm"
7
+ s.version = Haproxy2Rpm::VERSION
8
+ s.authors = ["Patrick Huesler"]
9
+ s.email = ["patrick.huesler@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = "Sending haproxy logs to new relic rpm"
12
+ s.description = "Sending haproxy logs to new relic rpm"
13
+ s.add_dependency "newrelic_rpm"
14
+ s.add_dependency "eventmachine-tail"
15
+ s.add_development_dependency "shoulda-context"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,24 @@
1
+ module Haproxy2Rpm
2
+ class FileParser
3
+
4
+ include Enumerable
5
+
6
+ def initialize(path)
7
+ @lines = File.open(path){|f| f.readlines}
8
+ @records = []
9
+ @lines.each do |line|
10
+ @records << LineParser.new(line)
11
+ end
12
+ end
13
+
14
+ def [](element)
15
+ @records
16
+ end
17
+
18
+ def each &block
19
+ @records.each do |record|
20
+ yield record
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,48 @@
1
+ module Haproxy2Rpm
2
+ class LineParser
3
+
4
+ def initialize(line)
5
+ @line = line
6
+ @parts = line.split("\s")
7
+ end
8
+
9
+ def tq
10
+ @tw ||= response_times[0].to_i
11
+ end
12
+
13
+ def tw
14
+ @tw ||= response_times[1].to_i
15
+ end
16
+
17
+ def tc
18
+ @tc ||= response_times[2].to_i
19
+ end
20
+
21
+ def tr
22
+ @tr ||= response_times[3].to_i
23
+ end
24
+
25
+ def tt
26
+ @tt ||= response_times[4].to_i
27
+ end
28
+
29
+ def status_code
30
+ @status_code ||= @parts[6].to_i
31
+ end
32
+
33
+ # we need to chop \"
34
+ def http_method
35
+ @http_method ||= @parts[13][1..-1]
36
+ end
37
+
38
+ def uri
39
+ @uri ||= @parts[14]
40
+ end
41
+
42
+ private
43
+
44
+ def response_times
45
+ @response_times ||= @parts[5].split("/")
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,3 @@
1
+ module Haproxy2Rpm
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
2
+
3
+ require "newrelic_rpm"
4
+ require "eventmachine"
5
+ require "eventmachine-tail"
6
+ require "haproxy2rpm/version"
7
+ require "haproxy2rpm/file_parser"
8
+ require "haproxy2rpm/line_parser"
9
+
10
+ module Haproxy2Rpm
11
+ def self.run(log_file)
12
+ NewRelic::Agent.manual_start
13
+ stats_engine = NewRelic::Agent.agent.stats_engine
14
+ EventMachine.run do
15
+ EventMachine::file_tail(log_file) do |filetail, line|
16
+ request = LineParser.new(line)
17
+ stats_engine.get_stats('Custom/HAProxy/response_times',false).record_data_point(request.tr)
18
+ end
19
+ end
20
+ end
21
+
22
+ def self.stop
23
+ puts 'stopping new relic agent'
24
+ NewRelic::Agent.shutdown
25
+ end
26
+ end
@@ -0,0 +1 @@
1
+ haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/0/7/147/6723 200 243 - - ---- 1/3/5 0/0 "HEAD / HTTP/1.0"
@@ -0,0 +1,46 @@
1
+ $LOAD_PATH.unshift( File.dirname(__FILE__) )
2
+
3
+ require 'test_helper'
4
+
5
+ class Haproxy2RpmTest < Test::Unit::TestCase
6
+ context 'parsing of haproxy files' do
7
+ setup do
8
+ @line = File.open(File.join(File.dirname(__FILE__), 'fixtures', 'haproxy.log')){|f| f.readlines}.first
9
+ @result = Haproxy2Rpm::LineParser.new(@line)
10
+ end
11
+
12
+ should 'parse the Tq (total time in ms spent waiting for client)' do
13
+ assert_equal 6559, @result.tq
14
+ end
15
+
16
+ # this is the time waiting in the global queue
17
+ should 'parse the Tw (total time in ms spent waiting in queue)' do
18
+ assert_equal 0, @result.tw
19
+ end
20
+
21
+ should 'parse the Tc (total time in ms spent waiting for the connection to the final server' do
22
+ assert_equal 7, @result.tc
23
+ end
24
+
25
+ # this is the response time of your application server
26
+ should 'parse the Tr (total time in ms spent waiting for server to send full HTTP response)' do
27
+ assert_equal 147, @result.tr
28
+ end
29
+
30
+ should 'parse the Tt (total time in ms spent between accept and close' do
31
+ assert_equal 6723, @result.tt
32
+ end
33
+
34
+ should 'parse the status code' do
35
+ assert_equal 200, @result.status_code
36
+ end
37
+
38
+ should 'parse the http method' do
39
+ assert_equal 'HEAD', @result.http_method
40
+ end
41
+
42
+ should 'parse the uri' do
43
+ assert_equal '/', @result.uri
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ $LOAD_PATH.unshift( File.join( File.dirname(__FILE__), "..", "lib") )
2
+
3
+ require 'test/unit'
4
+ require 'shoulda-context'
5
+ require 'haproxy2rpm'
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haproxy2rpm
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Patrick Huesler
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-08 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: newrelic_rpm
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: eventmachine-tail
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: shoulda-context
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id003
49
+ description: Sending haproxy logs to new relic rpm
50
+ email:
51
+ - patrick.huesler@gmail.com
52
+ executables:
53
+ - haproxy2rpm
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - .gitignore
60
+ - Gemfile
61
+ - README.md
62
+ - Rakefile
63
+ - bin/haproxy2rpm
64
+ - haproxy2rpm.gemspec
65
+ - lib/haproxy2rpm.rb
66
+ - lib/haproxy2rpm/file_parser.rb
67
+ - lib/haproxy2rpm/line_parser.rb
68
+ - lib/haproxy2rpm/version.rb
69
+ - test/fixtures/haproxy.log
70
+ - test/haproxy2pm_test.rb
71
+ - test/test_helper.rb
72
+ has_rdoc: true
73
+ homepage: ""
74
+ licenses: []
75
+
76
+ post_install_message:
77
+ rdoc_options: []
78
+
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: "0"
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: "0"
93
+ requirements: []
94
+
95
+ rubyforge_project:
96
+ rubygems_version: 1.6.2
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Sending haproxy logs to new relic rpm
100
+ test_files:
101
+ - test/fixtures/haproxy.log
102
+ - test/haproxy2pm_test.rb
103
+ - test/test_helper.rb