atatus 1.2.0 → 1.6.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.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/Gemfile +72 -22
  4. data/LICENSE +1 -1
  5. data/atatus.gemspec +2 -2
  6. data/lib/atatus/agent.rb +78 -29
  7. data/lib/atatus/central_config/cache_control.rb +18 -1
  8. data/lib/atatus/central_config.rb +72 -27
  9. data/lib/atatus/child_durations.rb +64 -0
  10. data/lib/atatus/collector/base.rb +99 -43
  11. data/lib/atatus/collector/builder.rb +134 -4
  12. data/lib/atatus/collector/hist.rb +54 -0
  13. data/lib/atatus/collector/layer.rb +1 -0
  14. data/lib/atatus/collector/transport.rb +41 -11
  15. data/lib/atatus/config/bytes.rb +17 -0
  16. data/lib/atatus/config/duration.rb +17 -0
  17. data/lib/atatus/config/options.rb +29 -9
  18. data/lib/atatus/config/regexp_list.rb +17 -0
  19. data/lib/atatus/config/wildcard_pattern_list.rb +64 -0
  20. data/lib/atatus/config.rb +129 -28
  21. data/lib/atatus/context/request/socket.rb +18 -1
  22. data/lib/atatus/context/request/url.rb +17 -0
  23. data/lib/atatus/context/request.rb +17 -0
  24. data/lib/atatus/context/response.rb +27 -2
  25. data/lib/atatus/context/user.rb +17 -0
  26. data/lib/atatus/context.rb +32 -1
  27. data/lib/atatus/context_builder.rb +19 -4
  28. data/lib/atatus/deprecations.rb +17 -0
  29. data/lib/atatus/error/exception.rb +24 -0
  30. data/lib/atatus/error/log.rb +17 -0
  31. data/lib/atatus/error.rb +27 -0
  32. data/lib/atatus/error_builder.rb +21 -2
  33. data/lib/atatus/grape.rb +62 -0
  34. data/lib/atatus/graphql.rb +91 -0
  35. data/lib/atatus/grpc.rb +99 -0
  36. data/lib/atatus/instrumenter.rb +135 -30
  37. data/lib/atatus/internal_error.rb +17 -0
  38. data/lib/atatus/logging.rb +17 -2
  39. data/lib/atatus/metadata/process_info.rb +17 -0
  40. data/lib/atatus/metadata/service_info.rb +21 -6
  41. data/lib/atatus/metadata/system_info/container_info.rb +49 -10
  42. data/lib/atatus/metadata/system_info/hw_info.rb +1 -1
  43. data/lib/atatus/metadata/system_info.rb +22 -3
  44. data/lib/atatus/metadata.rb +17 -0
  45. data/lib/atatus/metrics/breakdown_set.rb +31 -0
  46. data/lib/atatus/metrics/{cpu_mem.rb → cpu_mem_set.rb} +110 -63
  47. data/lib/atatus/metrics/metric.rb +140 -0
  48. data/lib/atatus/metrics/set.rb +123 -0
  49. data/lib/atatus/metrics/span_scoped_set.rb +56 -0
  50. data/lib/atatus/metrics/transaction_set.rb +26 -0
  51. data/lib/atatus/metrics/vm_set.rb +58 -0
  52. data/lib/atatus/metrics.rb +69 -27
  53. data/lib/atatus/metricset.rb +48 -4
  54. data/lib/atatus/middleware.rb +28 -8
  55. data/lib/atatus/naively_hashable.rb +17 -0
  56. data/lib/atatus/normalizers/grape/endpoint_run.rb +65 -0
  57. data/lib/atatus/normalizers/grape.rb +22 -0
  58. data/lib/atatus/normalizers/rails/action_controller.rb +44 -0
  59. data/lib/atatus/normalizers/rails/action_mailer.rb +43 -0
  60. data/lib/atatus/normalizers/{action_view.rb → rails/action_view.rb} +17 -0
  61. data/lib/atatus/normalizers/rails/active_record.rb +80 -0
  62. data/lib/atatus/normalizers/rails.rb +27 -0
  63. data/lib/atatus/normalizers.rb +23 -9
  64. data/lib/atatus/opentracing.rb +75 -42
  65. data/lib/atatus/rails.rb +29 -13
  66. data/lib/atatus/railtie.rb +19 -6
  67. data/lib/atatus/resque.rb +29 -0
  68. data/lib/atatus/sinatra.rb +53 -0
  69. data/lib/atatus/span/context/db.rb +43 -0
  70. data/lib/atatus/span/context/destination.rb +77 -0
  71. data/lib/atatus/span/context/http.rb +43 -0
  72. data/lib/atatus/span/context.rb +43 -28
  73. data/lib/atatus/span.rb +47 -17
  74. data/lib/atatus/span_helpers.rb +32 -6
  75. data/lib/atatus/spies/action_dispatch.rb +27 -6
  76. data/lib/atatus/spies/delayed_job.rb +26 -5
  77. data/lib/atatus/spies/dynamo_db.rb +62 -0
  78. data/lib/atatus/spies/elasticsearch.rb +53 -7
  79. data/lib/atatus/spies/faraday.rb +54 -20
  80. data/lib/atatus/spies/http.rb +36 -6
  81. data/lib/atatus/spies/json.rb +18 -0
  82. data/lib/atatus/spies/mongo.rb +41 -10
  83. data/lib/atatus/spies/net_http.rb +52 -11
  84. data/lib/atatus/spies/rake.rb +42 -23
  85. data/lib/atatus/spies/redis.rb +17 -0
  86. data/lib/atatus/spies/resque.rb +57 -0
  87. data/lib/atatus/spies/sequel.rb +54 -17
  88. data/lib/atatus/spies/shoryuken.rb +69 -0
  89. data/lib/atatus/spies/sidekiq.rb +46 -25
  90. data/lib/atatus/spies/sinatra.rb +20 -4
  91. data/lib/atatus/spies/sneakers.rb +74 -0
  92. data/lib/atatus/spies/sucker_punch.rb +58 -0
  93. data/lib/atatus/spies/tilt.rb +20 -1
  94. data/lib/atatus/spies.rb +33 -15
  95. data/lib/atatus/sql/signature.rb +169 -0
  96. data/lib/atatus/sql/tokenizer.rb +264 -0
  97. data/lib/atatus/sql/tokens.rb +63 -0
  98. data/lib/atatus/sql.rb +36 -0
  99. data/lib/atatus/sql_summarizer.rb +24 -6
  100. data/lib/atatus/stacktrace/frame.rb +17 -3
  101. data/lib/atatus/stacktrace.rb +17 -0
  102. data/lib/atatus/stacktrace_builder.rb +23 -3
  103. data/lib/atatus/subscriber.rb +23 -4
  104. data/lib/atatus/trace_context/traceparent.rb +111 -0
  105. data/lib/atatus/trace_context/tracestate.rb +148 -0
  106. data/lib/atatus/trace_context.rb +84 -51
  107. data/lib/atatus/transaction.rb +74 -18
  108. data/lib/atatus/transport/base.rb +44 -27
  109. data/lib/atatus/transport/connection/http.rb +58 -35
  110. data/lib/atatus/transport/connection/proxy_pipe.rb +24 -5
  111. data/lib/atatus/transport/connection.rb +28 -72
  112. data/lib/atatus/transport/filters/hash_sanitizer.rb +77 -0
  113. data/lib/atatus/transport/filters/secrets_filter.rb +30 -55
  114. data/lib/atatus/transport/filters.rb +18 -1
  115. data/lib/atatus/transport/headers.rb +83 -0
  116. data/lib/atatus/transport/serializers/context_serializer.rb +30 -3
  117. data/lib/atatus/transport/serializers/error_serializer.rb +17 -2
  118. data/lib/atatus/transport/serializers/metadata_serializer.rb +44 -22
  119. data/lib/atatus/transport/serializers/metricset_serializer.rb +34 -6
  120. data/lib/atatus/transport/serializers/span_serializer.rb +47 -12
  121. data/lib/atatus/transport/serializers/transaction_serializer.rb +18 -2
  122. data/lib/atatus/transport/serializers.rb +17 -5
  123. data/lib/atatus/transport/user_agent.rb +48 -0
  124. data/lib/atatus/transport/worker.rb +31 -7
  125. data/lib/atatus/util/inflector.rb +17 -0
  126. data/lib/atatus/util/lru_cache.rb +17 -0
  127. data/lib/atatus/util/throttle.rb +17 -0
  128. data/lib/atatus/util.rb +18 -1
  129. data/lib/atatus/version.rb +19 -1
  130. data/lib/atatus.rb +84 -16
  131. metadata +46 -26
  132. data/Rakefile +0 -19
  133. data/bench/.gitignore +0 -2
  134. data/bench/app.rb +0 -53
  135. data/bench/benchmark.rb +0 -36
  136. data/bench/report.rb +0 -55
  137. data/bench/rubyprof.rb +0 -39
  138. data/bench/stackprof.rb +0 -23
  139. data/bin/build_docs +0 -5
  140. data/bin/console +0 -15
  141. data/bin/setup +0 -8
  142. data/bin/with_framework +0 -7
  143. data/lib/atatus/metrics/vm.rb +0 -60
  144. data/lib/atatus/normalizers/action_controller.rb +0 -27
  145. data/lib/atatus/normalizers/action_mailer.rb +0 -26
  146. data/lib/atatus/normalizers/active_record.rb +0 -45
  147. data/lib/atatus/util/prefixed_logger.rb +0 -18
  148. data/vendor/.gitkeep +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6399d781fb6ed0fbf4d275871f8badd44feef60f0579fb98395471d837ab0a2
