tpt-rails 1.0.2 → 1.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
  SHA256:
3
- metadata.gz: 2bac9b26e7c559bcd12c7a74894bf5596877561cfc23ba624482571ea47d3cd3
4
- data.tar.gz: ce0b334eb643297400a1f8be459997dcf0011f092bd533ffd491e49f615cad48
3
+ metadata.gz: '069473918c000e049099c5538f36b2e10211e16f4cbfa4adfb2e3f31066b3550'
4
+ data.tar.gz: 1bb6905ec5f83c4e10292550999e70babf5139437878709779935557d4b335ad
5
5
  SHA512:
6
- metadata.gz: ac3ad3e0d29a4aa067195668e002585bdee24c85046e4d0271492ec0d264d80d8acb8a100a832ed331bd1a3b2347ba2ebfa3b4e9874d593da24fd5fa963a40c5
7
- data.tar.gz: eaeef4b7457d511b8d410e4d54ffe1fc92785107a7354aa78c6af207e9b915aa2432bd357804ed34c0194884a39f2741b4b179ea214c7e2a8ab087e9c7e73437
6
+ metadata.gz: f7a28b2dae2af0cd5e5904532c1706ab2b3866c061c9fcae39008e3efee9f163132443597a4e35b524a2720cc5b57c959f43fd30e8e2b415a0d40dde383c4075
7
+ data.tar.gz: ea76d2ca17491bd1e63e19c84913487beabb367c6e7a3a16c8ff3064d50533749c349ed915fd6b406fc979a8f0ac2d4748eb2e46aaf9ea31717b558c14c8277a
data/README.md CHANGED
@@ -62,8 +62,8 @@ See the documentation in [lib/tpt/rails.rb](lib/tpt/rails.rb).
62
62
 
63
63
  ### Error reporting (e.g. Bugsnag/Rollbar)
64
64
 
65
- If you configure `rollbar_access_token` or `bugsnag_api_key` then your project will be automatically
66
- configured to report unhandled exceptions.
65
+ If you configure `rollbar_access_token` & `rollbar_enabled`, or `bugsnag_api_key` then your project
66
+ will be automatically configured to report unhandled exceptions.
67
67
 
68
68
  To report handled exceptions:
69
69
 
@@ -100,12 +100,24 @@ Tpt::Rails provides the following endpoint:
100
100
 
101
101
  This endpoint reports an error via `Tpt::Rails.report` and emits a metric to Datadog.
102
102
 
103
+ ### Puma instrumentation
104
+
105
+ Add the following to `config/puma.rb` to have Puma metrics sent to Datadog:
106
+
107
+ ```ruby
108
+ before_fork do
109
+ Tpt::Rails::PumaStatsCollector.run(metrics_client: Tpt::Rails.statsd)
110
+ end
111
+ ```
112
+
113
+ Note: this currently only collects metrics when running Puma in _clustered_ mode (i.e. w/ more than one worker)
114
+
103
115
  ## Developing this Gem
104
116
 
105
117
  ### Running tests
106
118
 
107
119
  1. Start `docker-compose up` (provides a real Redis instance for tests)
108
- 2. Run `rails test`
120
+ 2. Run `bin/test`
109
121
 
110
122
  ### Using your local version of this gem in a local app
111
123
 
@@ -119,7 +131,7 @@ gem 'tpt-rails', path: '/your/local/path/to/tpt/rails'
119
131
 
120
132
  First ensure you have permissions to publish to rubygems.org.
121
133
 
