better_fx 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ff923b091c09a0c2e4f23274f3d4189d32775e5c
4
- data.tar.gz: 0c84f088ff4c5b4030a90ba2f7dce02065894ef3
3
+ metadata.gz: 4b9a9c55efdf7a86cd3183221c5d675024c4b9c3
4
+ data.tar.gz: 36a119c9ae945b44eb1f03ac44c2101ae930be9e
5
5
  SHA512:
6
- metadata.gz: 2b72084b4f6cffd71bb56240378ecf9dd187a9cae630491efff48a1b4f880a16b37a3fa857eac1dbecdeea59c5723aa75f991790949799259bbf349056cf41ec
7
- data.tar.gz: d2ce91f3eced03a85f5995ac35963270619f0f02cfce94dbabc14adaef5b04e490fd1ec7a9b68d78490971dd9ae8850f2cc5cb6e2ce33917ea49cf2290b33ba4
6
+ metadata.gz: ece668019a30ae4d48910e838212c409f303aeba53bcaf64e8867edf2e7034fa4da5f6a13693093300a9ecf86c0d6f0e5133a0f0bd6f8caa782a2000b5a033ed
7
+ data.tar.gz: 0cf961fa42da0e35c301ef9e800869a9e871563e347d054cc8d3ac3e480d128fe53bc9ff9dfce823b0e1a99f79b3ff216f794d9d6ac9bfcef83331701ff15efc
data/README.md CHANGED
@@ -24,6 +24,47 @@ bfx = BetterFx::Client.new
24
24
  bfx.gauge :soccer_ball_air_pressure, value: 11
25
25
  ```
26
26
 
27
+ ## OO functionality
28
+
29
+ Usually you'll be reporting the same measurement over and over and the gauge syntax is a bit
30
+ too functional
31
+
32
+ In the following example we have an imaginary worker that is invoked like so:
33
+
34
+ ```ruby
35
+ TelemetricWorker.new.run
36
+ ```
37
+
38
+ It's implementation is ...
39
+
40
+ ```ruby
41
+ class TelemetricWorker
42
+ include BetterFx::Measurement
43
+ attr_accessor :filename
44
+
45
+ measurement :file_size do |worker|
46
+ File.size worker.filename
47
+ end
48
+
49
+ def step_gets_file
50
+ # get file from s3
51
+ end
52
+
53
+ def step_does_other_thing
54
+ # use your imagination
55
+ end
56
+
57
+ def run
58
+ step_gets_file
59
+ measure :file_size
60
+ step_does_other_thing
61
+ end
62
+ end
63
+ ```
64
+
65
+ This way everytime `#run` is executed the file_size measurement is sent to SignalFx. Note this functionality is
66
+ currently available for measurements (gauges) only.
67
+
27
68
  ## Configuration
28
69
 
29
70
  To use BetterFx with the least amount of code, just set the environment variable
data/better_fx.gemspec CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.homepage =
17
17
  "https://github.com/Referly/better_fx"
18
18
  s.add_runtime_dependency "signalfx", "~> 0.1" # Apache2 - @link https://github.com/signalfx/signalfx-ruby
19
+ s.add_runtime_dependency "activesupport", "~> 4" # MIT - @link https://github.com/rails/rails/blob/master/activesupport/MIT-LICENSE
19
20
  s.add_development_dependency "rspec", "~> 3.2" # MIT - @link https://github.com/rspec/rspec/blob/master/License.txt
20
21
  s.add_development_dependency "byebug", "~> 3.5" # BSD (content is BSD) https://github.com/deivid-rodriguez/byebug/blob/master/LICENSE
21
22
  s.add_development_dependency "simplecov", "~> 0.10" # MIT - @link https://github.com/colszowka/simplecov/blob/master/MIT-LICENSE
@@ -3,12 +3,14 @@ module BetterFx
3
3
  class Configuration
4
4
  attr_accessor :signalfx_api_token,
5
5
  :supported_environments,
6
- :current_environment
6
+ :current_environment,
7
+ :signalfx_metric_namespace
7
8
 
8
9
  def initialize
9
10
  @signalfx_api_token = ENV["SIGNALFX_API_TOKEN"]
10
11
  @supported_environments = [:production, :prod, "production", "prod"]
11
12
  @current_environment = ENV["APP_ENV"] || :production
13
+ @signalfx_metric_namespace = ENV["SIGNALFX_METRIC_NAMESPACE"] || :better_fx
12
14
  end
13
15
  end
14
16
  end
