fozzie 0.0.27 → 1.0.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/.gitignore +2 -1
- data/Guardfile +2 -2
- data/README.md +22 -11
- data/Rakefile +1 -1
- data/fozzie.gemspec +8 -14
- data/lib/core_ext/module/monitor.rb +4 -3
- data/lib/fozzie.rb +6 -7
- data/lib/fozzie/adapter.rb +1 -0
- data/lib/fozzie/adapter/statsd.rb +86 -0
- data/lib/fozzie/bulk_dsl.rb +28 -0
- data/lib/fozzie/configuration.rb +32 -13
- data/lib/fozzie/dsl.rb +19 -0
- data/lib/fozzie/exception.rb +5 -0
- data/lib/fozzie/interface.rb +30 -15
- data/lib/fozzie/rack/middleware.rb +3 -1
- data/lib/fozzie/sniff.rb +28 -33
- data/lib/fozzie/version.rb +1 -1
- data/spec/config/fozzie.yml +2 -1
- data/spec/lib/core_ext/module/monitor_spec.rb +9 -0
- data/spec/lib/fozzie/adapter/statsd_spec.rb +82 -0
- data/spec/lib/fozzie/bulk_dsl_spec.rb +47 -0
- data/spec/lib/fozzie/configuration_spec.rb +34 -20
- data/spec/lib/fozzie/dsl_spec.rb +16 -0
- data/spec/lib/fozzie/rack/middleware_spec.rb +6 -36
- data/spec/lib/fozzie/rack/sinatra_spec.rb +31 -0
- data/spec/lib/fozzie/sniff_spec.rb +37 -37
- data/spec/lib/fozzie/version_spec.rb +1 -1
- data/spec/lib/fozzie_spec.rb +19 -3
- data/spec/shared_examples/fozzie_adapter.rb +7 -0
- data/spec/shared_examples/interface.rb +160 -0
- data/spec/spec_helper.rb +20 -10
- metadata +31 -74
- data/lib/core_ext/hash.rb +0 -16
- data/lib/fozzie/mill.rb +0 -50
- data/lib/fozzie/rails/engine.rb +0 -15
- data/lib/fozzie/rails/middleware.rb +0 -39
- data/lib/fozzie/railtie.rb +0 -15
- data/lib/fozzie/socket.rb +0 -53
- data/spec/lib/core_ext/hash_spec.rb +0 -33
- data/spec/lib/fozzie/interface_spec.rb +0 -180
- data/spec/lib/fozzie/mill_spec.rb +0 -43
- data/spec/lib/fozzie/rails/middleware_spec.rb +0 -125
data/.gitignore
CHANGED
data/Guardfile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# A sample Guardfile
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
3
|
|
4
|
-
guard 'rspec', :
|
4
|
+
guard 'rspec', :cli => "--color" do
|
5
5
|
watch(%r{^spec/.+_spec\.rb$})
|
6
6
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
7
|
watch('spec/spec_helper.rb') { "spec" }
|
8
|
-
end
|
8
|
+
end
|
data/README.md
CHANGED
@@ -109,12 +109,31 @@ class FooBar
|
|
109
109
|
# my code here...
|
110
110
|
end
|
111
111
|
|
112
|
+
_monitor("my.awesome.bucket.name")
|
113
|
+
def quux
|
114
|
+
# something
|
115
|
+
end
|
116
|
+
|
112
117
|
end
|
113
118
|
```
|
114
119
|
This will register the processing time for this method, everytime it is called, under the Graphite bucket `foo_bar.zar`.
|
115
120
|
|
116
121
|
This will work on both Class and Instance methods.
|
117
122
|
|
123
|
+
## Bulk
|
124
|
+
|
125
|
+
You can send a bulk of metrics using the `bulk` method:
|
126
|
+
``` ruby
|
127
|
+
Stats.bulk do
|
128
|
+
increment 'wat'
|
129
|
+
decrement 'wot'
|
130
|
+
gauge 'foo', rand
|
131
|
+
time_to_do 'wat_timer' { sleep 4 }
|
132
|
+
end
|
133
|
+
```
|
134
|
+
|
135
|
+
This will send all the given metrics in a single packet to the statistics server.
|
136
|
+
|
118
137
|
## Namespaces
|
119
138
|
|
120
139
|
Fozzie supports the following namespaces as default
|
@@ -185,13 +204,13 @@ Prefixes are cached on first use, therefore any changes to the Fozzie configure
|
|
185
204
|
|
186
205
|
## Middleware
|
187
206
|
|
188
|
-
To time and register the controller actions within your Rails application, Fozzie provides some middleware.
|
207
|
+
To time and register the controller actions within your Rack and Rails application, Fozzie provides some middleware.
|
189
208
|
|
190
209
|
### Rack
|
191
210
|
|
192
211
|
``` ruby
|
193
212
|
require 'rack'
|
194
|
-
require 'fozzie'
|
213
|
+
require 'fozzie/rack/middleware'
|
195
214
|
|
196
215
|
app = Rack::Builder.new {
|
197
216
|
use Fozzie::Rack::Middleware
|
@@ -201,9 +220,7 @@ app = Rack::Builder.new {
|
|
201
220
|
|
202
221
|
### Rails
|
203
222
|
|
204
|
-
|
205
|
-
|
206
|
-
Fozzie::Rails::Middleware will automatically be invoked on Rails initialization.
|
223
|
+
See [Fozzie Rails](http://github.com/lonelyplanet/fozzie_rails).
|
207
224
|
|
208
225
|
## Bucket name prefixes
|
209
226
|
|
@@ -242,18 +259,12 @@ Fozzie.logger = Logger.new 'log/fozzie.log'
|
|
242
259
|
|
243
260
|
This may change, depending on feedback and more production experience.
|
244
261
|
|
245
|
-
## Rails User Interface Performance Measuring
|
246
|
-
|
247
|
-
If you also require UI metrics, you can also include the Mill script in the bottom of any page you would like to measure (see `resources/mill.js` and `resources/mill.min.js`) and you start receiving measurements on page performance.
|
248
|
-
|
249
262
|
## Credits
|
250
263
|
|
251
264
|
Currently supported and maintained by [Marc Watts](marc.watts@lonelyplanet.co.uk) @ Lonely Planet Online.
|
252
265
|
|
253
266
|
Big thanks and Credits:
|
254
267
|
|
255
|
-
* [Mark Barger](mark.barger@lonelyplanet.co.uk) for support in trying to make this Gem useful.
|
256
|
-
|
257
268
|
* [Dave Nolan](https://github.com/textgoeshere)
|
258
269
|
|
259
270
|
* [Etsy](http://codeascraft.etsy.com/) whose [Statsd](https://github.com/etsy/statsd) product has enabled us to come such a long way in a very short period of time. We love Etsy.
|
data/Rakefile
CHANGED
data/fozzie.gemspec
CHANGED
@@ -5,18 +5,18 @@ require "fozzie/version"
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "fozzie"
|
7
7
|
s.version = Fozzie::VERSION
|
8
|
-
s.authors = ["Marc Watts"
|
8
|
+
s.authors = ["Marc Watts"]
|
9
9
|
s.email = ["marc.watts@lonelyplanet.co.uk"]
|
10
|
-
s.summary = %q{
|
10
|
+
s.summary = %q{Ruby gem from Lonely Planet Online to register statistics. Currently supports Statsd.}
|
11
11
|
s.description = %q{
|
12
|
-
Gem to make statistics sending
|
13
|
-
|
12
|
+
Gem to make statistics sending from Ruby applications simple and efficient as possible.
|
13
|
+
Currently supports Statsd, and is inspired by the original ruby-statsd gem by Etsy.
|
14
14
|
}
|
15
15
|
|
16
16
|
s.rubyforge_project = "fozzie"
|
17
17
|
|
18
18
|
s.files = `git ls-files`.split("\n")
|
19
|
-
s.test_files = `git ls-files -- {
|
19
|
+
s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
|
20
20
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
21
|
s.require_paths = ["lib"]
|
22
22
|
|
@@ -25,15 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
|
26
26
|
s.add_development_dependency 'rake'
|
27
27
|
s.add_development_dependency 'rspec'
|
28
|
-
s.add_development_dependency 'mocha'
|
29
|
-
s.add_development_dependency 'syntax'
|
30
|
-
s.add_development_dependency 'simplecov'
|
31
|
-
|
32
|
-
s.add_development_dependency 'sinatra'
|
33
|
-
s.add_development_dependency 'rack-test'
|
34
|
-
s.add_development_dependency 'actionpack', '2.3.14'
|
35
|
-
|
36
28
|
s.add_development_dependency 'guard'
|
37
29
|
s.add_development_dependency 'guard-rspec'
|
38
|
-
|
30
|
+
s.add_development_dependency 'rb-fsevent'
|
31
|
+
s.add_development_dependency 'sinatra'
|
32
|
+
s.add_development_dependency 'rack-test'
|
39
33
|
end
|
@@ -2,10 +2,11 @@ require 'fozzie/sniff'
|
|
2
2
|
|
3
3
|
class Module
|
4
4
|
|
5
|
-
def _monitor
|
5
|
+
def _monitor(bucket_name = nil)
|
6
6
|
return unless Fozzie.c.sniff?
|
7
|
-
self.class_eval {
|
7
|
+
self.class_eval { extend Fozzie::Sniff }
|
8
8
|
@_monitor_flag = true
|
9
|
+
@_bucket_name = bucket_name
|
9
10
|
end
|
10
11
|
|
11
|
-
end
|
12
|
+
end
|
data/lib/fozzie.rb
CHANGED
@@ -11,15 +11,14 @@ module Fozzie
|
|
11
11
|
|
12
12
|
require 'core_ext/module/monitor'
|
13
13
|
|
14
|
+
require 'fozzie/adapter'
|
15
|
+
|
16
|
+
require "fozzie/exception"
|
14
17
|
require 'fozzie/configuration'
|
15
|
-
require "fozzie/
|
18
|
+
require "fozzie/dsl"
|
19
|
+
require "fozzie/bulk_dsl"
|
16
20
|
require "fozzie/version"
|
17
21
|
|
18
|
-
require "fozzie/rack/middleware"
|
19
|
-
require "fozzie/rails/middleware"
|
20
|
-
|
21
|
-
require 'fozzie/railtie' if defined?(::Rails)
|
22
|
-
|
23
22
|
class << self
|
24
23
|
|
25
24
|
# Shortcut for `Fozzie.config`
|
@@ -58,7 +57,7 @@ module Fozzie
|
|
58
57
|
|
59
58
|
# Loads each namespace for registering statistics
|
60
59
|
self.c.namespaces.each do |klas|
|
61
|
-
Kernel.const_set(klas,
|
60
|
+
Kernel.const_set(klas, Dsl.instance) unless const_defined?(klas)
|
62
61
|
end
|
63
62
|
|
64
63
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
%w{statsd}.each {|r| require "fozzie/adapter/#{r}" }
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Fozzie
|
4
|
+
module Adapter
|
5
|
+
|
6
|
+
class Statsd
|
7
|
+
|
8
|
+
RESERVED_CHARS_REGEX = /[\:\|\@\s]/
|
9
|
+
RESERVED_CHARS_REPLACEMENT = '_'
|
10
|
+
DELIMETER = '.'
|
11
|
+
SAFE_SEPARATOR = '-'
|
12
|
+
TYPES = { :gauge => 'g', :count => 'c', :timing => 'ms' }
|
13
|
+
BULK_DELIMETER = "\n"
|
14
|
+
|
15
|
+
# Send the statistic to the server
|
16
|
+
#
|
17
|
+
# Creates the Statsd key from the given values, and sends to socket (depending on sample rate)
|
18
|
+
def register(*stats)
|
19
|
+
metrics = stats.flatten.collect do |stat|
|
20
|
+
next if sampled?(stat[:sample_rate])
|
21
|
+
|
22
|
+
bucket = format_bucket(stat[:bin])
|
23
|
+
value = format_value(stat[:value], stat[:type], stat[:sample_rate])
|
24
|
+
|
25
|
+
[bucket, value].join(':')
|
26
|
+
end.compact.join(BULK_DELIMETER)
|
27
|
+
|
28
|
+
send_to_socket(metrics)
|
29
|
+
end
|
30
|
+
|
31
|
+
def format_bucket(stat)
|
32
|
+
bucket = [stat].flatten.compact.collect(&:to_s).join(DELIMETER).downcase
|
33
|
+
bucket = bucket.gsub('::', DELIMETER).gsub(RESERVED_CHARS_REGEX, RESERVED_CHARS_REPLACEMENT)
|
34
|
+
bucket = [Fozzie.c.data_prefix, bucket].compact.join(DELIMETER)
|
35
|
+
|
36
|
+
bucket
|
37
|
+
end
|
38
|
+
|
39
|
+
def format_value(val, type, sample_rate)
|
40
|
+
converted_type = TYPES[type.to_sym]
|
41
|
+
converted_type ||= TYPES[:gauge]
|
42
|
+
|
43
|
+
value = [val, converted_type].join('|')
|
44
|
+
value << '@%s' % sample_rate.to_s if sample_rate < 1
|
45
|
+
|
46
|
+
value
|
47
|
+
end
|
48
|
+
|
49
|
+
# If the statistic is sampled, generate a condition to check if it's good to send
|
50
|
+
def sampled(sample_rate)
|
51
|
+
yield unless sampled?(sample_rate)
|
52
|
+
end
|
53
|
+
|
54
|
+
def sampled?(sample_rate)
|
55
|
+
sample_rate < 1 and rand > sample_rate
|
56
|
+
end
|
57
|
+
|
58
|
+
# Send data to the server via the socket
|
59
|
+
def send_to_socket(message)
|
60
|
+
Fozzie.logger.debug {"Statsd: #{message}"} if Fozzie.logger
|
61
|
+
Timeout.timeout(Fozzie.c.timeout) {
|
62
|
+
res = socket.send(message, 0, Fozzie.c.host, Fozzie.c.port)
|
63
|
+
Fozzie.logger.debug {"Statsd sent: #{res}"} if Fozzie.logger
|
64
|
+
(res.to_i == message.length)
|
65
|
+
}
|
66
|
+
rescue => exc
|
67
|
+
Fozzie.logger.debug {"Statsd Failure: #{exc.message}\n#{exc.backtrace}"} if Fozzie.logger
|
68
|
+
false
|
69
|
+
end
|
70
|
+
|
71
|
+
# The Socket we want to use to send data
|
72
|
+
def socket
|
73
|
+
@socket ||= ::UDPSocket.new
|
74
|
+
end
|
75
|
+
|
76
|
+
def delimeter
|
77
|
+
DELIMETER
|
78
|
+
end
|
79
|
+
|
80
|
+
def safe_separator
|
81
|
+
SAFE_SEPARATOR
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Fozzie
|
2
|
+
class BulkDsl
|
3
|
+
include Fozzie::Interface
|
4
|
+
|
5
|
+
def initialize(&block)
|
6
|
+
@metrics = []
|
7
|
+
block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
|
8
|
+
send_bulk
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# Cache the requested metrics for bulk sending
|
14
|
+
#
|
15
|
+
def send(stat, value, type, sample_rate = 1)
|
16
|
+
val = { :bin => stat, :value => value, :type => type, :sample_rate => sample_rate }
|
17
|
+
|
18
|
+
@metrics.push(val)
|
19
|
+
end
|
20
|
+
|
21
|
+
def send_bulk
|
22
|
+
return if @metrics.empty?
|
23
|
+
|
24
|
+
adapter.register(@metrics)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/fozzie/configuration.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'yaml'
|
2
|
-
require '
|
2
|
+
require 'facets/hash/symbolize_keys'
|
3
3
|
require 'sys/uname'
|
4
4
|
require 'timeout'
|
5
5
|
|
@@ -7,16 +7,32 @@ module Fozzie
|
|
7
7
|
|
8
8
|
# Fozzie configuration allows assignment of global properties
|
9
9
|
# that will be used within the Fozzie codebase.
|
10
|
+
|
10
11
|
class Configuration
|
11
12
|
include Sys
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
def_delegators :adapter, :delimeter, :safe_separator
|
12
16
|
|
13
|
-
attr_accessor :env, :config_path, :host, :port, :appname, :namespaces,
|
17
|
+
attr_accessor :env, :config_path, :host, :port, :appname, :namespaces,
|
18
|
+
:timeout, :monitor_classes, :sniff_envs, :ignore_prefix, :prefix
|
14
19
|
|
15
20
|
def initialize(args = {})
|
16
21
|
merge_and_assign_config(args)
|
22
|
+
self.adapter
|
17
23
|
self.origin_name
|
18
24
|
end
|
19
25
|
|
26
|
+
def adapter=(adapter)
|
27
|
+
@adapter = eval("Fozzie::Adapter::#{adapter}").new
|
28
|
+
rescue NoMethodError
|
29
|
+
raise AdapterMissing, "Adapter could not be found for given provider #{@provider}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def adapter
|
33
|
+
@adapter || default_configuration[:adapter]
|
34
|
+
end
|
35
|
+
|
20
36
|
def disable_prefix
|
21
37
|
@ignore_prefix = true
|
22
38
|
end
|
@@ -26,15 +42,17 @@ module Fozzie
|
|
26
42
|
return nil if @ignore_prefix
|
27
43
|
return @data_prefix if @data_prefix
|
28
44
|
|
29
|
-
|
30
|
-
(
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
45
|
+
escaped_prefix_with_dynamically_resolved_parts = prefix.map do |part|
|
46
|
+
resolved_part = (part.kind_of?(Symbol) && self.respond_to?(part) ? self.send(part) : part.to_s)
|
47
|
+
escaped_resolved_part = resolved_part.gsub(delimeter, safe_separator)
|
48
|
+
escaped_resolved_part == "" ? nil : escaped_resolved_part
|
49
|
+
end.compact
|
50
|
+
|
51
|
+
@data_prefix = if escaped_prefix_with_dynamically_resolved_parts.any?
|
52
|
+
escaped_prefix_with_dynamically_resolved_parts.join(delimeter).strip
|
53
|
+
else
|
54
|
+
nil
|
55
|
+
end
|
38
56
|
end
|
39
57
|
|
40
58
|
# Returns the origin name of the current machine to register the stat against
|
@@ -70,7 +88,8 @@ module Fozzie
|
|
70
88
|
:timeout => 0.5,
|
71
89
|
:monitor_classes => [],
|
72
90
|
:sniff_envs => [:development, :staging, :production],
|
73
|
-
:ignore_prefix => false
|
91
|
+
:ignore_prefix => false,
|
92
|
+
:adapter => :Statsd
|
74
93
|
}.dup
|
75
94
|
end
|
76
95
|
|
@@ -89,4 +108,4 @@ module Fozzie
|
|
89
108
|
|
90
109
|
end
|
91
110
|
|
92
|
-
end
|
111
|
+
end
|
data/lib/fozzie/dsl.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require "fozzie/interface"
|
3
|
+
|
4
|
+
module Fozzie
|
5
|
+
class Dsl
|
6
|
+
include Fozzie::Interface, Singleton
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Send the statistic to the chosen provider
|
11
|
+
#
|
12
|
+
def send(stat, value, type, sample_rate = 1)
|
13
|
+
val = { :bin => stat, :value => value, :type => type, :sample_rate => sample_rate }
|
14
|
+
|
15
|
+
adapter.register(val)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/lib/fozzie/interface.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
require 'fozzie/socket'
|
1
|
+
require 'fozzie/adapter/statsd'
|
3
2
|
|
4
3
|
module Fozzie
|
5
|
-
|
6
|
-
include Fozzie::Socket, Singleton
|
4
|
+
module Interface
|
7
5
|
|
8
6
|
# Increments the given stat by one, with an optional sample rate
|
9
7
|
#
|
@@ -23,14 +21,14 @@ module Fozzie
|
|
23
21
|
#
|
24
22
|
# `Stats.count 'wat', 500`
|
25
23
|
def count(stat, count, sample_rate=1)
|
26
|
-
send(stat, count,
|
24
|
+
send(stat, count, :count, sample_rate)
|
27
25
|
end
|
28
26
|
|
29
27
|
# Registers a timing (in ms) for the given stat, with an optional sample rate
|
30
28
|
#
|
31
29
|
# `Stats.timing 'wat', 500`
|
32
30
|
def timing(stat, ms, sample_rate=1)
|
33
|
-
send(stat, ms,
|
31
|
+
send(stat, ms, :timing, sample_rate)
|
34
32
|
end
|
35
33
|
|
36
34
|
# Registers the time taken to complete a given block (in ms), with an optional sample rate
|
@@ -47,7 +45,7 @@ module Fozzie
|
|
47
45
|
#
|
48
46
|
# `Stats.time_to_do 'wat' { # Do something, again... }`
|
49
47
|
def time_to_do(stat, sample_rate=1, &block)
|
50
|
-
|
48
|
+
time(stat, sample_rate, &block)
|
51
49
|
end
|
52
50
|
|
53
51
|
# Registers the time taken to complete a given block (in ms), with an optional sample rate
|
@@ -99,6 +97,13 @@ module Fozzie
|
|
99
97
|
deployed(app)
|
100
98
|
end
|
101
99
|
|
100
|
+
# Register an event of any type
|
101
|
+
#
|
102
|
+
# `Stats.event 'wat', 'app'`
|
103
|
+
def event(type, app = nil)
|
104
|
+
gauge ["event", type.to_s, app], Time.now.usec
|
105
|
+
end
|
106
|
+
|
102
107
|
# Registers an increment on the result of the given boolean
|
103
108
|
#
|
104
109
|
# `Stats.increment_on 'wat', wat.random?`
|
@@ -108,18 +113,28 @@ module Fozzie
|
|
108
113
|
perf
|
109
114
|
end
|
110
115
|
|
111
|
-
# Register an event of any type
|
112
|
-
#
|
113
|
-
# `Stats.event 'wat', 'app'`
|
114
|
-
def event(type, app = nil)
|
115
|
-
gauge ["event", type.to_s, app], Time.now.usec
|
116
|
-
end
|
117
|
-
|
118
116
|
# Register an arbitrary value
|
119
117
|
#
|
120
118
|
# `Stats.gauge 'wat', 'app'`
|
121
119
|
def gauge(stat, value, sample_rate = 1)
|
122
|
-
send(stat, value,
|
120
|
+
send(stat, value, :gauge, sample_rate)
|
123
121
|
end
|
122
|
+
|
123
|
+
# Register multiple statistics in a single call
|
124
|
+
#
|
125
|
+
# `Stats.bulk do
|
126
|
+
# increment 'wat'
|
127
|
+
# decrement 'wot'
|
128
|
+
# end`
|
129
|
+
def bulk(&block)
|
130
|
+
Fozzie::BulkDsl.new(&block)
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def adapter
|
136
|
+
Fozzie.c.adapter
|
137
|
+
end
|
138
|
+
|
124
139
|
end
|
125
140
|
end
|