122
- Then execute:
134
+ Once you've merged, check out the `master` branch and execute:
123
135
  ```sh
124
136
  bundle exec gem bump --push --tag --version patch # patch/minor/major/X.X.X
125
137
  bundle exec gem release
@@ -9,7 +9,7 @@ image:
9
9
 
10
10
  environment:
11
11
  ENVIRONMENT: staging
12
- APP_ENV: production
12
+ APP_ENV: staging
13
13
  RAILS_ENV: production
14
14
 
15
15
  postgresql:
@@ -70,13 +70,14 @@ service:
70
70
  resources:
71
71
  # requests is guaranteed. kubernetes will only put your pod on a node where it can guarantee these
72
72
  # amounts.
73
- requests:
74
- memory: 256Mi
75
- cpu: 200m
76
- # limits is when your pod gets killed for using too many resources
77
- limits:
73
+ requests: &requests
78
74
  memory: 512Mi
79
- cpu: 1
75
+ cpu: 500m
76
+ # limits is when your pod gets killed for using too many resources. normally these should be set
77
+ # the same as the "requests" limit, but if you have a unique workload that requires burstable
78
+ # limits then consult with CloudOps
79
+ limits:
80
+ *requests
80
81
 
81
82
  app:
82
83
  # this configures your service to be available at <%= Tpt::Rails.app_name %>.<ingress_dns_name>
@@ -6,6 +6,7 @@ end
6
6
  require 'tpt/rails/engine'
7
7
  require 'tpt/rails/internal'
8
8
  require 'tpt/rails/config'
9
+ require 'tpt/rails/puma_stats_collector'
9
10
 
10
11
  module Tpt::Rails
11
12
  class NotConfigured < StandardError; end
@@ -19,6 +20,7 @@ module Tpt::Rails
19
20
  # config.app_name = '…'
20
21
  # config.app_env = '…'
21
22
  # config.rollbar_access_token = '…'
23
+ # config.rollbar_enabled = true/false
22
24
  # config.datadog_statsd_url = '…'
23
25
  # config.health_check(:foo) { … }
24
26
  # …
@@ -66,5 +68,10 @@ module Tpt::Rails
66
68
  def config # :nodoc:
67
69
  configured? ? @config : raise(NotConfigured)
68
70
  end
71
+
72
+ # This should be set by the deployment tool. E.g. Jenkins: https://git.io/JJFiD
73
+ def release_version
74
+ ENV['TPT_RELEASE_VERSION'].presence
75
+ end
69
76
  end
70
77
  end
@@ -21,6 +21,8 @@ class Tpt::Rails::Config
21
21
  attr_accessor :redis_url
22
22
  # A project-specific access token from rollbar
23
23
  attr_accessor :rollbar_access_token
24
+ # Allow enabling/disabling Rollbar. Defaults to false.
25
+ attr_accessor :rollbar_enabled
24
26
 
25
27
  # Add a health check to the endpoint provided at `/internal/health-check` by
26
28
  # Tpt::Rails::HealthChecksController.
@@ -64,6 +66,7 @@ class Tpt::Rails::Config
64
66
  @error_reporter = Tpt::Rails::Internal::ErrorReporter.new(
65
67
  bugsnag_api_key: bugsnag_api_key.presence,
66
68
  rollbar_access_token: rollbar_access_token.presence,
69
+ rollbar_enabled: rollbar_enabled ? true : false,
67
70
  )
68
71
  end
69
72
 
@@ -29,18 +29,23 @@ class Tpt::Rails::Internal::Datadog # :nodoc:
29
29
  url = @statsd_url || 'statsd://localhost'
30
30
  uri = URI.parse(url)
31
31
 
32
+ tags = ["env:#{Tpt::Rails.app_env}"]
33
+ tags << ["tpt_release_version:#{Tpt::Rails.release_version}"] if Tpt::Rails.release_version
34
+
32
35
  ::Datadog::Statsd.new(
33
36
  uri.host,
34
37
  uri.port || DEFAULT_STATSD_PORT,
35
38
  {
36
39
  namespace: Tpt::Rails.app_name,
37
- tags: ["env:#{Tpt::Rails.app_env}"],
40
+ tags: tags,
38
41
  }
39
42
  )
40
43
  end
41
44
 
42
45
  def configure_tracing
43
46
  uri = URI.parse(@trace_url)
47
+ tags = { 'env' => Tpt::Rails.app_env }
48
+ tags["tpt_release_version"] = Tpt::Rails.release_version if Tpt::Rails.release_version
44
49
 
45
50
  ::Datadog.configure do |c|
46
51
  # This will activate auto-instrumentation for Rails
@@ -53,7 +58,7 @@ class Tpt::Rails::Internal::Datadog # :nodoc:
53
58
  enabled: true,
54
59
  hostname: uri.host,
55
60
  port: uri.port || DEFAULT_TRACE_PORT,
56
- tags: { 'env' => Tpt::Rails.app_env },
61
+ tags: tags,
57
62
  )
58
63
  end
59
64
 
@@ -1,7 +1,8 @@
1
1
  class Tpt::Rails::Internal::ErrorReporter # :nodoc:
2
- def initialize(bugsnag_api_key: nil, rollbar_access_token: nil)
2
+ def initialize(bugsnag_api_key: nil, rollbar_access_token: nil, rollbar_enabled: false)
3
3
  @bugsnag_api_key = bugsnag_api_key
4
4
  @rollbar_access_token = rollbar_access_token
5
+ @rollbar_enabled = rollbar_enabled
5
6
 
6
7
  configure_bugsnag if bugsnag?
7
8
  configure_rollbar if rollbar?
@@ -48,6 +49,7 @@ class Tpt::Rails::Internal::ErrorReporter # :nodoc:
48
49
 
49
50
  Bugsnag.configure do |config|
50
51
  config.api_key = @bugsnag_api_key
52
+ config.app_version = Tpt::Rails.release_version if Tpt::Rails.release_version
51
53
  end
52
54
  end
53
55
 
@@ -57,12 +59,10 @@ class Tpt::Rails::Internal::ErrorReporter # :nodoc:
57
59
 
58
60
  Rollbar.configure do |config|
59
61
  config.access_token = @rollbar_access_token
60
-
61
- if ::Rails.env.test? || ::Rails.env.development?
62
- config.enabled = false
63
- end
64
-
62
+ config.code_version = Tpt::Rails.release_version if Tpt::Rails.release_version
63
+ config.enabled = @rollbar_enabled
65
64
  config.environment = Tpt::Rails.app_env
65
+ config.populate_empty_backtraces = true
66
66
  end
67
67
  end
68
68
  end
@@ -0,0 +1,86 @@
1
+ module Tpt::Rails::PumaStatsCollector # :nodoc:
2
+ class PumaStats
3
+ def initialize(stats)
4
+ @stats = JSON.parse(stats, symbolize_names: true)
5
+ end
6
+
7
+ def clustered?
8
+ @stats.has_key?(:workers)
9
+ end
10
+
11
+ def workers
12
+ @stats.fetch(:workers, 1)
13
+ end
14
+
15
+ def booted_workers
16
+ @stats.fetch(:booted_workers, 1)
17
+ end
18
+
19
+ def running
20
+ get_stat(:running)
21
+ end
22
+
23
+ def backlog
24
+ get_stat(:backlog)
25
+ end
26
+
27
+ def pool_capacity
28
+ get_stat(:pool_capacity)
29
+ end
30
+
31
+ def max_threads
32
+ get_stat(:max_threads)
33
+ end
34
+
35
+ def to_s
36
+ {
37
+ workers: workers,
38
+ booted_workers: booted_workers,
39
+ running: running,
40
+ backlog: backlog,
41
+ pool_capacity: pool_capacity,
42
+ max_threads: max_threads
43
+ }.to_json
44
+ end
45
+
46
+ private
47
+ def get_stat(name)
48
+ if clustered?
49
+ @stats[:worker_status].map { |s| s[:last_status].fetch(name, 0) }.sum
50
+ else
51
+ @stats.fetch(name, 0)
52
+ end
53
+ end
54
+ end
55
+
56
+ class << self
57
+ def run(metrics_client:, start_delay: 10, collect_interval: 30)
58
+ Thread.new do
59
+ # Give Puma time to start
60
+ sleep start_delay
61
+
62
+ # Get pod name if set
63
+ pod_name = ENV["KUBE_POD"]
64
+
65
+ loop do
66
+ begin
67
+ stats = PumaStats.new(Puma.stats)
68
+
69
+ tags = []
70
+ # Add pod_name tag if set
71
+ tags << "pod_name:#{pod_name}" if pod_name
72
+
73
+ metrics_client.gauge("puma.workers", stats.workers, tags: tags)
74
+ metrics_client.gauge("puma.booted_workers", stats.booted_workers, tags: tags)
75
+ metrics_client.gauge("puma.running", stats.running, tags: tags)
76
+ metrics_client.gauge("puma.backlog", stats.backlog, tags: tags)
77
+ metrics_client.gauge("puma.pool_capacity", stats.pool_capacity, tags: tags)
78
+ metrics_client.gauge("puma.max_threads", stats.max_threads, tags: tags)
79
+ end
80
+
81
+ sleep collect_interval
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,5 +1,5 @@
1
1
  module Tpt
2
2
  module Rails
3
- VERSION = '1.0.2'
3
+ VERSION = '1.3.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tpt-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TpT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-28 00:00:00.000000000 Z
11
+ date: 2020-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -126,10 +126,11 @@ files:
126
126
  - lib/tpt/rails/internal/datadog.rb
127
127
  - lib/tpt/rails/internal/error_reporter.rb
128
128
  - lib/tpt/rails/internal/health_checks.rb
129
+ - lib/tpt/rails/puma_stats_collector.rb
129
130
  - lib/tpt/rails/version.rb
130
131
  homepage: https://github.com/TeachersPayTeachers/tpt-rails
131
132
  licenses:
132
- - None
133
+ - Nonstandard
133
134
  metadata: {}
134
135
  post_install_message:
135
136
  rdoc_options: []