@@ -0,0 +1,64 @@
1
+ require "active_support/inflector"
2
+ module BetterFx
3
+ # A mixin for creating declarative telemetry to send
4
+ # to BetterFx (plan being to move this into BetterFx)
5
+ module Measurement
6
+ def self.included(mod)
7
+ mod.extend ClassMethods
8
+ mod.send :include, InstanceMethods
9
+ end
10
+ # Instance methods
11
+ module InstanceMethods
12
+ # Perform a measurement and send the results
13
+ # to the Telemetry system
14
+ #
15
+ # @param name [String, Symbol] the name of the measurement to perform
16
+ def measure(name, _opts = {})
17
+ name = name.to_s
18
+ prok = self.class.measurements[name]
19
+ value = prok ? prok.call(self) : nil
20
+ return unless value
21
+ fq_gauge_name = self.class.gauge_name name
22
+ self.class.bfx.gauge fq_gauge_name, value: value
23
+ value
24
+ end
25
+ end
26
+
27
+ # Class methods
28
+ module ClassMethods
29
+ # Defines a measurement
30
+ #
31
+ # @param name [String, Symbol] the name of the measurement (measurement names
32
+ # are inherently namespaced by class so should just use a meaningful name. It will
33
+ # show up in the telemetry system as gauge.$CLASS.name)
34
+ # @param blk [Block] you must provide a block which contains the code for performing
35
+ # the measurement; the block must return the value of the measurement
36
+ def measurement(name, _opts = {}, &blk)
37
+ name = name.to_s
38
+ @_measurements ||= {}
39
+ @_measurements[name] = blk
40
+ end
41
+
42
+ # Returns all of the defined measurements
43
+ #
44
+ # @return [Hash] the measurements with names as keys and procs as values
45
+ def measurements
46
+ @_measurements
47
+ end
48
+
49
+ # A memoized BetterFx Client instance
50
+ #
51
+ # @return [BetterFx::Client] a BetterFx client
52
+ def bfx
53
+ @_bfx ||= BetterFx::Client.new
54
+ end
55
+
56
+ # Generates the fully qualified gauge name
57
+ #
58
+ # @param measurement_name [String, Symbol] the name of the measurement
59
+ def gauge_name(measurement_name)
60
+ "#{BetterFx.configuration.signalfx_metric_namespace}.#{name.to_s.underscore.downcase}.#{measurement_name}".tr "/", "."
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,4 +1,4 @@
1
1
  module BetterFx
2
- VERSION = "0.2.0".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  VERSION_DATE = "2016-10-13".freeze
4
4
  end
data/lib/better_fx.rb CHANGED
@@ -3,6 +3,7 @@ require "signalfx"
3
3
  SignalFxClient.send :alias_method, :bf_xmit, :send
4
4
  require_relative "better_fx/configuration"
5
5
  require_relative "better_fx/client"
6
+ require_relative "better_fx/measurement"
6
7
  module BetterFx
7
8
  class << self
8
9
  # Allows the user to set configuration options
@@ -0,0 +1,76 @@
1
+ require "spec_helper"
2
+
3
+ describe BetterFx::Measurement do
4
+ module TestClasses
5
+ class Telemetric
6
+ include BetterFx::Measurement
7
+
8
+ def inst_method
9
+ "instance method found"
10
+ end
11
+ end
12
+ class OtherTelemetric
13
+ include BetterFx::Measurement
14
+ end
15
+ end
16
+
17
+ let(:k1) { TestClasses::Telemetric }
18
+ let(:k2) { TestClasses::OtherTelemetric }
19
+ let(:mock_fx) { double "BetterFxClient", gauge: true }
20
+ before do
21
+ k1.instance_variable_set :@_bfx, nil
22
+ k2.instance_variable_set :@_bfx, nil
23
+ allow(BetterFx::Client).to receive(:new).and_return mock_fx
24
+ end
25
+ describe "defining a measurement" do
26
+ describe ".measurement" do
27
+ it "defines a new measurement of the specified name" do
28
+ k1.measurement :foo do
29
+ 5
30
+ end
31
+ expect(k1.new.measure(:foo)).to eq 5
32
+ end
33
+ it "isolates measurements by class" do
34
+ k1.measurement :foo do
35
+ 5
36
+ end
37
+ k2.measurement :foo do
38
+ 12
39
+ end
40
+ expect(k1.instance_variable_get(:@_measurements)["foo"]).to be_a Proc
41
+ expect(k1.instance_variable_get(:@_measurements)["foo"].call).to eq 5
42
+ expect(k2.instance_variable_get(:@_measurements)["foo"]).to be_a Proc
43
+ expect(k2.instance_variable_get(:@_measurements)["foo"].call).to eq 12
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "performing a measurement" do
49
+ describe "#measure" do
50
+ let(:prok) { proc { 123 } }
51
+ let(:instance_of_k1) { k1.new }
52
+ before do
53
+ k1.measurement :foo, &prok
54
+ end
55
+
56
+ it "executes the proc associated with the measurement name" do
57
+ expect(prok).to receive :call
58
+ k1.new.measure :foo
59
+ end
60
+
61
+ it "sends the result of the proc to BetterFx" do
62
+ expect(mock_fx).to receive(:gauge).with(k1.gauge_name(:foo), hash_including(value: 123))
63
+ instance_of_k1.measure :foo
64
+ end
65
+
66
+ it "returns the result of the proc" do
67
+ expect(instance_of_k1.measure(:foo)).to eq prok.call
68
+ end
69
+
70
+ it "yields the current instance to the block" do
71
+ k1.measurement :bar, &:inst_method
72
+ expect(instance_of_k1.measure(:bar)).to eq "instance method found"
73
+ end
74
+ end
75
+ end
76
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_fx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Courtland Caldwell
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '4'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -110,8 +124,10 @@ files:
110
124
  - lib/better_fx.rb
111
125
  - lib/better_fx/client.rb
112
126
  - lib/better_fx/configuration.rb
127
+ - lib/better_fx/measurement.rb
113
128
  - lib/better_fx/version.rb
114
129
  - spec/better_fx/client_spec.rb
130
+ - spec/better_fx/telemetry_spec.rb
115
131
  - spec/better_fx_spec.rb
116
132
  - spec/simplecov_custom_profile.rb
117
133
  - spec/spec_helper.rb
@@ -142,6 +158,7 @@ specification_version: 4
142
158
  summary: A more idiomatic interface to SignalFx.
143
159
  test_files:
144
160
  - spec/better_fx/client_spec.rb
161
+ - spec/better_fx/telemetry_spec.rb
145
162
  - spec/better_fx_spec.rb
146
163
  - spec/simplecov_custom_profile.rb
147
164
  - spec/spec_helper.rb