4
- data.tar.gz: 0da5efde082affe391be507829d4cfb2eac79e9e7d87e35143e86857167f2407
3
+ metadata.gz: fdb76c9559c230c2e772a5878d82486da076104089c39302722fccca8f0c22db
4
+ data.tar.gz: 20233ccdea5269e3b3eb6c7c348091a161f875fbd1946554bdd314ee09f55ba2
5
5
  SHA512:
6
- metadata.gz: 9332acfc6e05a1627e05e98dcf9ab3bfee8c7e111f1ccc41300340b54650e5d56145a0cbc46da4f07bd4b2084cc4af0e57ccdadf55831d6732309d573dd8eb78
7
- data.tar.gz: b0570c4ea30150e82bdaaf1f61939ec405205a96e3808654bb3e2aaf5a156a0f25d825038c19286ca9d3774175ad5568156baa43fb5cd08b98703e3eeb55eb13
6
+ metadata.gz: c0dfd9f4d6ecddad2036b1b289ec864ea0edbc5f0949bfd76639b741e5a6be6ca2da9840347b10950635a235df37c20c9464505675e022b10d5c9341dc2807c1
7
+ data.tar.gz: 38d6f642f6f413e8c0ed989ba28d70bb9ce9643525fa28156ce8853e3781c1b3d3e9329d06d9ed0d8b7096a7d6799ad8817701012007a443f9a44a47ecf16136
data/CHANGELOG.md CHANGED
@@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+
8
+ ## 1.6.0 (Fri, 24 Dec 2021)
9
+
10
+ - Added support for set custom data.
11
+ - Fixed the span timing issue.
12
+
13
+
14
+ ## 1.5.0 (Thu, 27 May 2021)
15
+
16
+ - Fixed issue in status code conversion.
17
+
18
+
19
+ ## 1.4.0 (Tue, 15 Sept 2020)
20
+
21
+ - Added histogram support.
22
+ - Fixed Ruby 2.7.0 warning messages.
23
+
24
+
25
+ ## 1.3.0 (Wed, 18 Mar 2020)
26
+
27
+ - Added custom instrumentation via annotate method.
28
+
29
+
7
30
  ## 1.2.0 (Tue, 21 Jan 2020)
