solid_apm 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6159733df2a423e8080f5d8e118ead35dc63e70cd7ce41c0dd1b82c33922b07
4
- data.tar.gz: 99752422f96489651453e355e358e8c60cf9c02ae52de2793d475a03599ce796
3
+ metadata.gz: c6233330338e9044097e1315840f1bbc7f2cdeb1677df3dac3261c2a50666046
4
+ data.tar.gz: 37f306cf60295e74485092216c4bdbe2ba2c824ce08d279424e15c631543b33f
5
5
  SHA512:
6
- metadata.gz: 2c41be36b7d999e112c283247062740eca1bbc27b150329e3300385ec40f4e983efdf2f47ac25f4c6e176b6f605a19894368d85dda8e69e826c4a02afafb745a
7
- data.tar.gz: 9ee48dc1a610c5e2726908bbb78ed526ef1d62641d894af558ea932022c77308f11ef6ec392565f8ad96e3815ecaadf1d36acc4a43d245569c372ae198c59aa2
6
+ metadata.gz: 18d46f142b8bc401acc9dcd3417c9782d04a6e2beabda8d3c7dbafd62429f8bcf13e69ecf2e7fe51049f17da8b35411c3b1239c3f9476950590917990d0c7aba
7
+ data.tar.gz: a0140e3fdb51254f8c615ed7cd4002f851d0c1ef11b71d408c4966581b1638f475ada593977a53761631493201e53641df382b9c8d9c10598935fe7ae8b50da3
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Jean-Francis Bastien
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
+ [![Gem Version](https://badge.fury.io/rb/solid_apm.svg)](https://badge.fury.io/rb/solid_apm)
2
+
1
3
  # SolidApm
2
4
  Rails engine to manage APM data without using a third party service.
3
5
 
4
- <img src="https://github.com/Bhacaz/solid_apm/assets/7858787/b83a4768-dbff-4c1c-8972-4b9db1092c99" width="400px">
5
- <img src="https://github.com/Bhacaz/solid_apm/assets/7858787/87696866-1fb3-46d6-91ae-0137cc7da578" width="400px">
6
-
6
+ <img src="./docs/img.png" width="400px">
7
+ <img src="./docs/img_1.png" width="400px">
7
8
 
8
9
  ## Installation
9
10
 
@@ -21,6 +22,10 @@ Rails.application.routes.draw do
21
22
  end
22
23
  ```
23
24
 
25
+ Routing constraint can be use to authorize access.
26
+ See [Routing constraint](https://guides.rubyonrails.org/routing.html#advanced-constraints)
27
+ for more information.
28
+
24
29
  Configure the database connection:
25
30
  ```ruby
26
31
  # config/initializers/solid_apm.rb
@@ -36,22 +41,38 @@ DATABASE=solid_apm bin/rails solid_apm:install:migrations
36
41
 
37
42
  Go to `http://localhost:3000/solid_apm` and start monitoring your application.
38
43
 
44
+ Add context
45
+
46
+ ```ruby
47
+ class ApplicationController
48
+ before_action do
49
+ SolidApm.set_context(user_id: current_user&.id)
50
+ end
51
+ end
52
+ ```
53
+
39
54
  ## TODOs
40
55
 
41
56
  ### Features
42
57
 
43
- - [ ] Ignore `/solid_apm` requests
44
58
  - [ ] Better handle subscribing to ActiveSupport notifications
45
- - [ ] Add methods to add context to the transaction (i.e. `SolidApm.add_context(user_id: 1)`)
59
+ - [ ] Custom events
46
60
 
47
61
  ### Interface
48
62
 
49
63
  - [ ] Paginate transactions list
50
64
  - [ ] Allow date range transactions index
51
- - [ ] Display transaction as aggregated data with avg latency, tpm and impact (Relative Avg. duration * transactions per minute)
52
65
 
53
66
  ## Contributing
54
67
  Contribution directions go here.
55
68
 
69
+ ## Release
70
+
71
+ ```shell
72
+ gem bump -v minor
73
+ bundle install && git add . && git commit --amend --no-edit
74
+ gem tag -p
75
+ ```
76
+
56
77
  ## License
57
78
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -13,7 +13,9 @@ import {
13
13
  // Connects to data-controller="transaction-chart"
14
14
  window.Stimulus.register('transaction-chart',
15
15
  class extends Controller {
16
- connect() {
16
+ static values = { name: String }
17
+
18
+ connect() {
17
19
  console.log('Connected')
18
20
  var options = {
19
21
  chart: {
@@ -34,7 +36,13 @@ window.Stimulus.register('transaction-chart',
34
36
  }
35
37
  }
36
38
  }
37
- fetch('transactions.json')
39
+
40
+ let path = 'transactions/count_by_minutes'
41
+ if (this.nameValue) {
42
+ path = path + "?name=" + encodeURIComponent(this.nameValue);
43
+ }
44
+
45
+ fetch(path)
38
46
  .then(response => response.json())
39
47
  .then(data => {
40
48
  const transformedData = []
@@ -2,21 +2,35 @@
2
2
 
3
3
  module SolidApm
4
4
  class TransactionsController < ApplicationController
5
+ TransactionAggregation = Struct.new(:name, :tmp, :latency, :impact)
6
+
5
7
  def index
6
- @transactions = Transaction.all.order(timestamp: :desc).limit(10)
7
-
8
- # uri = URI('https://dog-api.kinduff.com/api/facts')
9
- # response = Net::HTTP.get(uri)
10
- # @dog_fact = JSON.parse(response)
11
- #
12
- # Rails.cache.fetch('dog_fact', expires_in: 1.minutes) do
13
- # 'This is a dog fact!'
14
- # end
15
-
16
- respond_to do |format|
17
- format.html
18
- format.json { render json: transactions_count_by_minutes }
8
+ @aggregated_transactions = Transaction.where(created_at: 1.hour.ago..).group_by(&:name)
9
+ @aggregated_transactions.transform_values! do |transactions|
10
+ latency = transactions.map(&:duration).sum / transactions.size
11
+ tmp = transactions.size.to_f / 60
12
+ impact = latency * tmp
13
+ TransactionAggregation.new(
14
+ transactions.first.name,
15
+ tmp,
16
+ latency,
17
+ impact
18
+ )
19
+ end
20
+ # Find the maximum and minimum impact values
21
+ max_impact = @aggregated_transactions.values.max_by(&:impact).impact
22
+ min_impact = @aggregated_transactions.values.min_by(&:impact).impact
23
+
24
+ # Normalize impact 0-100
25
+ @aggregated_transactions.each do |_, aggregation|
26
+ normalized_impact = ((aggregation.impact - min_impact) / (max_impact - min_impact)) * 100
27
+ aggregation.impact = normalized_impact.to_i
19
28
  end
29
+ @aggregated_transactions = @aggregated_transactions.sort_by { |_, v| -v.impact }.to_h
30
+ end
31
+
32
+ def show_by_name
33
+ @transactions = Transaction.where(name: params[:name]).order(timestamp: :desc).limit(20)
20
34
  end
21
35
 
22
36
  def show
@@ -29,13 +43,16 @@ module SolidApm
29
43
  render json: @spans
30
44
  end
31
45
 
32
- private
33
-
34
- def transactions_count_by_minutes
35
- Transaction.all.order(timestamp: :desc)
46
+ def count_by_minutes
47
+ scope = Transaction.all.order(timestamp: :desc)
36
48
  .where(created_at: 1.hour.ago..)
37
- .group_by { |t| t.created_at.beginning_of_minute }
38
- .transform_values!(&:count)
49
+
50
+ if params[:name].present?
51
+ scope = scope.where(name: params[:name])
52
+ end
53
+
54
+ render json: scope.group_by { |t| t.created_at.beginning_of_minute }
55
+ .transform_values!(&:count)
39
56
  end
40
57
  end
41
- end
58
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidApm
4
+ module SpanSubscriber
5
+ class ActionDispatch < Base
6
+ PATTERN = /\w+\.action_dispatch/.freeze
7
+ def self.subscribe
8
+ super do |name, start, finish, id, payload|
9
+ transaction = SpanSubscriber::Base.transaction
10
+ transaction.name = "#{payload[:request].controller_class}##{payload[:request].path_parameters[:action]}"
11
+ transaction.end_time = finish
12
+ transaction.duration = ((transaction.end_time.to_f - transaction.timestamp.to_f) * 1000).round(6)
13
+ transaction.metadata = {
14
+ params: payload[:request].params.except(:controller, :action),
15
+ context: SpanSubscriber::Base.context
16
+ }
17
+ SpanSubscriber::Base.context = nil
18
+ end
19
+ end
20
+
21
+ def summary(payload)
22
+ "#{payload[:request].controller_class}##{payload[:request].path_parameters[:action]}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,37 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidApm
4
- module SpanSubscriber
5
- class ActionViewRender < Base
6
- PATTERN = /^render_.+\.action_view/
4
+ module SpanSubscriber
5
+ class ActionViewRender < Base
6
+ PATTERN = /^render_.+\.action_view/
7
7
 
8
- def summary(payload)
9
- identifier = payload[:identifier]
10
- sanitize_path(identifier)
11
- end
8
+ def summary(payload)
9
+ identifier = payload[:identifier]
10
+ sanitize_path(identifier)
11
+ end
12
12
 
13
- private
13
+ private
14
14
 
15
- def sanitize_path(path)
16
- if path.start_with? Rails.root.to_s
17
- app_path(path)
18
- else
19
- gem_path(path)
15
+ def sanitize_path(path)
16
+ if path.start_with? Rails.root.to_s
17
+ app_path(path)
18
+ else
19
+ gem_path(path)
20
+ end
20
21
  end
21
- end
22
22
 
23
- def app_path(path)
24
- return unless path.start_with? Rails.root.to_s
23
+ def app_path(path)
24
+ return unless path.start_with? Rails.root.to_s
25
25
 
26
- format '$APP_PATH%s', path[Rails.root.to_s.length, path.length]
27
- end
26
+ format '$APP_PATH%s', path[Rails.root.to_s.length, path.length]
27
+ end
28
28
 
29
- def gem_path(path)
30
- root = Gem.path.find { |gp| path.start_with? gp }
31
- return unless root
29
+ def gem_path(path)
30
+ root = Gem.path.find { |gp| path.start_with? gp }
31
+ return unless root
32
32
 
33
- format '$GEM_PATH%s', path[root.length, path.length]
33
+ format '$GEM_PATH%s', path[root.length, path.length]
34
+ end
34
35
  end
35
36
  end
36
- end
37
37
  end
@@ -1,55 +1,59 @@
1
1
  # frozen_string_literal: true
2
2
  module SolidApm
3
- module SpanSubscriber
4
- class Base
5
- # PATTERN = /.*/
3
+ module SpanSubscriber
4
+ class Base
5
+ # PATTERN = /.*/
6
6
 
7
- class_attribute :subscribers, default: Set.new
8
- thread_cattr_accessor :transaction
9
- thread_cattr_accessor :spans
7
+ class_attribute :subscribers, default: Set.new
8
+ thread_cattr_accessor :transaction
9
+ thread_cattr_accessor :spans
10
+ thread_cattr_accessor :context
10
11
 
11
- def self.inherited(subclass)
12
- subscribers << subclass
13
- end
12
+ def self.inherited(subclass)
13
+ subscribers << subclass
14
+ end
14
15
 
15
- def self.subscribe!
16
- subscribers.each(&:subscribe)
17
- end
16
+ def self.subscribe!
17
+ subscribers.each(&:subscribe)
18
+ end
18
19
 
19
- def self.subscribe
20
- ActiveSupport::Notifications.subscribe(self::PATTERN) do |name, start, finish, id, payload|
21
- next unless SpanSubscriber::Base.transaction
22
-
23
- subtype, type = name.split('.')
24
- duration = ((finish.to_f - start.to_f) * 1000).round(6)
25
-
26
- span = {
27
- uuid: SecureRandom.uuid,
28
- sequence: SpanSubscriber::Base.spans.size + 1,
29
- timestamp: start,
30
- end_time: finish,
31
- duration: duration,
32
- name: name,
33
- type: type,
34
- subtype: subtype,
35
- summary: self.new.summary(payload),
36
- }
37
-
38
- SpanSubscriber::Base.spans << span
20
+ def self.subscribe
21
+ ActiveSupport::Notifications.subscribe(self::PATTERN) do |name, start, finish, id, payload|
22
+ next unless SpanSubscriber::Base.transaction
23
+
24
+ subtype, type = name.split('.')
25
+ duration = ((finish.to_f - start.to_f) * 1000).round(6)
26
+
27
+ span = {
28
+ uuid: SecureRandom.uuid,
29
+ sequence: SpanSubscriber::Base.spans.size + 1,
30
+ timestamp: start,
31
+ end_time: finish,
32
+ duration: duration,
33
+ name: name,
34
+ type: type,
35
+ subtype: subtype,
36
+ summary: self.new.summary(payload),
37
+ }
38
+
39
+ SpanSubscriber::Base.spans << span
40
+
41
+ # Allow the subscriber to yield additional spans, like ending the transaction
42
+ yield(name, start, finish, id, payload) if block_given?
43
+ end
39
44
  end
40
- end
41
45
 
42
- # def summary(payload)
43
- # if payload.is_a?(Hash)
44
- # payload.first.last.inspect
45
- # else
46
- # payload.inspect
47
- # end
48
- # end
46
+ # def summary(payload)
47
+ # if payload.is_a?(Hash)
48
+ # payload.first.last.inspect
49
+ # else
50
+ # payload.inspect
51
+ # end
52
+ # end
49
53
 
50
- # private_class_method :subscribe
54
+ # private_class_method :subscribe
55
+ end
51
56
  end
52
57
  end
53
- end
54
58
 
55
59
  Dir[File.join(__dir__, '*.rb')].sort.each { |file| require file }
@@ -3,27 +3,24 @@
3
3
  <h2 class="title is-4 has-text-grey">Last hour</h2>
4
4
  <div data-controller="transaction-chart"></div>
5
5
 
6
- <table class="table">
6
+ <table class="table is-fullwidth">
7
7
  <thead>
8
8
  <tr>
9
- <% SolidApm::Transaction.attribute_names.each do |attribute| %>
10
- <% next if attribute.to_s.end_with?('_at') %>
11
- <th scope="col"><%= attribute.humanize %></th>
12
- <% end %>
9
+ <th>Name</th>
10
+ <th>Latency</th>
11
+ <th>tmp</th>
12
+ <th>Impact</th>
13
13
  </tr>
14
14
  </thead>
15
- <tbody>
16
- <% @transactions.each do |transaction| %>
15
+
16
+ <% @aggregated_transactions.each do |name, aggregation| %>
17
17
  <tr>
18
- <% transaction.attributes.each do |attribute| %>
19
- <% next if attribute[0].to_s.end_with?('_at') %>
20
- <% if attribute[0] == 'uuid' %>
21
- <td><%= link_to attribute[1], transaction %></td>
22
- <% else %>
23
- <td><%= attribute[1] %></td>
24
- <% end %>
25
- <% end %>
18
+ <td><%= link_to name, transaction_by_name_path(name) %></td>
19
+ <td><%= aggregation.latency.round(2) %> ms</td>
20
+ <td><%= aggregation.tmp.round(2) %></td>
21
+ <td>
22
+ <progress class="progress is-warning" value="<%= aggregation.impact %>" max="100"></progress>
23
+ </td>
26
24
  </tr>
27
25
  <% end %>
28
- </tbody>
29
26
  </table>
@@ -3,6 +3,7 @@
3
3
  <h2 class="title is-6"><span class="has-text-grey-dark">Trace ID:</span> <%= @transaction.uuid %></h2>
4
4
  <h2 class="title is-6"><span class="has-text-grey-dark">Timestamp:</span> <%= @transaction.timestamp %></h2>
5
5
  <h2 class="title is-6"><span class="has-text-grey-dark">Duration:</span> <%= @transaction.duration %> ms</h2>
6
+ <h2 class="title is-6"><span class="has-text-grey-dark">Unix minute:</span> <%= @transaction.unix_minute %></h2>
6
7
  <h2 class="title is-6"><span class="has-text-grey-dark">Metadata:</span> <%= @transaction.metadata %></h2>
7
8
 
8
9
  <%= render template: 'solid_apm/spans/index', collection: @transaction.spans, locals: { spans: @transaction.spans } %>
@@ -0,0 +1,27 @@
1
+ <h1 class="title is-3"><%= params[:name] %></h1>
2
+ <div data-controller="transaction-chart" data-transaction-chart-name-value="<%= params[:name] %>"></div>
3
+
4
+ <table class="table">
5
+ <thead>
6
+ <tr>
7
+ <% SolidApm::Transaction.attribute_names.each do |attribute| %>
8
+ <% next if attribute.to_s.end_with?('_at') %>
9
+ <th scope="col"><%= attribute.humanize %></th>
10
+ <% end %>
11
+ </tr>
12
+ </thead>
13
+ <tbody>
14
+ <% @transactions.each do |transaction| %>
15
+ <tr>
16
+ <% transaction.attributes.each do |attribute| %>
17
+ <% next if attribute[0].to_s.end_with?('_at') %>
18
+ <% if attribute[0] == 'uuid' %>
19
+ <td><%= link_to attribute[1], transaction_path(transaction) %></td>
20
+ <% else %>
21
+ <td><%= attribute[1] %></td>
22
+ <% end %>
23
+ <% end %>
24
+ </tr>
25
+ <% end %>
26
+ </tbody>
27
+ </table>
data/config/routes.rb CHANGED
@@ -2,6 +2,12 @@ SolidApm::Engine.routes.draw do
2
2
  root 'transactions#index'
3
3
 
4
4
  get 'transactions', to: 'transactions#index'
5
- get 'transactions/:id', to: 'transactions#show', as: 'transaction'
5
+ get 'transactions/count_by_minutes',
6
+ to: 'transactions#count_by_minutes',
7
+ as: 'transactions_count_by_minutes',
8
+ default: { format: 'json' }
9
+
10
+ get 'transactions/:id', to: 'transactions#show', as: 'transaction', constraints: { id: /\d+/ }
11
+ get 'transactions/:name', to: 'transactions#show_by_name', as: 'transaction_by_name'
6
12
  get 'transactions/:id/spans', to: 'transactions#spans', as: 'transaction_spans'
7
13
  end
@@ -11,24 +11,6 @@ module SolidApm
11
11
  end
12
12
 
13
13
  config.after_initialize do
14
- ActiveSupport::Notifications.subscribe("start_processing.action_controller") do |name, start, finish, id, payload|
15
- SpanSubscriber::Base.transaction = Transaction.new(
16
- uuid: SecureRandom.uuid,
17
- timestamp: start,
18
- type: 'request',
19
- name: "#{payload[:controller]}##{payload[:action]}",
20
- metadata: { params: payload[:request].params.except(:controller, :action) }
21
- )
22
- SpanSubscriber::Base.spans = []
23
- end
24
-
25
- ActiveSupport::Notifications.subscribe("process_action.action_controller") do |name, start, finish, id, payload|
26
- # Set the end time and duration of the transaction with the process_action event
27
- transaction = SpanSubscriber::Base.transaction
28
- transaction.end_time = finish
29
- transaction.duration = ((transaction.end_time.to_f - transaction.timestamp.to_f) * 1000).round(6)
30
- end
31
-
32
14
  SpanSubscriber::Base.subscribe!
33
15
  end
34
16
  end
@@ -1,28 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidApm
4
- class Middleware
4
+ class Middleware
5
5
  def initialize(app)
6
6
  @app = app
7
7
  end
8
8
 
9
9
  def call(env)
10
- env['rack.after_reply'] ||= []
11
- env['rack.after_reply'] << ->() do
12
- self.class.call
13
- rescue StandardError => e
14
- Rails.logger.error e
15
- Rails.logger.error e.backtrace&.join("\n")
16
- end
10
+ self.class.init_transaction
11
+ status, headers, body = @app.call(env)
17
12
 
18
- @app.call(env)
13
+ env['rack.after_reply'] ||= []
14
+ env['rack.after_reply'] << ->() do
15
+ self.class.call
16
+ rescue StandardError => e
17
+ Rails.logger.error e
18
+ Rails.logger.error e.backtrace&.join("\n")
19
+ end
20
+ [status, headers, body]
19
21
  end
20
22
 
21
23
  def self.call
22
24
  transaction = SpanSubscriber::Base.transaction
23
- return unless transaction
24
-
25
25
  SpanSubscriber::Base.transaction = nil
26
+ if transaction.nil? || transaction.name.start_with?('SolidApm::')
27
+ SpanSubscriber::Base.spans = nil
28
+ return
29
+ end
30
+
26
31
  ApplicationRecord.transaction do
27
32
  transaction.save!
28
33
 
@@ -33,5 +38,17 @@ class Middleware
33
38
  end
34
39
  SpanSubscriber::Base.spans = nil
35
40
  end
41
+
42
+ def self.init_transaction
43
+ now = Time.zone.now
44
+ SpanSubscriber::Base.transaction = Transaction.new(
45
+ uuid: SecureRandom.uuid,
46
+ timestamp: now,
47
+ unix_minute: (now.to_f / 60).to_i,
48
+ type: 'request'
49
+ )
50
+ SpanSubscriber::Base.spans = []
51
+ SpanSubscriber::Base.transaction
52
+ end
36
53
  end
37
54
  end
@@ -1,3 +1,3 @@
1
1
  module SolidApm
2
- VERSION = "0.1.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/solid_apm.rb CHANGED
@@ -3,4 +3,8 @@ require "solid_apm/engine"
3
3
 
4
4
  module SolidApm
5
5
  mattr_accessor :connects_to
6
+
7
+ def self.set_context(context)
8
+ SpanSubscriber::Base.context = context
9
+ end
6
10
  end
metadata CHANGED
@@ -1,36 +1,79 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Francis Bastien
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-10 00:00:00.000000000 Z
11
+ date: 2024-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: actionpack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 7.1.3.2
19
+ version: '7.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 7.1.3.2
27
- description: Description of SolidApm.
26
+ version: '7.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionview
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '7.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '7.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '7.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '7.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: railties
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '7.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '7.1'
69
+ description: SolidApm allow you to monitor your application without any external service.
28
70
  email:
29
71
  - bhacaz@gmail.com
30
72
  executables: []
31
73
  extensions: []
32
74
  extra_rdoc_files: []
33
75
  files:
76
+ - LICENSE
34
77
  - README.md
35
78
  - Rakefile
36
79
  - app/assets/config/solid_apm_manifest.js
@@ -44,7 +87,7 @@ files:
44
87
  - app/jobs/solid_apm/application_job.rb
45
88
  - app/models/solid_apm/application_record.rb
46
89
  - app/models/solid_apm/span.rb
47
- - app/models/solid_apm/span_subscriber/action_controller.rb
90
+ - app/models/solid_apm/span_subscriber/action_dispatch.rb
48
91
  - app/models/solid_apm/span_subscriber/action_view_render.rb
49
92
  - app/models/solid_apm/span_subscriber/active_record_sql.rb
50
93
  - app/models/solid_apm/span_subscriber/active_support_cache.rb
@@ -56,6 +99,7 @@ files:
56
99
  - app/views/solid_apm/spans/index.html.erb
57
100
  - app/views/solid_apm/transactions/index.html.erb
58
101
  - app/views/solid_apm/transactions/show.html.erb
102
+ - app/views/solid_apm/transactions/show_by_name.html.erb
59
103
  - config/routes.rb
60
104
  - db/migrate/20240608015633_create_solid_apm_transactions.rb
61
105
  - db/migrate/20240608021940_create_solid_apm_spans.rb
@@ -68,7 +112,9 @@ homepage: https://github.com/Bhacaz/solid_apm
68
112
  licenses: []
69
113
  metadata:
70
114
  homepage_uri: https://github.com/Bhacaz/solid_apm
71
- post_install_message:
115
+ source_code_uri: https://github.com/Bhacaz/solid_apm
116
+ changelog_uri: https://github.com/Bhacaz/solid_apm/releases
117
+ post_install_message:
72
118
  rdoc_options: []
73
119
  require_paths:
74
120
  - lib
@@ -76,15 +122,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
122
  requirements:
77
123
  - - ">="
78
124
  - !ruby/object:Gem::Version
79
- version: '0'
125
+ version: '3.2'
80
126
  required_rubygems_version: !ruby/object:Gem::Requirement
81
127
  requirements:
82
128
  - - ">="
83
129
  - !ruby/object:Gem::Version
84
130
  version: '0'
85
131
  requirements: []
86
- rubygems_version: 3.5.9
87
- signing_key:
132
+ rubygems_version: 3.5.11
133
+ signing_key:
88
134
  specification_version: 4
89
- summary: Summary of SolidApm.
135
+ summary: SolidApm is a DB base engine for Application Performance Monitoring.
90
136
  test_files: []
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SolidApm
4
- module SpanSubscriber
5
- class ActionController < Base
6
- PATTERN = 'process_action.action_controller'
7
-
8
- def summary(payload)
9
- "#{payload[:controller]}##{payload[:action]}"
10
- end
11
- end
12
- end
13
- end