haproxy2rpm 0.0.7 → 0.0.8
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 +2 -1
- data/CHANGELOG.md +12 -0
- data/README.md +7 -0
- data/bin/haproxy2rpm +4 -0
- data/config/newrelic.yml.example +227 -0
- data/examples/haproxy2rpm.monitrc +4 -0
- data/examples/routes.rb +4 -0
- data/examples/simple_config.rb +40 -0
- data/haproxy2rpm.gemspec +1 -0
- data/lib/haproxy2rpm/rpm.rb +79 -14
- data/lib/haproxy2rpm/syslog.rb +1 -5
- data/lib/haproxy2rpm/version.rb +1 -1
- data/lib/haproxy2rpm.rb +5 -1
- data/test/fixtures/config.rb +17 -0
- data/test/haproxy2pm_test.rb +0 -18
- data/test/rpm_test.rb +97 -0
- data/test/test_helper.rb +31 -0
- metadata +26 -4
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## v 0.0.8
|
4
|
+
|
5
|
+
* config file similar to unicorn.rb
|
6
|
+
* support for custom parsers
|
7
|
+
* support for custom recorders
|
8
|
+
* simple router
|
9
|
+
* improved test suite
|
10
|
+
|
11
|
+
### Known issues
|
12
|
+
|
13
|
+
* daemonize mode is still broken
|
14
|
+
|
3
15
|
## v 0.0.7
|
4
16
|
|
5
17
|
* support for pid file in normal mode (not daemonized)
|
data/README.md
CHANGED
@@ -21,6 +21,11 @@ Tell haproxy to log to syslog. e.g:
|
|
21
21
|
haproxy2rpm /path/to/logfile
|
22
22
|
haproxy2rpm --syslog
|
23
23
|
haproxy2rpm --syslog --daemonize
|
24
|
+
haproxy2rpm --syslog -c /path/to/config/file.rb
|
25
|
+
|
26
|
+
## Configuration
|
27
|
+
|
28
|
+
Check the examples folder
|
24
29
|
|
25
30
|
## Supported RPM features
|
26
31
|
|
@@ -38,3 +43,5 @@ Tell haproxy to log to syslog. e.g:
|
|
38
43
|
## Roadmap
|
39
44
|
|
40
45
|
* Working daemonized mode
|
46
|
+
* remove haproxy dependency and make it a more generic rpm recorder that
|
47
|
+
works over syslog and log files. This would allow to send custom messages to rpm by just sending log lines through syslog. The haproxy part would be more of a strategy. That means we need to make it easyly extendible without forking or creating a new gem
|
data/bin/haproxy2rpm
CHANGED
@@ -17,6 +17,10 @@ options = {
|
|
17
17
|
}
|
18
18
|
|
19
19
|
opts = OptionParser.new do |opts|
|
20
|
+
opts.on("-cFILE", "--config-file FILE", "Path to config file") do |file|
|
21
|
+
options[:config_file] = file
|
22
|
+
end
|
23
|
+
|
20
24
|
opts.on("-d", "--daemonize", "Daemonize") do
|
21
25
|
options[:daemonize] = true
|
22
26
|
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
#
|
2
|
+
# This file configures the New Relic Agent. New Relic monitors
|
3
|
+
# Ruby, Java, .NET, PHP, and Python applications with deep visibility and low overhead.
|
4
|
+
# For more information, visit www.newrelic.com.
|
5
|
+
#
|
6
|
+
# Generated July 17, 2011
|
7
|
+
#
|
8
|
+
# This configuration file is custom generated for wooga GmbH_1
|
9
|
+
|
10
|
+
# Here are the settings that are common to all environments:
|
11
|
+
common: &default_settings
|
12
|
+
# ============================== LICENSE KEY ===============================
|
13
|
+
|
14
|
+
# You must specify the license key associated with your New Relic
|
15
|
+
# account. This key binds your Agent's data to your account in the
|
16
|
+
# New Relic service.
|
17
|
+
license_key: 'INSERT YOUR LICENSE KEY HERE'
|
18
|
+
|
19
|
+
# Agent Enabled (Ruby/Rails Only)
|
20
|
+
# Use this setting to force the agent to run or not run.
|
21
|
+
# Default is 'auto' which means the agent will install and run only
|
22
|
+
# if a valid dispatcher such as Mongrel is running. This prevents
|
23
|
+
# it from running with Rake or the console. Set to false to
|
24
|
+
# completely turn the agent off regardless of the other settings.
|
25
|
+
# Valid values are true, false and auto.
|
26
|
+
# agent_enabled: auto
|
27
|
+
|
28
|
+
# Application Name
|
29
|
+
# Set this to be the name of your application as you'd like it show
|
30
|
+
# up in New Relic. New Relic will then auto-map instances of your application
|
31
|
+
# into a New Relic "application" on your home dashboard page. If you want
|
32
|
+
# to map this instance into multiple apps, like "AJAX Requests" and
|
33
|
+
# "All UI" then specify a semicolon-separated list of up to three
|
34
|
+
# distinct names. If you comment this out, it defaults to the
|
35
|
+
# capitalized RAILS_ENV (i.e., Production, Staging, etc)
|
36
|
+
app_name: haproxy2rpm
|
37
|
+
|
38
|
+
# When "true", the agent collects performance data about your
|
39
|
+
# application and reports this data to the New Relic service at
|
40
|
+
# newrelic.com. This global switch is normally overridden for each
|
41
|
+
# environment below. (formerly called 'enabled')
|
42
|
+
monitor_mode: true
|
43
|
+
|
44
|
+
# Developer mode should be off in every environment but
|
45
|
+
# development as it has very high overhead in memory.
|
46
|
+
developer_mode: false
|
47
|
+
|
48
|
+
# The newrelic agent generates its own log file to keep its logging
|
49
|
+
# information separate from that of your application. Specify its
|
50
|
+
# log level here.
|
51
|
+
log_level: info
|
52
|
+
|
53
|
+
# The newrelic agent communicates with the New Relic service via http by
|
54
|
+
# default. If you want to communicate via https to increase
|
55
|
+
# security, then turn on SSL by setting this value to true. Note,
|
56
|
+
# this will result in increased CPU overhead to perform the
|
57
|
+
# encryption involved in SSL communication, but this work is done
|
58
|
+
# asynchronously to the threads that process your application code,
|
59
|
+
# so it should not impact response times.
|
60
|
+
ssl: false
|
61
|
+
|
62
|
+
# EXPERIMENTAL: enable verification of the SSL certificate sent by
|
63
|
+
# the server. This setting has no effect unless SSL is enabled
|
64
|
+
# above. This may block your application. Only enable it if the data
|
65
|
+
# you send us needs end-to-end verified certificates.
|
66
|
+
#
|
67
|
+
# This means we cannot cache the DNS lookup, so each request to the
|
68
|
+
# New Relic service will perform a lookup. It also means that we cannot
|
69
|
+
# use a non-blocking lookup, so in a worst case, if you have DNS
|
70
|
+
# problems, your app may block indefinitely.
|
71
|
+
# verify_certificate: true
|
72
|
+
|
73
|
+
# Set your application's Apdex threshold value with the 'apdex_t'
|
74
|
+
# setting, in seconds. The apdex_t value determines the buckets used
|
75
|
+
# to compute your overall Apdex score.
|
76
|
+
# Requests that take less than apdex_t seconds to process will be
|
77
|
+
# classified as Satisfying transactions; more than apdex_t seconds
|
78
|
+
# as Tolerating transactions; and more than four times the apdex_t
|
79
|
+
# value as Frustrating transactions.
|
80
|
+
# For more about the Apdex standard, see
|
81
|
+
# http://support.newrelic.com/faqs/general/apdex
|
82
|
+
apdex_t: 0.5
|
83
|
+
|
84
|
+
# Proxy settings for connecting to the New Relic server.
|
85
|
+
#
|
86
|
+
# If a proxy is used, the host setting is required. Other settings
|
87
|
+
# are optional. Default port is 8080.
|
88
|
+
#
|
89
|
+
# proxy_host: hostname
|
90
|
+
# proxy_port: 8080
|
91
|
+
# proxy_user:
|
92
|
+
# proxy_pass:
|
93
|
+
|
94
|
+
# Tells transaction tracer and error collector (when enabled)
|
95
|
+
# whether or not to capture HTTP params. When true, frameworks can
|
96
|
+
# exclude HTTP parameters from being captured.
|
97
|
+
# Rails: the RoR filter_parameter_logging excludes parameters
|
98
|
+
# Java: create a config setting called "ignored_params" and set it to
|
99
|
+
# a comma separated list of HTTP parameter names.
|
100
|
+
# ex: ignored_params: credit_card, ssn, password
|
101
|
+
capture_params: false
|
102
|
+
|
103
|
+
# Transaction tracer captures deep information about slow
|
104
|
+
# transactions and sends this to the New Relic service once a
|
105
|
+
# minute. Included in the transaction is the exact call sequence of
|
106
|
+
# the transactions including any SQL statements issued.
|
107
|
+
transaction_tracer:
|
108
|
+
|
109
|
+
# Transaction tracer is enabled by default. Set this to false to
|
110
|
+
# turn it off. This feature is only available at the Professional
|
111
|
+
# product level.
|
112
|
+
enabled: true
|
113
|
+
|
114
|
+
# Threshold in seconds for when to collect a transaction
|
115
|
+
# trace. When the response time of a controller action exceeds
|
116
|
+
# this threshold, a transaction trace will be recorded and sent to
|
117
|
+
# New Relic. Valid values are any float value, or (default) "apdex_f",
|
118
|
+
# which will use the threshold for an dissatisfying Apdex
|
119
|
+
# controller action - four times the Apdex T value.
|
120
|
+
transaction_threshold: apdex_f
|
121
|
+
|
122
|
+
# When transaction tracer is on, SQL statements can optionally be
|
123
|
+
# recorded. The recorder has three modes, "off" which sends no
|
124
|
+
# SQL, "raw" which sends the SQL statement in its original form,
|
125
|
+
# and "obfuscated", which strips out numeric and string literals.
|
126
|
+
record_sql: obfuscated
|
127
|
+
|
128
|
+
# Threshold in seconds for when to collect stack trace for a SQL
|
129
|
+
# call. In other words, when SQL statements exceed this threshold,
|
130
|
+
# then capture and send to New Relic the current stack trace. This is
|
131
|
+
# helpful for pinpointing where long SQL calls originate from.
|
132
|
+
stack_trace_threshold: 0.500
|
133
|
+
|
134
|
+
# Determines whether the agent will capture query plans for slow
|
135
|
+
# SQL queries. Only supported in mysql and postgres. Should be
|
136
|
+
# set to false when using other adapters.
|
137
|
+
# explain_enabled: true
|
138
|
+
|
139
|
+
# Threshold for query execution time below which query plans will not
|
140
|
+
# not be captured. Relevant only when `explain_enabled` is true.
|
141
|
+
# explain_threshold: 0.5
|
142
|
+
|
143
|
+
# Error collector captures information about uncaught exceptions and
|
144
|
+
# sends them to New Relic for viewing
|
145
|
+
error_collector:
|
146
|
+
|
147
|
+
# Error collector is enabled by default. Set this to false to turn
|
148
|
+
# it off. This feature is only available at the Professional
|
149
|
+
# product level.
|
150
|
+
enabled: true
|
151
|
+
|
152
|
+
# Rails Only - tells error collector whether or not to capture a
|
153
|
+
# source snippet around the place of the error when errors are View
|
154
|
+
# related.
|
155
|
+
capture_source: true
|
156
|
+
|
157
|
+
# To stop specific errors from reporting to New Relic, set this property
|
158
|
+
# to comma-separated values. Default is to ignore routing errors,
|
159
|
+
# which are how 404's get triggered.
|
160
|
+
ignore_errors: ActionController::RoutingError
|
161
|
+
|
162
|
+
# (Advanced) Uncomment this to ensure the CPU and memory samplers
|
163
|
+
# won't run. Useful when you are using the agent to monitor an
|
164
|
+
# external resource
|
165
|
+
# disable_samplers: true
|
166
|
+
|
167
|
+
# If you aren't interested in visibility in these areas, you can
|
168
|
+
# disable the instrumentation to reduce overhead.
|
169
|
+
#
|
170
|
+
# disable_view_instrumentation: true
|
171
|
+
# disable_activerecord_instrumentation: true
|
172
|
+
# disable_memcache_instrumentation: true
|
173
|
+
# disable_dj: true
|
174
|
+
|
175
|
+
# Certain types of instrumentation such as GC stats will not work if
|
176
|
+
# you are running multi-threaded. Please let us know.
|
177
|
+
# multi_threaded = false
|
178
|
+
|
179
|
+
# Application Environments
|
180
|
+
# ------------------------------------------
|
181
|
+
# Environment-specific settings are in this section.
|
182
|
+
# For Rails applications, RAILS_ENV is used to determine the environment.
|
183
|
+
# For Java applications, pass -Dnewrelic.environment <environment> to set
|
184
|
+
# the environment.
|
185
|
+
|
186
|
+
# NOTE if your application has other named environments, you should
|
187
|
+
# provide newrelic configuration settings for these environments here.
|
188
|
+
|
189
|
+
development:
|
190
|
+
<<: *default_settings
|
191
|
+
# Turn off communication to New Relic service in development mode (also
|
192
|
+
# 'enabled').
|
193
|
+
# NOTE: for initial evaluation purposes, you may want to temporarily
|
194
|
+
# turn agent communication on in development mode.
|
195
|
+
monitor_mode: true
|
196
|
+
|
197
|
+
# Rails Only - when running in Developer Mode, the New Relic Agent will
|
198
|
+
# present performance information on the last 100 transactions you have
|
199
|
+
# executed since starting the app server.
|
200
|
+
# NOTE: There is substantial overhead when running in developer mode.
|
201
|
+
# Do not use for production or load testing.
|
202
|
+
developer_mode: true
|
203
|
+
|
204
|
+
# Enable textmate links
|
205
|
+
# textmate: true
|
206
|
+
|
207
|
+
test:
|
208
|
+
<<: *default_settings
|
209
|
+
# It almost never makes sense to turn on the agent when running
|
210
|
+
# unit, functional or integration tests or the like.
|
211
|
+
monitor_mode: false
|
212
|
+
|
213
|
+
# Turn on the agent in production for 24x7 monitoring. New Relic
|
214
|
+
# testing shows an average performance impact of < 5 ms per
|
215
|
+
# transaction, so you can leave this on all the time without
|
216
|
+
# incurring any user-visible performance degradation.
|
217
|
+
production:
|
218
|
+
<<: *default_settings
|
219
|
+
monitor_mode: true
|
220
|
+
|
221
|
+
# Many applications have a staging environment which behaves
|
222
|
+
# identically to production. Support for that environment is provided
|
223
|
+
# here. By default, the staging environment has the agent turned on.
|
224
|
+
staging:
|
225
|
+
<<: *default_settings
|
226
|
+
monitor_mode: true
|
227
|
+
app_name: My Application (Staging)
|
@@ -0,0 +1,4 @@
|
|
1
|
+
check process haproxy2rpm with pidfile /var/run/haproxy2rpm.pid
|
2
|
+
start program = "/bin/sh -c 'cd /etc/haproxy2rpm && mkdir -p log && /usr/bin/env NRCONFIG=/etc/haproxy2rpm/newrelic.yml /usr/local/bin/haproxy2rpm --address 127.0.0.1 --port 3333 --environment production --syslog --pid /var/run/haproxy2rpm.pid --log /var/log/haproxy2rpm.log --debug'"
|
3
|
+
stop program = "/bin/sh -c '/bin/kill `/bin/cat /var/run/haproxy2rpm.pid`'"
|
4
|
+
group haproxy2rpm
|
data/examples/routes.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
class MyRequestParser
|
2
|
+
def initialize(line)
|
3
|
+
@line = line.to_i
|
4
|
+
end
|
5
|
+
|
6
|
+
def value_in_seconds
|
7
|
+
@line / 1000.0
|
8
|
+
end
|
9
|
+
|
10
|
+
def value
|
11
|
+
@line
|
12
|
+
end
|
13
|
+
|
14
|
+
def is_error?
|
15
|
+
false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
config.message_parser = lambda do |line|
|
20
|
+
MyRequestParser.new(line)
|
21
|
+
end
|
22
|
+
|
23
|
+
config.request_recorder = lambda do |request|
|
24
|
+
params = {
|
25
|
+
'metric' => "Controller/my/request"
|
26
|
+
}
|
27
|
+
|
28
|
+
if request.is_error?
|
29
|
+
params['is_error'] = true
|
30
|
+
params['error_message'] = "Something went wrong"
|
31
|
+
end
|
32
|
+
|
33
|
+
# record a new relic transaction
|
34
|
+
record_transaction(request.value, params)
|
35
|
+
|
36
|
+
# record a custom metric for new relic custom views
|
37
|
+
result = stats_engine.get_stats_no_scope('Custom/my_custom').record_data_point(request.value)
|
38
|
+
Haproxy2Rpm.logger.debug "RECORDING (data point): #{result.inspect}"
|
39
|
+
|
40
|
+
end
|
data/haproxy2rpm.gemspec
CHANGED
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.add_dependency "eventmachine-tail"
|
15
15
|
s.add_development_dependency "rake"
|
16
16
|
s.add_development_dependency "shoulda-context"
|
17
|
+
s.add_development_dependency "mocha"
|
17
18
|
|
18
19
|
s.files = `git ls-files`.split("\n")
|
19
20
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/haproxy2rpm/rpm.rb
CHANGED
@@ -1,29 +1,94 @@
|
|
1
1
|
module Haproxy2Rpm
|
2
2
|
class Rpm
|
3
|
+
|
4
|
+
attr_accessor :routes, :queue_time_stats_engine, :stats_engine
|
5
|
+
|
3
6
|
def initialize(options = {})
|
4
7
|
agent_options = {:log => Haproxy2Rpm.logger}
|
5
8
|
agent_options[:app_name] = options[:app_name] if options[:app_name]
|
6
9
|
agent_options[:env] = options[:env] if options[:env]
|
7
10
|
NewRelic::Agent.manual_start agent_options
|
8
11
|
@stats_engine = NewRelic::Agent.agent.stats_engine
|
9
|
-
@
|
12
|
+
@queue_time_stats_engine = @stats_engine.get_stats_no_scope('WebFrontend/QueueTime')
|
13
|
+
@routes = options[:routes] || []
|
14
|
+
if options[:config_file]
|
15
|
+
Haproxy2Rpm.logger.info "Reading configuration from: #{options[:config_file]}"
|
16
|
+
content = File.open(options[:config_file]){|f| f.read }
|
17
|
+
instance_eval(content, options[:config_file])
|
18
|
+
end
|
10
19
|
end
|
11
|
-
|
20
|
+
|
21
|
+
def config
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
12
25
|
def process_and_send(line)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
if request.is_error?
|
19
|
-
params['is_error'] = true
|
20
|
-
params['error_message'] = "#{request.uri} : Status code #{request.status_code}"
|
26
|
+
message = message_parser.call(line)
|
27
|
+
if(message)
|
28
|
+
request_recorder.call(message_parser.call(line))
|
29
|
+
else
|
30
|
+
Haproxy2Rpm.logger.warn "Parser returned an empty message from line #{line}"
|
21
31
|
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_message_parser
|
35
|
+
lambda do |line|
|
36
|
+
LineParser.new(line)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def message_parser
|
41
|
+
@message_parser ||= default_message_parser
|
42
|
+
end
|
43
|
+
|
44
|
+
def message_parser=(block)
|
45
|
+
Haproxy2Rpm.logger.debug "Installing custom parser"
|
46
|
+
@message_parser = block
|
47
|
+
end
|
48
|
+
|
49
|
+
def default_request_recorder
|
50
|
+
lambda do |request|
|
51
|
+
rpm_number_unit = 1000.0
|
52
|
+
|
53
|
+
params = {
|
54
|
+
'metric' => "Controller#{route_for(request.http_path)}"
|
55
|
+
}
|
56
|
+
|
57
|
+
if request.is_error?
|
58
|
+
params['is_error'] = true
|
59
|
+
params['error_message'] = "#{request.uri} : Status code #{request.status_code}"
|
60
|
+
end
|
22
61
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
62
|
+
record_transaction(request.tr / rpm_number_unit, params)
|
63
|
+
Haproxy2Rpm.logger.debug "RECORDING (transaction): #{params.inspect}"
|
64
|
+
result = queue_time_stats_engine.record_data_point(request.tw / rpm_number_unit)
|
65
|
+
Haproxy2Rpm.logger.debug "RECORDING (data point): wait time #{request.tw}, #{result.inspect}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def request_recorder
|
70
|
+
@request_recorder ||= default_request_recorder
|
71
|
+
end
|
72
|
+
|
73
|
+
def request_recorder=(block)
|
74
|
+
Haproxy2Rpm.logger.debug "Installing custom recorder"
|
75
|
+
@request_recorder = block
|
76
|
+
end
|
77
|
+
|
78
|
+
def record_transaction(*args)
|
79
|
+
NewRelic::Agent.record_transaction(*args)
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
def route_for(path)
|
85
|
+
routes.each do |route|
|
86
|
+
match = path.match(route[:pattern])
|
87
|
+
if match
|
88
|
+
return route[:target]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
path
|
27
92
|
end
|
28
93
|
end
|
29
94
|
end
|
data/lib/haproxy2rpm/syslog.rb
CHANGED
@@ -2,15 +2,11 @@
|
|
2
2
|
# https://raw.github.com/jordansissel/experiments/master/ruby/eventmachine-speed/basic.rb
|
3
3
|
module Haproxy2Rpm
|
4
4
|
class SyslogHandler < EventMachine::Connection
|
5
|
-
def initialize
|
6
|
-
@rpm = Rpm.new
|
7
|
-
end
|
8
|
-
|
9
5
|
def receive_data(data)
|
10
6
|
message_start_index = data.index('haproxy')
|
11
7
|
message = data[message_start_index..-1]
|
12
8
|
Haproxy2Rpm.logger.debug "RECEIVED (syslog): #{message}"
|
13
|
-
|
9
|
+
Haproxy2Rpm.rpm.process_and_send(message)
|
14
10
|
end
|
15
11
|
end
|
16
12
|
end
|
data/lib/haproxy2rpm/version.rb
CHANGED
data/lib/haproxy2rpm.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
class DummyRequest
|
2
|
+
def initialize(line)
|
3
|
+
@line = line
|
4
|
+
end
|
5
|
+
|
6
|
+
def value
|
7
|
+
@line.to_i
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
config.message_parser = lambda do |line|
|
12
|
+
DummyRequest.new(line)
|
13
|
+
end
|
14
|
+
|
15
|
+
config.request_recorder = lambda do |request|
|
16
|
+
stats_engine.get_stats_no_scope('Custom/dummy').record_data_point(request.value)
|
17
|
+
end
|
data/test/haproxy2pm_test.rb
CHANGED
@@ -2,24 +2,6 @@ $LOAD_PATH.unshift( File.dirname(__FILE__) )
|
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
|
-
def log_entry(options = {})
|
6
|
-
defaults = {
|
7
|
-
:tq => 6559,
|
8
|
-
:tw => 100,
|
9
|
-
:tc => 7,
|
10
|
-
:tr => 147,
|
11
|
-
:tt => 6723,
|
12
|
-
:status_code => 200,
|
13
|
-
:http_path => '/',
|
14
|
-
:http_method => 'GET',
|
15
|
-
:http_query => 'example_param=test',
|
16
|
-
}
|
17
|
-
defaults.merge!(options)
|
18
|
-
log_line = <<LOG_LINE
|
19
|
-
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"
|
20
|
-
LOG_LINE
|
21
|
-
end
|
22
|
-
|
23
5
|
class Haproxy2RpmTest < Test::Unit::TestCase
|
24
6
|
context 'parsing of haproxy files' do
|
25
7
|
setup do
|
data/test/rpm_test.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
$LOAD_PATH.unshift( File.dirname(__FILE__) )
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class RpmTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context 'initialize' do
|
8
|
+
setup do
|
9
|
+
NewRelic::Agent.stubs(:manual_start)
|
10
|
+
end
|
11
|
+
|
12
|
+
should 'start the new relic agent' do
|
13
|
+
NewRelic::Agent.expects(:manual_start)
|
14
|
+
Haproxy2Rpm::Rpm.new({})
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'aquire the stats engine' do
|
18
|
+
stats_engine = mock
|
19
|
+
NewRelic::Agent.agent.expects(:stats_engine).returns(stats_engine)
|
20
|
+
stats_engine.expects(:get_stats_no_scope).with('WebFrontend/QueueTime')
|
21
|
+
Haproxy2Rpm::Rpm.new({})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
context '#process_and_send' do
|
25
|
+
setup do
|
26
|
+
NewRelic::Agent.stubs(:manual_start)
|
27
|
+
@instance = Haproxy2Rpm::Rpm.new({})
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'record the transaction time' do
|
31
|
+
NewRelic::Agent.expects(:record_transaction).with(0.1, any_parameters)
|
32
|
+
@instance.process_and_send(log_entry(:tr => 100))
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'record the controller metric' do
|
36
|
+
NewRelic::Agent.expects(:record_transaction).with(anything, has_entry('metric', 'Controller/user/check'))
|
37
|
+
@instance.process_and_send(log_entry(:http_path => "/user/check"))
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'consider routes' do
|
41
|
+
@instance.routes = [{:pattern => %r{^/[0-9]+/update$}, :target => '/user/update'}]
|
42
|
+
NewRelic::Agent.expects(:record_transaction).with(anything, has_entry('metric', 'Controller/user/update'))
|
43
|
+
@instance.process_and_send(log_entry(:http_path => "/49339032093/update"))
|
44
|
+
end
|
45
|
+
|
46
|
+
should 'record the queue time' do
|
47
|
+
stats = mock
|
48
|
+
@instance.queue_time_stats_engine = stats
|
49
|
+
stats.expects(:record_data_point).with(0.01)
|
50
|
+
@instance.process_and_send(log_entry(:tw => 10))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context '#message_parser=' do
|
55
|
+
setup do
|
56
|
+
NewRelic::Agent.stubs(:manual_start)
|
57
|
+
@instance = Haproxy2Rpm::Rpm.new({})
|
58
|
+
@instance.request_recorder = lambda{|r|}
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'allow to pass in a custom message parser' do
|
62
|
+
parser = lambda{|r|}
|
63
|
+
@instance.message_parser = parser
|
64
|
+
parser.expects(:call)
|
65
|
+
@instance.process_and_send(log_entry)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context '#request_recorder=' do
|
70
|
+
setup do
|
71
|
+
NewRelic::Agent.stubs(:manual_start)
|
72
|
+
@instance = Haproxy2Rpm::Rpm.new({})
|
73
|
+
@instance.message_parser = lambda{ |line| line }
|
74
|
+
end
|
75
|
+
|
76
|
+
should 'allow to pass in a custom recorder' do
|
77
|
+
recorder = lambda{|r|}
|
78
|
+
@instance.request_recorder = recorder
|
79
|
+
recorder.expects(:call)
|
80
|
+
@instance.process_and_send(log_entry)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'config_file' do
|
85
|
+
setup do
|
86
|
+
NewRelic::Agent.stubs(:manual_start)
|
87
|
+
@instance = Haproxy2Rpm::Rpm.new({:config_file => File.join(File.dirname(__FILE__), 'fixtures', 'config.rb')})
|
88
|
+
end
|
89
|
+
|
90
|
+
should 'eval the passed in config file' do
|
91
|
+
stats = mock
|
92
|
+
@instance.stats_engine.expects(:get_stats_no_scope).with('Custom/dummy').returns(stats)
|
93
|
+
stats.expects(:record_data_point).with(12)
|
94
|
+
@instance.process_and_send('12')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,5 +1,36 @@
|
|
1
1
|
$LOAD_PATH.unshift( File.join( File.dirname(__FILE__), "..", "lib") )
|
2
2
|
|
3
|
+
require "rubygems"
|
3
4
|
require 'test/unit'
|
5
|
+
require 'mocha'
|
4
6
|
require 'shoulda-context'
|
5
7
|
require 'haproxy2rpm'
|
8
|
+
|
9
|
+
|
10
|
+
ENV['NRCONFIG'] = File.join(File.dirname(__FILE__), '..', 'newrelic.yml')
|
11
|
+
|
12
|
+
class DummyLogger
|
13
|
+
[:level, :debug, :info, :warn, :fatal, :error].each do |method|
|
14
|
+
define_method(method) do |*args|
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
Haproxy2Rpm.logger = DummyLogger.new
|
19
|
+
|
20
|
+
def log_entry(options = {})
|
21
|
+
defaults = {
|
22
|
+
:tq => 6559,
|
23
|
+
:tw => 100,
|
24
|
+
:tc => 7,
|
25
|
+
:tr => 147,
|
26
|
+
:tt => 6723,
|
27
|
+
:status_code => 200,
|
28
|
+
:http_path => '/',
|
29
|
+
:http_method => 'GET',
|
30
|
+
:http_query => 'example_param=test',
|
31
|
+
}
|
32
|
+
defaults.merge!(options)
|
33
|
+
log_line = <<LOG_LINE
|
34
|
+
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
|
+
LOG_LINE
|
36
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haproxy2rpm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Patrick Huesler
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-07-
|
19
|
+
date: 2011-07-18 00:00:00 +02:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -75,6 +75,20 @@ dependencies:
|
|
75
75
|
version: "0"
|
76
76
|
type: :development
|
77
77
|
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: mocha
|
80
|
+
prerelease: false
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
type: :development
|
91
|
+
version_requirements: *id005
|
78
92
|
description: Sending haproxy logs to new relic rpm
|
79
93
|
email:
|
80
94
|
- patrick.huesler@wooga.com
|
@@ -93,6 +107,10 @@ files:
|
|
93
107
|
- Rakefile
|
94
108
|
- Research.md
|
95
109
|
- bin/haproxy2rpm
|
110
|
+
- config/newrelic.yml.example
|
111
|
+
- examples/haproxy2rpm.monitrc
|
112
|
+
- examples/routes.rb
|
113
|
+
- examples/simple_config.rb
|
96
114
|
- haproxy2rpm.gemspec
|
97
115
|
- lib/haproxy2rpm.rb
|
98
116
|
- lib/haproxy2rpm/file_parser.rb
|
@@ -100,7 +118,9 @@ files:
|
|
100
118
|
- lib/haproxy2rpm/rpm.rb
|
101
119
|
- lib/haproxy2rpm/syslog.rb
|
102
120
|
- lib/haproxy2rpm/version.rb
|
121
|
+
- test/fixtures/config.rb
|
103
122
|
- test/haproxy2pm_test.rb
|
123
|
+
- test/rpm_test.rb
|
104
124
|
- test/test_helper.rb
|
105
125
|
has_rdoc: true
|
106
126
|
homepage: https://github.com/wooga/haproxy2rpm
|
@@ -137,5 +157,7 @@ signing_key:
|
|
137
157
|
specification_version: 3
|
138
158
|
summary: Sending haproxy logs to new relic rpm
|
139
159
|
test_files:
|
160
|
+
- test/fixtures/config.rb
|
140
161
|
- test/haproxy2pm_test.rb
|
162
|
+
- test/rpm_test.rb
|
141
163
|
- test/test_helper.rb
|