8
31
 
9
32
  - Updated Sidekiq operation as background transaction.
data/Gemfile CHANGED
@@ -1,57 +1,107 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  source 'https://rubygems.org'
4
21
 
5
22
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
23
 
7
- gemspec
8
-
24
+ # Tools
25
+ gem 'bootsnap', require: false
26
+ gem 'cucumber', require: false
27
+ gem 'pry'
9
28
  gem 'rack-test'
10
- gem 'rspec'
29
+ gem 'rspec', '~> 3'
11
30
  gem 'rspec-its'
12
31
  gem 'rubocop', require: nil
32
+ gem 'rubocop-performance', require: nil
13
33
  gem 'timecop'
14
34
  gem 'webmock'
15
35
 
36
+ # Integrations
37
+ gem 'aws-sdk-dynamodb', require: nil
38
+ gem 'aws-sdk-sqs', require: nil
16
39
  gem 'elasticsearch', require: nil
17
40
  gem 'fakeredis', require: nil
18
41
  gem 'faraday', require: nil
42
+ gem 'graphql', require: nil
43
+ gem 'google-protobuf', '< 3.12' if !defined?(JRUBY_VERSION) && RUBY_VERSION < '2.5'
44
+ gem 'grpc' if !defined?(JRUBY_VERSION)
45
+ gem 'json'
19
46
  gem 'json-schema', require: nil
