Skip to content

Commit 32bafcc

Browse files
authored
Merge pull request #114 from ChrisBr/cb/block-instrumentation
Implement block instrumentation
2 parents b0866c8 + 0528a25 commit 32bafcc

File tree

9 files changed

+167
-9
lines changed

9 files changed

+167
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ For the full commit log, [see here](https://github.com/influxdata/influxdb-rails
1313
- Implement `enqueue.active_job` subscriber (https://guides.rubyonrails.org/active_support_instrumentation.html#enqueue-active-job)
1414
- Implement `perform_start.active_job` subscriber (https://guides.rubyonrails.org/active_support_instrumentation.html#perform-start-active-job)
1515
- Implement `perform.active_job` subscriber (https://guides.rubyonrails.org/active_support_instrumentation.html#perform-active-job)
16+
- Implement block instrumentation `InfluxDB::Rails.instrument do; 1 + 1; end`
1617

1718
## v1.0.0, released 2019-10-23
1819
The Final release, no code changes.

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,44 @@ class ApplicationController
176176
end
177177
```
178178

179+
### Block Instrumentation
180+
If you want to add custom instrumentation, you can wrap any code into a block instrumentation
181+
182+
```ruby
183+
InfluxDB::Rails.instrument "expensive_operation", tags: { }, values: { } do
184+
expensive_operation
185+
end
186+
```
187+
188+
Reported tags:
189+
190+
```ruby
191+
hook: "block_instrumentation"
192+
server: Socket.gethostname,
193+
app_name: configuration.application_name,
194+
location: "PostsController#index",
195+
name: "expensive_operation"
196+
```
197+
198+
Reported values:
199+
```ruby
200+
value: 100 # execution time of the block
201+
```
202+
203+
You can also overwrite the `value`
204+
205+
```ruby
206+
InfluxDB::Rails.instrument "user_count", values: { value: 1 } do
207+
User.create(name: 'mickey', surname: 'mouse')
208+
end
209+
```
210+
211+
or call it even without a block
212+
213+
```ruby
214+
InfluxDB::Rails.instrument "temperature", values: { value: 25 }
215+
```
216+
179217
### Custom client configuration
180218

181219
The settings named `config.client.*` are used to construct an `InfluxDB::Client`

lib/influxdb-rails.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require "net/https"
33
require "rubygems"
44
require "socket"
5+
require "influxdb/rails/middleware/block_instrumentation_subscriber"
56
require "influxdb/rails/middleware/render_subscriber"
67
require "influxdb/rails/middleware/request_subscriber"
78
require "influxdb/rails/middleware/sql_subscriber"
@@ -60,6 +61,13 @@ def configuration
6061
def current
6162
@current ||= InfluxDB::Rails::Context.new
6263
end
64+
65+
def instrument(name, options = {})
66+
ActiveSupport::Notifications.instrument "block_instrumentation.influxdb_rails",
67+
**options.merge(name: name) do
68+
yield if block_given?
69+
end
70+
end
6371
end
6472
end
6573
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
require "influxdb/rails/middleware/subscriber"
2+
3+
module InfluxDB
4+
module Rails
5+
module Middleware
6+
class BlockInstrumentationSubscriber < Subscriber
7+
def values(_start, duration, payload)
8+
{
9+
value: duration,
10+
}.merge(payload[:values].to_h)
11+
end
12+
13+
def tags(payload)
14+
{
15+
hook: "block_instrumentation",
16+
name: payload[:name],
17+
}.merge(payload[:tags].to_h)
18+
end
19+
end
20+
end
21+
end
22+
end

lib/influxdb/rails/railtie.rb

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@ class Railtie < ::Rails::Railtie # :nodoc:
2525
ActiveSupport::Notifications.subscribe "start_processing.action_controller", &cache
2626

2727
{
28-
"process_action.action_controller" => Middleware::RequestSubscriber,
29-
"render_template.action_view" => Middleware::RenderSubscriber,
30-
"render_partial.action_view" => Middleware::RenderSubscriber,
31-
"render_collection.action_view" => Middleware::RenderSubscriber,
32-
"sql.active_record" => Middleware::SqlSubscriber,
33-
"instantiation.active_record" => Middleware::ActiveRecordSubscriber,
34-
"enqueue.active_job" => Middleware::ActiveJobSubscriber,
35-
"perform_start.active_job" => Middleware::ActiveJobSubscriber,
36-
"perform.active_job" => Middleware::ActiveJobSubscriber,
28+
"process_action.action_controller" => Middleware::RequestSubscriber,
29+
"render_template.action_view" => Middleware::RenderSubscriber,
30+
"render_partial.action_view" => Middleware::RenderSubscriber,
31+
"render_collection.action_view" => Middleware::RenderSubscriber,
32+
"sql.active_record" => Middleware::SqlSubscriber,
33+
"instantiation.active_record" => Middleware::ActiveRecordSubscriber,
34+
"enqueue.active_job" => Middleware::ActiveJobSubscriber,
35+
"perform_start.active_job" => Middleware::ActiveJobSubscriber,
36+
"perform.active_job" => Middleware::ActiveJobSubscriber,
37+
"block_instrumentation.influxdb_rails" => Middleware::BlockInstrumentationSubscriber,
3738
}.each do |hook_name, subscriber_class|
3839
subscribe_to(hook_name, subscriber_class)
3940
end
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
require File.dirname(__FILE__) + "/../spec_helper"
2+
3+
RSpec.describe "BlockInstrumentation metrics", type: :request do
4+
let(:tags_middleware) do
5+
lambda do |tags|
6+
tags.merge(tags_middleware: :tags_middleware)
7+
end
8+
end
9+
before do
10+
allow_any_instance_of(ActionDispatch::Request).to receive(:request_id).and_return(:request_id)
11+
allow_any_instance_of(InfluxDB::Rails::Configuration).to receive(:application_name).and_return(:app_name)
12+
allow_any_instance_of(InfluxDB::Rails::Configuration).to receive(:tags_middleware).and_return(tags_middleware)
13+
end
14+
15+
it "writes metric" do
16+
get "/metrics"
17+
18+
expect_metric(
19+
tags: a_hash_including(
20+
location: "MetricsController#index",
21+
hook: "block_instrumentation",
22+
additional_tag: :value,
23+
server: Socket.gethostname,
24+
app_name: :app_name,
25+
tags_middleware: :tags_middleware,
26+
block_tag: :block_tag,
27+
name: "name"
28+
),
29+
values: a_hash_including(
30+
additional_value: :value,
31+
request_id: :request_id,
32+
block_value: :block_value,
33+
value: be_between(1, 30)
34+
)
35+
)
36+
end
37+
38+
it "includes correct timestamps" do
39+
travel_to Time.zone.local(2018, 1, 1, 9, 0, 0)
40+
41+
get "/metrics"
42+
43+
expect_metric(
44+
tags: a_hash_including(
45+
location: "MetricsController#index",
46+
hook: "block_instrumentation"
47+
),
48+
timestamp: 1_514_797_200
49+
)
50+
end
51+
52+
it "does not write metric when hook is ignored" do
53+
allow_any_instance_of(InfluxDB::Rails::Configuration).to receive(:ignored_hooks).and_return(["block_instrumentation.influxdb_rails"])
54+
55+
get "/metrics"
56+
57+
expect_no_metric(
58+
tags: a_hash_including(
59+
location: "MetricsController#index",
60+
hook: "block_instrumentation"
61+
)
62+
)
63+
end
64+
end

spec/support/rails5/app.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class MetricsController < ApplicationController
4949
end
5050

5151
def index
52+
InfluxDB::Rails.instrument "name", tags: { block_tag: :block_tag }, values: { block_value: :block_value } do
53+
1 + 1
54+
end
5255
MetricJob.perform_later
5356
Metric.create!(name: "name")
5457
end

spec/support/rails6/app.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class MetricsController < ApplicationController
4949
end
5050

5151
def index
52+
InfluxDB::Rails.instrument "name", tags: { block_tag: :block_tag }, values: { block_value: :block_value } do
53+
1 + 1
54+
end
5255
MetricJob.perform_later
5356
Metric.create!(name: "name")
5457
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require "spec_helper"
2+
3+
RSpec.describe InfluxDB::Rails do
4+
describe ".instrument" do
5+
it "supports calling wihout a block" do
6+
InfluxDB::Rails.instrument "name", values: { value: 1 }
7+
8+
expect_metric(
9+
values: a_hash_including(value: 1),
10+
tags: a_hash_including(
11+
hook: "block_instrumentation",
12+
server: Socket.gethostname,
13+
location: :raw
14+
)
15+
)
16+
end
17+
end
18+
end

0 commit comments

Comments
 (0)