chronos-ruby 1.1.2 → 1.1.4

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.
@@ -0,0 +1,96 @@
1
+ require "yaml"
2
+ require "uri"
3
+ require "chronos/deploy/error"
4
+
5
+ module Chronos
6
+ module Deploy
7
+ # @responsibility Validate and resolve public options, canonical ENV and legacy aliases.
8
+ # Resolves explicit CLI configuration without booting an application or agent.
9
+ class Configuration
10
+ FIELDS = %w(project_id project_key host environment service_name deploy_id revision version).freeze
11
+ ALIASES = {"environment" => "DEPLOY_ENVIRONMENT", "service_name" => "SERVICE_NAME",
12
+ "deploy_id" => "DEPLOY_ID", "revision" => "GIT_SHA", "version" => "APP_VERSION"}.freeze
13
+ HOST_ERROR = "Host must be an absolute HTTPS URL without credentials, query or fragment.".freeze
14
+
15
+ def self.read(options, env)
16
+ root = File.realpath(File.expand_path(options[:root] || Dir.pwd))
17
+ public_values = read_public(root)
18
+ values = FIELDS.each_with_object({}) do |field, result|
19
+ result[field] = resolve(field, options, env, public_values)
20
+ end
21
+ values["host"] ||= "https://chronosmonitor.com.br"
22
+ validate_host!(values["host"])
23
+ values
24
+ rescue Errno::ENOENT, Errno::ENOTDIR, Errno::EACCES
25
+ raise Error, "Configuration root or file is unavailable; check --root and permissions."
26
+ end
27
+
28
+ def self.read_public(root)
29
+ path = File.join(root, "config/chronos-deploy.yml")
30
+ if File.symlink?(File.join(root, "config")) || File.symlink?(path)
31
+ raise Error, "Configuration path must not contain symlinks."
32
+ end
33
+ return {} unless File.exist?(path)
34
+ raise Error, "Public configuration must be a regular file." unless File.file?(path)
35
+ raise Error, "Public configuration exceeds 64 KiB." if File.size(path) > 65_536
36
+
37
+ parsed = YAML.safe_load(File.read(path))
38
+ values = parsed.nil? ? {} : parsed
39
+ raise ArgumentError unless values.is_a?(Hash) && (values.keys - (FIELDS - ["project_key"])).empty?
40
+
41
+ values.each_value { |value| validate_text!(value) }
42
+ values
43
+ end
44
+
45
+ def self.resolve(field, options, env, public_values)
46
+ prefix = %w(revision version).include?(field) ? "CHRONOS_DEPLOY_" : "CHRONOS_"
47
+ primary = env["#{prefix}#{field.upcase}"]
48
+ alternate = env[ALIASES[field]] if ALIASES[field]
49
+ if primary && alternate && primary != alternate
50
+ raise Error, "Conflicting canonical and alias environment variables; keep only one source."
51
+ end
52
+
53
+ value = options[field.to_sym] || primary || alternate || public_values[field]
54
+ validate_text!(value)
55
+ value
56
+ end
57
+
58
+ def self.validate_text!(value)
59
+ raise ArgumentError unless value.nil? || value.is_a?(String)
60
+ return if value.nil?
61
+ return if value.valid_encoding? && value.encoding.ascii_compatible? && !value.match(/[[:cntrl:]]/)
62
+
63
+ raise Error, "Configuration values must be text without control characters."
64
+ end
65
+
66
+ def self.validate_host!(host)
67
+ uri = URI.parse(host)
68
+ valid = uri.scheme == "https" && uri.host && !uri.userinfo && !uri.query && !uri.fragment
69
+ raise Error, HOST_ERROR unless valid
70
+ rescue URI::InvalidURIError
71
+ raise Error, HOST_ERROR
72
+ end
73
+
74
+ def self.validate!(values, command)
75
+ required = %w(project_id project_key environment)
76
+ required << "deploy_id" if command != "verify"
77
+ missing = required.select { |field| values[field].to_s.strip.empty? }
78
+ raise Error.new("Supply the required configuration fields.", :missing_fields => missing) unless missing.empty?
79
+
80
+ validate_release!(values) unless command == "verify"
81
+ %w(environment service_name deploy_id revision version).each do |field|
82
+ if values[field] && values[field].bytesize > 128
83
+ raise Error, "Deployment metadata exceeds the 128-byte protocol limit."
84
+ end
85
+ end
86
+ true
87
+ end
88
+
89
+ def self.validate_release!(values)
90
+ return unless values["revision"].to_s.strip.empty? && values["version"].to_s.strip.empty?
91
+
92
+ raise Error, "Supply the revision or version of the published artifact."
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,14 @@
1
+ module Chronos
2
+ module Deploy
3
+ # @responsibility Carry static actionable errors and allowlisted diagnostics without raw input.
4
+ # Messages must be static: never interpolate input or exception messages.
5
+ class Error < StandardError
6
+ attr_reader :details
7
+
8
+ def initialize(message, details = {})
9
+ super(message)
10
+ @details = details
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,65 @@
1
+ require "chronos/deploy/error"
2
+ require "chronos/deploy/providers"
3
+
4
+ module Chronos
5
+ module Deploy
6
+ # @responsibility Generate provider fragments while preserving existing customer integrations.
7
+ # Explicit, idempotent generation of static fragments below a caller-selected root.
8
+ class Installer
9
+ PATHS = Providers::PATHS
10
+
11
+ def install(options)
12
+ raise Error, "Use --check without --force." if options[:force] && options[:check]
13
+
14
+ relative = PATHS[options[:provider]]
15
+ raise Error, "Choose a supported --provider; see chronos --help." unless relative
16
+
17
+ root = installation_root(options)
18
+ require "chronos/deploy/secure_directory"
19
+ SecureDirectory.with_root(root) do |directory|
20
+ install_into(directory, relative, options)
21
+ end
22
+ rescue Errno::EEXIST, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP
23
+ raise Error, "Integration destination is unavailable or changed; inspect it before retrying."
24
+ end
25
+
26
+ private
27
+
28
+ def install_into(directory, relative, options)
29
+ content = Providers.template(options[:provider])
30
+ existing = directory.with_parent(relative, false) { |parent, name| parent && parent.read(name) }
31
+ return "unchanged" if unchanged?(existing, relative, content, options)
32
+ raise Error, "Integration is missing; run install without --check." if options[:check]
33
+ return "would_write_#{relative}" if options[:dry_run]
34
+
35
+ directory.with_parent(relative, true) do |parent, name|
36
+ current = parent.read(name)
37
+ unless unchanged?(current, relative, content, options)
38
+ parent.write(name, content, options[:provider] == "kamal", options[:force])
39
+ end
40
+ end
41
+ "created_#{relative}; merge after successful publication; supply explicit published identity and revision"
42
+ end
43
+
44
+ def installation_root(options)
45
+ root = File.expand_path(options[:root] || Dir.pwd)
46
+ unless File.directory?(root) && !File.symlink?(root)
47
+ raise Error, "Installation root must be an existing directory, not a symlink."
48
+ end
49
+
50
+ root
51
+ end
52
+
53
+ def unchanged?(existing, relative, content, options)
54
+ return false if existing.nil?
55
+ return true if existing == content
56
+ return false if options[:force] && !options[:check]
57
+
58
+ proposed = content.lines.map { |line| "+#{line}" }.join
59
+ raise Error.new("Existing integration differs; merge the proposed template or explicitly use --force.",
60
+ :path => relative,
61
+ :diff => "--- existing (content withheld for privacy)\n+++ proposed\n#{proposed}")
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,50 @@
1
+ module Chronos
2
+ module Deploy
3
+ # Static integration fragments never interpolate customer input or credentials.
4
+ module Providers
5
+ PATHS = {
6
+ "kamal" => ".kamal/hooks/post-deploy",
7
+ "capistrano" => "lib/capistrano/tasks/chronos_deploy.rake",
8
+ "github-actions" => "config/chronos/deploy/github-actions.steps.yml",
9
+ "gitlab-ci" => "config/chronos/deploy/gitlab-ci.job.yml",
10
+ "jenkins" => "config/chronos/deploy/jenkins.post.groovy",
11
+ "azure-devops" => "config/chronos/deploy/azure-pipelines.steps.yml"
12
+ }.freeze
13
+ COMMAND = "bundle exec chronos deploy notify --on-error=warn".freeze
14
+ MARKER = "# Chronos deploy template v1; credentials from environment only.\n".freeze
15
+ INSTRUCTIONS = "# Supply CHRONOS_DEPLOY_ID and CHRONOS_DEPLOY_REVISION/VERSION " \
16
+ "from the actual publication.\n".freeze
17
+ CAPISTRANO = <<-'RUBY'.freeze
18
+ # Do not also load chronos/capistrano. Runs locally once after publication.
19
+ namespace :chronos_cli do
20
+ task :notify do
21
+ if Rake::Task.task_defined?("chronos:notify_deploy")
22
+ raise "Remove the duplicate chronos/capistrano integration"
23
+ end
24
+ system("bundle", "exec", "chronos", "deploy", "notify", "--on-error=warn")
25
+ end
26
+ end
27
+ after "deploy:published", "chronos_cli:notify"
28
+ RUBY
29
+ BODIES = {
30
+ "kamal" => "exec #{COMMAND}\n",
31
+ "capistrano" => CAPISTRANO,
32
+ "github-actions" => "# Merge into the real job after successful publication.\n" \
33
+ "- name: Notify Chronos\n run: #{COMMAND}\n",
34
+ "gitlab-ci" => "# Merge script into the successful deployment job; preserve artifact outputs.\n" \
35
+ ".chronos_deploy_notification:\n script:\n - #{COMMAND}\n",
36
+ "jenkins" => "// Merge into existing post { success { ... } }; export actual publication outputs.\n" \
37
+ "sh '#{COMMAND}'\n",
38
+ "azure-devops" => "# Merge after successful publication in the same job.\n" \
39
+ "- script: #{COMMAND}\n displayName: Notify Chronos\n condition: succeeded()\n"
40
+ }.freeze
41
+
42
+ def self.template(provider)
43
+ comments = MARKER + INSTRUCTIONS
44
+ comments = comments.gsub(/^#/, "//") if provider == "jenkins"
45
+ shebang = provider == "kamal" ? "#!/bin/sh\n" : ""
46
+ shebang + comments + BODIES.fetch(provider)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,44 @@
1
+ require "logger"
2
+ require "chronos"
3
+ require "chronos/deploy/configuration"
4
+
5
+ module Chronos
6
+ module Deploy
7
+ # @responsibility Execute the existing deploy or receipt API with bounded transport and guaranteed close.
8
+ # One explicit operation through the existing agent, always closed on exit.
9
+ class Runner
10
+ def call(command, values, timeout)
11
+ Configuration.validate!(values, command)
12
+ begin
13
+ configure(values, timeout, command)
14
+ outcome = if command == "verify"
15
+ Chronos.verify_integration
16
+ else
17
+ Chronos.notify_deploy({:deploy_id => values["deploy_id"], :revision => values["revision"],
18
+ :version => values["version"]}, timeout)
19
+ end
20
+ ensure
21
+ closed = Chronos.close(timeout)
22
+ end
23
+ command == "notify" ? outcome == true && closed != false : outcome
24
+ end
25
+
26
+ private
27
+
28
+ def configure(values, timeout, command)
29
+ Chronos.configure do |config|
30
+ values.each do |key, value|
31
+ attribute = key == "version" ? "app_version" : key
32
+ config.public_send("#{attribute}=", value) unless value.nil?
33
+ end
34
+ config.logger = Logger.new(File::NULL)
35
+ config.timeout = timeout
36
+ config.open_timeout = timeout
37
+ config.max_retries = 0
38
+ config.backlog_size = 0
39
+ config.dependency_reporting = false if command == "verify"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,125 @@
1
+ require "fiddle/import"
2
+ require "securerandom"
3
+ require "chronos/deploy/error"
4
+
5
+ module Chronos
6
+ module Deploy
7
+ # @responsibility Anchor installer reads and writes to directory descriptors without following symlinks.
8
+ # POSIX openat/mkdirat/linkat/renameat prevent parent-path replacement from redirecting writes.
9
+ class SecureDirectory
10
+ # Fixed POSIX entry points; no shell, dynamic symbol names, or user-provided native code.
11
+ module Native
12
+ extend Fiddle::Importer
13
+ dlload Fiddle::Handle::DEFAULT
14
+ extern "int openat(int, const char*, int, unsigned int)"
15
+ extern "int mkdirat(int, const char*, unsigned int)"
16
+ extern "int linkat(int, const char*, int, const char*, int)"
17
+ extern "int renameat(int, const char*, int, const char*)"
18
+ extern "int unlinkat(int, const char*, int)"
19
+ end
20
+
21
+ def self.with_root(root)
22
+ raise Error, "Secure installation requires POSIX no-follow support." unless File.const_defined?(:NOFOLLOW)
23
+
24
+ handle = File.open(root, File::RDONLY | File::NOFOLLOW | File::NONBLOCK)
25
+ raise Error, "Installation root must be a directory." unless handle.stat.directory?
26
+
27
+ yield new(handle)
28
+ ensure
29
+ handle.close if handle && !handle.closed?
30
+ end
31
+
32
+ def with_parent(relative, create)
33
+ handles = []
34
+ current = self
35
+ parts = relative.split("/")
36
+ parts[0...-1].each do |part|
37
+ child = current.directory(part, create)
38
+ return yield(nil, parts.last) unless child
39
+
40
+ handles << child
41
+ current = self.class.new(child)
42
+ end
43
+ yield current, parts.last
44
+ ensure
45
+ handles.reverse_each(&:close)
46
+ end
47
+
48
+ def initialize(handle)
49
+ @handle = handle
50
+ end
51
+
52
+ def directory(name, create)
53
+ file = open_file(name, File::RDONLY | File::NONBLOCK)
54
+ if file.nil? && create
55
+ status = Native.mkdirat(@handle.fileno, name, 0o755)
56
+ check!(status) unless status.zero? || Fiddle.last_error == Errno::EEXIST::Errno
57
+ file = open_file(name, File::RDONLY | File::NONBLOCK)
58
+ end
59
+ return nil unless file
60
+ return file if file.stat.directory?
61
+
62
+ file.close
63
+ raise Error, "Installation parent must be a directory."
64
+ end
65
+
66
+ def read(name)
67
+ file = open_file(name, File::RDONLY | File::NONBLOCK)
68
+ return nil unless file
69
+
70
+ begin
71
+ raise Error, "Integration must be a regular file of at most 64 KiB." unless file.stat.file?
72
+
73
+ content = file.read(65_537) || ""
74
+ raise Error, "Integration must be a regular file of at most 64 KiB." if content.bytesize > 65_536
75
+
76
+ content
77
+ ensure
78
+ file.close
79
+ end
80
+ end
81
+
82
+ def write(name, content, executable, force)
83
+ temporary = ".chronos-deploy-#{SecureRandom.hex(16)}"
84
+ file = open_file(temporary, File::WRONLY | File::CREAT | File::EXCL, 0o600)
85
+ raise Error, "Installation directory is unavailable." unless file
86
+
87
+ begin
88
+ file.write(content)
89
+ file.chmod(executable ? 0o755 : 0o644)
90
+ file.close
91
+ if force
92
+ check!(Native.renameat(@handle.fileno, temporary, @handle.fileno, name))
93
+ else
94
+ check!(Native.linkat(@handle.fileno, temporary, @handle.fileno, name, 0))
95
+ end
96
+ ensure
97
+ file.close unless file.closed?
98
+ Native.unlinkat(@handle.fileno, temporary, 0)
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def open_file(name, flags, mode = 0)
105
+ if name.empty? || name.include?("/") || name.include?("\0") || %w(. ..).include?(name)
106
+ raise Error, "Unsafe installation path component."
107
+ end
108
+
109
+ descriptor = Native.openat(@handle.fileno, name, flags | File::NOFOLLOW, mode)
110
+ return nil if descriptor < 0 && Fiddle.last_error == Errno::ENOENT::Errno
111
+
112
+ check!(descriptor)
113
+ file = File.for_fd(descriptor, (flags & File::WRONLY).zero? ? "r" : "w")
114
+ file.close_on_exec = true
115
+ file
116
+ end
117
+
118
+ def check!(status)
119
+ return status if status >= 0
120
+
121
+ raise Error, "Installation path changed, contains a symlink, or is unavailable; inspect it before retrying."
122
+ end
123
+ end
124
+ end
125
+ end
@@ -1,4 +1,5 @@
1
1
  require "json"
2
+ require "chronos/core/sql_lexer"
2
3
 
3
4
  module Chronos
4
5
  module Rails
@@ -63,10 +64,7 @@ module Chronos
63
64
  return false unless connection
64
65
  return false unless (query["operation"] || query[:operation]).to_s == "SELECT"
65
66
  return false if table(query).empty?
66
- return false unless raw_sql.to_s.lstrip =~ /\ASELECT\b/i
67
-
68
- normalized = (query["normalized_query"] || query[:normalized_query]).to_s
69
- normalized.sub(/;\s*\z/, "") !~ /;/
67
+ Core::SqlLexer.new(raw_sql, adapter_name(connection)).single_select?
70
68
  end
71
69
 
72
70
  def indexes(connection, table_name)
@@ -7,7 +7,7 @@ module Chronos
7
7
  #
8
8
  # @responsibility Register the integration verification task with deterministic JSON output.
9
9
  # @motivation Give Rails and plain Ruby operators one repeatable end-to-end credential check.
10
- # @limits It never reads environment variables, prints credentials, or modifies application data.
10
+ # @limits Deploy reads explicit CLI ENV; verification uses the configured agent. Neither prints credentials.
11
11
  # @collaborators Rake and Chronos.verify_integration.
12
12
  # @thread_safety Installation checks the process-global Rake registry and is intended for boot time.
13
13
  # @compatibility Rake versions compatible with Ruby 2.2.10 through Ruby 2.6.
@@ -22,6 +22,7 @@ module Chronos
22
22
  TASK_NAME = "chronos:verify_integration".freeze
23
23
 
24
24
  def self.install(options = {})
25
+ install_deploy(options)
25
26
  return false if ::Rake::Task.task_defined?(TASK_NAME)
26
27
 
27
28
  output = options[:output] || $stdout
@@ -37,5 +38,16 @@ module Chronos
37
38
  end
38
39
  true
39
40
  end
41
+
42
+ def self.install_deploy(options)
43
+ return if ::Rake::Task.task_defined?("chronos:deploy")
44
+
45
+ task "chronos:deploy" do
46
+ require "chronos/cli"
47
+ status = Chronos::CLI.new(options[:output] || $stdout, options[:env] || ENV).run(["deploy", "notify"])
48
+ (options[:exit] || proc { |code| exit(code) }).call(status) unless status.zero?
49
+ end
50
+ end
51
+ private_class_method :install_deploy
40
52
  end
41
53
  end
@@ -1,4 +1,4 @@
1
1
  module Chronos
2
2
  # Current version of the legacy Chronos Ruby agent.
3
- VERSION = "1.1.2".freeze
3
+ VERSION = "1.1.4".freeze
4
4
  end
@@ -0,0 +1,26 @@
1
+ require "rails/generators"
2
+ require "chronos/deploy/installer"
3
+
4
+ module Chronos
5
+ module Generators
6
+ module Deploy
7
+ # @responsibility Delegate explicit Rails generation to the shared deploy installer.
8
+ # Rails adapter for the same explicit installer used by the CLI.
9
+ class InstallGenerator < ::Rails::Generators::Base
10
+ namespace "chronos:deploy:install"
11
+ class_option :provider, :type => :string, :required => true
12
+ class_option :dry_run, :type => :boolean, :default => false
13
+ class_option :check, :type => :boolean, :default => false
14
+ class_option :force, :type => :boolean, :default => false
15
+
16
+ def install_deploy
17
+ result = Chronos::Deploy::Installer.new.install(
18
+ :root => destination_root, :provider => options[:provider],
19
+ :dry_run => options[:dry_run], :check => options[:check], :force => options[:force]
20
+ )
21
+ say result
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chronos-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antonio Jefferson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-08-13 00:00:00.000000000 Z
11
+ date: 2026-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,6 +44,20 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: 12.3.3
47
+ - !ruby/object:Gem::Dependency
48
+ name: minitest
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 5.10.3
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '='
59
+ - !ruby/object:Gem::Version
60
+ version: 5.10.3
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: rspec
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -86,11 +100,15 @@ dependencies:
86
100
  - - '='
87
101
  - !ruby/object:Gem::Version
88
102
  version: 1.19.2
89
- description: Base do cliente Chronos para excecoes, telemetria e observabilidade em
90
- aplicacoes Ruby legadas.
103
+ description: Cliente oficial do Chronos para capturar e enviar exceções, métricas
104
+ e dados de telemetria de aplicações Ruby e Rails. A gem centraliza sinais de observabilidade
105
+ para facilitar o monitoramento, a análise de desempenho e o diagnóstico de falhas
106
+ no Chronos Monitor. Conheça a plataforma oficial de recebimento e visualização dos
107
+ dados em https://chronosmonitor.com.br.
91
108
  email:
92
109
  - antoniojeferson96@gmail.com
93
- executables: []
110
+ executables:
111
+ - chronos
94
112
  extensions: []
95
113
  extra_rdoc_files: []
96
114
  files:
@@ -126,12 +144,15 @@ files:
126
144
  - docs/adr/ADR-017-deploy-events-and-correlation.md
127
145
  - docs/adr/ADR-018-pre-1.0-hardening.md
128
146
  - docs/adr/ADR-019-bounded-query-diagnostics.md
147
+ - docs/adr/legacy-deploy-cli.md
129
148
  - docs/architecture.md
130
149
  - docs/compatibility.md
131
150
  - docs/configuration.md
132
151
  - docs/data-collected.md
152
+ - docs/deploy-cli.md
133
153
  - docs/deprecation-policy.md
134
154
  - docs/examples/plain-ruby.md
155
+ - docs/legacy-test-environment.md
135
156
  - docs/migration-from-airbrake.md
136
157
  - docs/modules/active-job.md
137
158
  - docs/modules/apm-aggregation.md
@@ -167,9 +188,12 @@ files:
167
188
  - docs/release-1.0-readiness.md
168
189
  - docs/release-1.1-readiness.md
169
190
  - docs/release-1.1.2-readiness.md
191
+ - docs/release-1.1.3-readiness.md
192
+ - docs/release-1.1.4-readiness.md
170
193
  - docs/security-review.md
171
194
  - docs/semver.md
172
195
  - docs/troubleshooting.md
196
+ - exe/chronos
173
197
  - lib/chronos.rb
174
198
  - lib/chronos/adapters.rb
175
199
  - lib/chronos/adapters/net_http_transport.rb
@@ -188,12 +212,14 @@ files:
188
212
  - lib/chronos/application/retry_policy.rb
189
213
  - lib/chronos/application/verify_integration.rb
190
214
  - lib/chronos/capistrano.rb
215
+ - lib/chronos/cli.rb
191
216
  - lib/chronos/configuration.rb
192
217
  - lib/chronos/configuration/apm_validation.rb
193
218
  - lib/chronos/configuration/snapshot.rb
194
219
  - lib/chronos/configuration/validation.rb
195
220
  - lib/chronos/core.rb
196
221
  - lib/chronos/core/backtrace_parser.rb
222
+ - lib/chronos/core/bounded_copy.rb
197
223
  - lib/chronos/core/breadcrumb.rb
198
224
  - lib/chronos/core/cache_normalizer.rb
199
225
  - lib/chronos/core/correlation_context.rb
@@ -208,9 +234,16 @@ files:
208
234
  - lib/chronos/core/safe_serializer.rb
209
235
  - lib/chronos/core/sanitizer.rb
210
236
  - lib/chronos/core/sensitive_value_filter.rb
237
+ - lib/chronos/core/sql_lexer.rb
211
238
  - lib/chronos/core/sql_normalizer.rb
212
239
  - lib/chronos/core/sql_query_analyzer.rb
213
240
  - lib/chronos/core/telemetry_event.rb
241
+ - lib/chronos/deploy/configuration.rb
242
+ - lib/chronos/deploy/error.rb
243
+ - lib/chronos/deploy/installer.rb
244
+ - lib/chronos/deploy/providers.rb
245
+ - lib/chronos/deploy/runner.rb
246
+ - lib/chronos/deploy/secure_directory.rb
214
247
  - lib/chronos/errors.rb
215
248
  - lib/chronos/integrations.rb
216
249
  - lib/chronos/integrations/active_job.rb
@@ -241,6 +274,7 @@ files:
241
274
  - lib/chronos/ruby/version.rb
242
275
  - lib/chronos/sidekiq.rb
243
276
  - lib/chronos/version.rb
277
+ - lib/generators/chronos/deploy/install/install_generator.rb
244
278
  - lib/generators/chronos/install/install_generator.rb
245
279
  - lib/generators/chronos/install/templates/chronos.rb
246
280
  homepage: https://github.com/antoniojefferson/chronos-ruby
@@ -272,5 +306,5 @@ requirements: []
272
306
  rubygems_version: 3.4.22
273
307
  signing_key:
274
308
  specification_version: 4
275
- summary: Cliente Ruby para captura de eventos do Chronos
309
+ summary: Monitoramento de exceções, métricas e telemetria para Ruby e Rails
276
310
  test_files: []