20
47
  gem 'mongo', require: nil
21
48
  gem 'opentracing', require: nil
22
49
  gem 'rake', require: nil
50
+ gem 'resque', require: nil
23
51
  gem 'sequel', require: nil
52
+ gem 'shoryuken', require: nil
24
53
  gem 'sidekiq', require: nil
25
- gem 'simplecov', require: false, group: :test
26
- gem 'simplecov-cobertura', require: false, group: :test
54
+ gem 'simplecov', require: false
55
+ gem 'simplecov-cobertura', require: false
56
+ gem 'sneakers', '~> 2.12', require: nil
57
+ gem 'sucker_punch', '~> 2.0', require: nil
27
58
  gem 'yard', require: nil
28
59
  gem 'yarjuf'
29
60
 
30
- if RUBY_PLATFORM == 'java'
31
- gem 'jdbc-sqlite3'
32
- else
33
- gem 'sqlite3'
34
- end
61
+ ## Install Framework
62
+ GITHUB_REPOS = {
63
+ 'grape' => 'ruby-grape/grape',
64
+ 'rails' => 'rails/rails',
65
+ 'sinatra' => 'sinatra/sinatra'
66
+ }.freeze
35
67
 
36
- framework, *version = ENV.fetch('FRAMEWORK', 'rails').split('-')
37
- version = version.join('-')
68
+ # new || legacy || default
69
+ env_frameworks = ENV['FRAMEWORKS'] || ENV['FRAMEWORK'] || ''
70
+ parsed_frameworks = env_frameworks.split(',')
71
+ frameworks_versions = parsed_frameworks.inject({}) do |frameworks, str|
72
+ framework, *version = str.split('-')
73
+ frameworks.merge(framework => version.join('-'))
74
+ end
38
75
 
39
- case version
40
- when 'master'
41
- gem framework, github: "#{framework}/#{framework}"
42
- when /.+/
43
- gem framework, "~> #{version}.0"
44
- else
45
- gem framework
76
+ frameworks_versions.each do |framework, version|
77
+ case version
78
+ when 'master'
79
+ gem framework, github: GITHUB_REPOS.fetch(framework)
80
+ when /.+/
81
+ gem framework, "~> #{version}.0"
82
+ else
83
+ gem framework
84
+ end
46
85
  end
47
86
 
48
- gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
87
+ if frameworks_versions.key?('rails')
88
+ unless frameworks_versions['rails'] =~ /^(master|6)/
89
+ gem 'delayed_job', require: nil
90
+ end
91
+ end
49
92
 
50
- unless version =~ /^(master|6)/
51
- gem 'delayed_job', require: nil
93
+ if RUBY_PLATFORM == 'java'
94
+ gem 'activerecord-jdbcsqlite3-adapter'
95
+ gem 'jdbc-sqlite3'
96
+ elsif frameworks_versions['rails'] =~ /^(4|5)/
97
+ gem 'sqlite3', '~> 1.3.6'
98
+ else
99
+ gem 'sqlite3' # rubocop:disable Bundler/DuplicatedGem
52
100
  end
53
101
 
54
102
  group :bench do
55
103
  gem 'ruby-prof', require: nil, platforms: %i[ruby]
56
104
  gem 'stackprof', require: nil, platforms: %i[ruby]
57
105
  end
106
+
107
+ gemspec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- All components of this product are Copyright (c) 2019 Atatus. All rights reserved.
1
+ All components of this product are Copyright (c) 2021 Atatus. All rights reserved.
2
2
 
3
3
  Except as otherwise expressly provided in this Agreement,
4
4
  End User shall not (and shall not permit any third party to):
data/atatus.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.homepage = 'https://www.atatus.com'
13
13
  spec.metadata = {
14
14
  'changelog_uri' => 'https://docs.atatus.com/docs/release-notes/ruby.html',
15
- 'documentation_uri' => 'https://docs.atatus.com/docs/application-monitoring/ruby-agent/rails.html',
15
+ 'documentation_uri' => 'https://docs.atatus.com/docs/application-monitoring/ruby-agent/overview.html',
16
16
  }
17
17
  spec.date = Time.now.strftime('%Y-%m-%d')
18
18
  spec.licenses = ['Atatus']
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  ]
27
27
 
28
28
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
29
- f.match(%r{^(test|spec|features|docs|releases)/}) || f.match(%r{^(CONTRIBUTING.md|RELEASE.md)})
29
+ f.match(%r{^(bench|bin|test|spec|features|docs|releases)/}) || f.match(%r{^(CONTRIBUTING.md|RELEASE.md|Rakefile|docker-compose.yml|Dockerfile)})
30
30
  end
31
31
 
32
32
  spec.add_dependency('concurrent-ruby', '~> 1.0')
data/lib/atatus/agent.rb CHANGED
@@ -1,3 +1,20 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  require 'atatus/error'
@@ -5,19 +22,18 @@ require 'atatus/error'
5
22
  require 'atatus/context_builder'
6
23
  require 'atatus/error_builder'
7
24
  require 'atatus/stacktrace_builder'
8
- require 'atatus/collector/base'
9
25
 
10
26
  require 'atatus/central_config'
11
- # require 'atatus/transport/base'
27
+ require 'atatus/collector/base'
12
28
  require 'atatus/metrics'
13
29
 
14
30
  require 'atatus/spies'
15
31
 
16
32
  module Atatus
17
- # rubocop:disable Metrics/ClassLength
18
33
  # @api private
19
34
  class Agent
20
35
  include Logging
36
+ extend Forwardable
21
37
 
22
38
  LOCK = Mutex.new
23
39
 
@@ -27,7 +43,6 @@ module Atatus
27
43
  @instance
28
44
  end
29
45
 
30
- # rubocop:disable Metrics/MethodLength
31
46
  def self.start(config)
32
47
  return @instance if @instance
33
48
 
@@ -36,9 +51,9 @@ module Atatus
36
51
  LOCK.synchronize do
37
52
  return @instance if @instance
38
53
 
39
- unless config.active?
54
+ unless config.enabled?
40
55
  config.logger.debug format(
41
- "%sAgent disabled with `active: false'",
56
+ "%sAgent disabled with `enabled: false'",
42
57
  Logging::PREFIX
43
58
  )
44
59
  return
@@ -47,7 +62,6 @@ module Atatus
47
62
  @instance = new(config).start
48
63
  end
49
64
  end
50
- # rubocop:enable Metrics/MethodLength
51
65
 
52
66
  def self.stop
53
67
  LOCK.synchronize do
@@ -62,24 +76,21 @@ module Atatus
62
76
  !!@instance
63
77
  end
64
78
 
65
- # rubocop:disable Metrics/MethodLength
66
79
  def initialize(config)
67
- @config = config
68
-
69
80
  @stacktrace_builder = StacktraceBuilder.new(config)
70
81
  @context_builder = ContextBuilder.new(config)
71
82
  @error_builder = ErrorBuilder.new(self)
72
83
 
73
84
  @central_config = CentralConfig.new(config)
74
- # @transport = Transport::Base.new(config)
85
+ @collector = Collector::Base.new(config)
86
+ @metrics = Metrics.new(config) { |event| enqueue event }
75
87
  @instrumenter = Instrumenter.new(
76
88
  config,
89
+ metrics: metrics,
77
90
  stacktrace_builder: stacktrace_builder
78
91
  ) { |event| enqueue event }
79
- @metrics = Metrics.new(config) { |event| enqueue event }
80
- @collector = Collector::Base.new(config)
92
+ @pid = Process.pid
81
93
  end
82
- # rubocop:enable Metrics/MethodLength
83
94
 
84
95
  attr_reader(
85
96
  :central_config,
@@ -89,29 +100,31 @@ module Atatus
89
100
  :instrumenter,
90
101
  :metrics,
91
102
  :stacktrace_builder,
92
- # :transport,
93
103
  :collector
94
104
  )
95
105
 
96
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
106
+ def_delegator :@central_config, :config
107
+
97
108
  def start
98
- unless config.disable_start_message
99
- info '[%s] Starting atatus ruby agent', VERSION
109
+ unless config.disable_start_message?
110
+ config.logger.info format(
111
+ '[%s] Starting atatus ruby agent',
112
+ VERSION
113
+ )
100
114
  end
101
115
 
102
- if @config.license_key.nil? || @config.app_name.nil?
103
- if @config.license_key.nil? && @config.app_name.nil?
116
+ if config.license_key.nil? || config.app_name.nil?
117
+ if config.license_key.nil? && config.app_name.nil?
104
118
  error 'Atatus configuration license_key and app_name are missing'
105
- elsif @config.license_key.nil?
119
+ elsif config.license_key.nil?
106
120
  error 'Atatus configuration license_key is missing'
107
- elsif @config.app_name.nil?
121
+ elsif config.app_name.nil?
108
122
  error 'Atatus configuration app_name is missing'
109
123
  end
110
124
  end
111
125
 
112
- collector.start
113
126
  central_config.start
114
- # transport.start
127
+ collector.start
115
128
  instrumenter.start
116
129
  metrics.start
117
130
 
@@ -122,7 +135,6 @@ module Atatus
122
135
 
123
136
  self
124
137
  end
125
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
126
138
 
127
139
  def stop
128
140
  debug 'Stopping agent'
@@ -131,7 +143,6 @@ module Atatus
131
143
  metrics.stop
132
144
  instrumenter.stop
133
145
  collector.stop
134
- # transport.stop
135
146
 
136
147
  self
137
148
  end
@@ -172,9 +183,13 @@ module Atatus
172
183
  context: nil,
173
184
  trace_context: nil
174
185
  )
186
+ return unless config.recording?
187
+ detect_forking!
188
+
175
189
  instrumenter.start_transaction(
176
190
  name,
177
191
  type,
192
+ config: config,
178
193
  context: context,
179
194
  trace_context: trace_context
180
195
  )
@@ -192,8 +207,16 @@ module Atatus
192
207
  action: nil,
193
208
  backtrace: nil,
194
209
  context: nil,
195
- trace_context: nil
210
+ trace_context: nil,
211
+ parent: nil,
212
+ sync: nil
196
213
  )
214
+ detect_forking!
215
+
216
+ # We don't check config.recording? because the span
217
+ # will not be created if there's no transaction.
218
+ # We want to use the recording value from the config
219
+ # that existed when start_transaction was called. ~estolfo
197
220
  instrumenter.start_span(
198
221
  name,
199
222
  type,
@@ -201,7 +224,9 @@ module Atatus
201
224
  action: action,
202
225
  backtrace: backtrace,
203
226
  context: context,
204
- trace_context: trace_context
227
+ trace_context: trace_context,
228
+ parent: parent,
229
+ sync: sync
205
230
  )
206
231
  end
207
232
  # rubocop:enable Metrics/ParameterLists
@@ -229,6 +254,8 @@ module Atatus
229
254
  # errors
230
255
 
231
256
  def report(exception, context: nil, handled: true)
257
+ return unless config.recording?
258
+ detect_forking!
232
259
  return if config.filter_exception_types.include?(exception.class.to_s)
233
260
 
234
261
  error = @error_builder.build_exception(
@@ -241,6 +268,9 @@ module Atatus
241
268
  end
242
269
 
243
270
  def report_message(message, context: nil, backtrace: nil, **attrs)
271
+ return unless config.recording?
272
+ detect_forking!
273
+
244
274
  error = @error_builder.build_log(
245
275
  message,
246
276
  context: context,
@@ -256,6 +286,25 @@ module Atatus
256
286
  def add_filter(key, callback)
257
287
  # transport.add_filter(key, callback)
258
288
  end
289
+
290
+ # misc
291
+
292
+ def inspect
293
+ super.split.first + '>'
294
+ end
295
+
296
+ def detect_forking!
297
+ return if @pid == Process.pid
298
+
299
+ config.logger.debug "Detected forking,
300
+ restarting threads in process [PID:#{Process.pid}]"
301
+
302
+ central_config.handle_forking!
303
+ collector.handle_forking!
304
+ instrumenter.handle_forking!
305
+ metrics.handle_forking!
306
+
307
+ @pid = Process.pid
308
+ end
259
309
  end
260
- # rubocop:enable Metrics/ClassLength
261
310
  end
@@ -1,3 +1,20 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  module Atatus
@@ -26,7 +43,7 @@ module Atatus
26
43
  def parse!(value)
27
44
  value.split(',').each do |token|
28
45
  k, v = token.split('=').map(&:strip)
29
- instance_variable_set(:"@#{k.gsub('-', '_')}", v ? v.to_i : true)
46
+ instance_variable_set(:"@#{k.tr('-', '_')}", v ? v.to_i : true)
30
47
  end
31
48
  end
32
49
  end
@@ -1,3 +1,20 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  require 'atatus/central_config/cache_control'
@@ -23,21 +40,29 @@ module Atatus
23
40
  def initialize(config)
24
41
  @config = config
25
42
  @modified_options = {}
26
- @service_info = {
27
- 'service.name': config.service_name,
28
- 'service.environment': config.environment
29
- }.to_json
43
+ # @http = Transport::Connection::Http.new(config)
44
+ @etag = 1
30
45
  end
31
46
 
32
47
  attr_reader :config
33
48
  attr_reader :scheduled_task, :promise # for specs
34
49
 
35
50
  def start
51
+ return
36
52
  return unless config.central_config?
37
53
 
54
+ debug 'Starting CentralConfig'
55
+
38
56
  fetch_and_apply_config
39
57
  end
40
58
 
59
+ def stop
60
+ return
61
+ debug 'Stopping CentralConfig'
62
+
63
+ @scheduled_task&.cancel
64
+ end
65
+
41
66
  def fetch_and_apply_config
42
67
  @promise =
43
68
  Concurrent::Promise
@@ -46,11 +71,6 @@ module Atatus
46
71
  .rescue(&method(:handle_error))
47
72
  end
48
73
 
49
- def stop
50
- @scheduled_task&.cancel
51
- end
52
-
53
- # rubocop:disable Metrics/MethodLength
54
74
  def fetch_config
55
75
  resp = perform_request
56
76
 
@@ -65,7 +85,6 @@ module Atatus
65
85
  raise ServerError, resp
66
86
  end
67
87
  end
68
- # rubocop:enable Metrics/MethodLength
69
88
 
70
89
  def assign(update)
71
90
  # For each updated option, store the original value,
@@ -81,20 +100,35 @@ module Atatus
81
100
  update[key] = @modified_options.delete(key)
82
101
  end
83
102
 
84
- config.assign(update)
103
+ @config.replace_options(update)
104
+ end
105
+
106
+ def handle_forking!
107
+ stop
108
+ start
85
109
  end
86
110
 
87
111
  private
88
112
 
89
- # rubocop:disable Metrics/MethodLength
113
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
90
114
  def handle_success(resp)
115
+ if (etag = resp.headers['Etag'])
116
+ @etag = etag
117
+ end
118
+
91
119
  if resp.status == 304
92
120
  info 'Received 304 Not Modified'
93
121
  else
94
- update = JSON.parse(resp.body.to_s)
95
- assign(update)
122
+ if resp.body && !resp.body.empty?
123
+ update = JSON.parse(resp.body.to_s)
124
+ assign(update)
125
+ end
96
126
 
97
- info 'Updated config from Kibana'
127
+ if update && update.any?
128
+ info 'Updated config from Kibana'
129
+ debug 'Modified: %s', update.inspect
130
+ debug 'Modified original options: %s', @modified_options.inspect
131
+ end
98
132
  end
99
133
 
100
134
  schedule_next_fetch(resp)
@@ -104,31 +138,42 @@ module Atatus
104
138
  error 'Failed to apply remote config, %s', e.inspect
105
139
  debug { e.backtrace.join('\n') }
106
140
  end
107
- # rubocop:enable Metrics/MethodLength
141
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
108
142
 
109
143
  def handle_error(error)
110
- error(
144
+ # For tests, WebMock failures don't have real responses
145
+ response = error.response if error.respond_to?(:response)
146
+
147
+ debug(
111
148
  'Failed fetching config: %s, trying again in %d seconds',
112
- error.response.body, DEFAULT_MAX_AGE
149
+ response&.body, DEFAULT_MAX_AGE
113
150
  )
114
151
 
115
152
  assign({})
116
153
 
117
- schedule_next_fetch(error.response)
154
+ schedule_next_fetch(response)
118
155
  end
119
156
 
120
157
  def perform_request
121
- Http.post(
122
- config.server_url + '/agent/v1/config/',
123
- body: @service_info,
124
- headers: { etag: 1, content_type: 'application/json' }
125
- )
158
+ # @http.get(server_url, headers: headers)
159
+ end
160
+
161
+ def server_url
162
+ @server_url ||=
163
+ config.server_url +
164
+ '/config/v1/agents' \
165
+ "?service.name=#{config.service_name}"
166
+ end
167
+
168
+ def headers
169
+ { 'Etag': @etag }
126
170
  end
127
171
 
128
- def schedule_next_fetch(resp)
172
+ def schedule_next_fetch(resp = nil)
173
+ headers = resp&.headers
129
174
  seconds =
130
- if (cache_header = resp.headers['Cache-Control'])
131
- CacheControl.new(cache_header).max_age
175
+ if headers && headers['Cache-Control']
176
+ CacheControl.new(headers['Cache-Control']).max_age
132
177
  else
133
178
  DEFAULT_MAX_AGE
134
179
  end