logister-ruby 0.2.6 → 0.2.8
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +53 -6
- data/lib/logister/client.rb +46 -3
- data/lib/logister/configuration.rb +20 -2
- data/lib/logister/context_helpers.rb +6 -0
- data/lib/logister/railtie.rb +1 -0
- data/lib/logister/reporter.rb +99 -2
- data/lib/logister/request_subscriber.rb +37 -0
- data/lib/logister/version.rb +1 -1
- data/lib/logister.rb +8 -0
- data/logister-ruby.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 533fd3675cc1afc26e61d5bb20220cdd2e3d2fd643d51f0492f6c377eaa1c532
|
|
4
|
+
data.tar.gz: fae0c653ea921eb9d394f7c03c337a60141acd265d6ae54cd166b06b9e1ed219
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94689cef817604ea72eba2c9413335588561c19d986e6a4f8dd880777bea84dbf03b40318e0ad1c8ad7fb7c5a6b87430c9509786dcdf31c9f9005b4cefc1756b
|
|
7
|
+
data.tar.gz: 1fcdca232672d5af22036584285737e9a75ea6d5d5c3d7269452ee645185d820e407c14ac5c330a5a58514a7c996d274666c2619dff3923f84c6ee1fcb4f5f2d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.2.8 - 2026-06-18
|
|
4
|
+
|
|
5
|
+
- Added first-class source context configuration (`repository`, `commit_sha`, and `branch`) with `LOGISTER_*` and GitHub Actions environment variable support.
|
|
6
|
+
- Added `Logister.record_deployment` for posting release-to-commit deployment records to Logister.
|
|
7
|
+
|
|
8
|
+
## v0.2.7 - 2026-05-22
|
|
9
|
+
|
|
10
|
+
- Added `Logister.report_span` and opt-in Rails request span capture for request load waterfall charts.
|
|
11
|
+
|
|
3
12
|
## v0.2.6 - 2026-05-22
|
|
4
13
|
|
|
5
14
|
- Added README guidance for using Ruby reports with the Logister project Insights beta, including practical metric, transaction, log, check-in, and custom attribute examples.
|
data/README.md
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# logister-ruby
|
|
2
2
|
|
|
3
|
-
`logister-ruby` is the Ruby and Rails client for sending errors, logs, metrics, transactions, and check-ins to Logister.
|
|
3
|
+
`logister-ruby` is the Ruby and Rails client for sending errors, logs, metrics, transactions, spans, and check-ins to Logister.
|
|
4
4
|
|
|
5
5
|
Install it from RubyGems as `logister-ruby`.
|
|
6
6
|
|
|
7
7
|
## Table Of Contents
|
|
8
8
|
|
|
9
9
|
- [What this gem is for](#what-this-gem-is-for)
|
|
10
|
+
- [Package Links](#package-links)
|
|
10
11
|
- [Self-hosted backend](#self-hosted-backend)
|
|
11
12
|
- [Install From RubyGems](#install-from-rubygems)
|
|
12
13
|
- [Configuration](#configuration)
|
|
@@ -30,6 +31,13 @@ Use this gem when you want a Ruby or Rails app to send telemetry into the Logist
|
|
|
30
31
|
- Product docs: https://docs.logister.org/
|
|
31
32
|
- RubyGems package: https://rubygems.org/gems/logister-ruby
|
|
32
33
|
|
|
34
|
+
## Package Links
|
|
35
|
+
|
|
36
|
+
- RubyGems package: https://rubygems.org/gems/logister-ruby
|
|
37
|
+
- GitHub releases: https://github.com/taimoorq/logister-ruby/releases
|
|
38
|
+
- Source repository: https://github.com/taimoorq/logister-ruby
|
|
39
|
+
- Integration docs: https://docs.logister.org/integrations/ruby/
|
|
40
|
+
|
|
33
41
|
## Self-hosted backend
|
|
34
42
|
|
|
35
43
|
Use the open source Logister app repository to self-host the ingestion UI/API backend:
|
|
@@ -78,6 +86,7 @@ Logister.configure do |config|
|
|
|
78
86
|
config.max_dependencies = 20
|
|
79
87
|
config.capture_sql_breadcrumbs = true
|
|
80
88
|
config.sql_breadcrumb_min_duration_ms = 25.0
|
|
89
|
+
config.capture_request_spans = true
|
|
81
90
|
|
|
82
91
|
config.feature_flags_resolver = lambda do |request:, user:, **|
|
|
83
92
|
{ new_checkout: user&.respond_to?(:beta?) && user.beta? }
|
|
@@ -121,6 +130,7 @@ end
|
|
|
121
130
|
|
|
122
131
|
If Rails is present, the gem installs middleware that reports unhandled exceptions automatically.
|
|
123
132
|
It also attaches richer context such as trace IDs, route/response/performance info, breadcrumbs, dependency calls, and user metadata when available.
|
|
133
|
+
Set `config.capture_request_spans = true` to emit root `server` spans for request load waterfall charts while keeping existing transaction events.
|
|
124
134
|
Manual `Logister.report_error` calls use the same shared enrichment path, so Ruby apps get runtime, deployment, breadcrumb, dependency, user, and nested exception cause context even when an error is reported outside the Rails middleware.
|
|
125
135
|
|
|
126
136
|
## Database load metrics (ActiveRecord)
|
|
@@ -189,6 +199,16 @@ Logister.report_transaction(
|
|
|
189
199
|
context: { trace_id: "trace-123", request_id: "req-123" }
|
|
190
200
|
)
|
|
191
201
|
|
|
202
|
+
Logister.report_span(
|
|
203
|
+
name: "render checkout",
|
|
204
|
+
duration_ms: 82.1,
|
|
205
|
+
trace_id: "trace-123",
|
|
206
|
+
parent_span_id: "span-root",
|
|
207
|
+
kind: "render",
|
|
208
|
+
status: "ok",
|
|
209
|
+
context: { route: "POST /checkout" }
|
|
210
|
+
)
|
|
211
|
+
|
|
192
212
|
Logister.report_log(
|
|
193
213
|
message: "payment provider timeout",
|
|
194
214
|
level: "warn",
|
|
@@ -269,10 +289,37 @@ Practical Insights recipes:
|
|
|
269
289
|
- Release validation: send `release`, then filter the Insights tab to the new release and compare errors, transaction P95, database query timing, and custom metrics.
|
|
270
290
|
- Queue monitoring: report metrics such as `queue.depth`, `queue.latency`, and `jobs.retry_count` with a stable `queue` context key.
|
|
271
291
|
- Performance triage: send transaction events with `route`, `service`, and `tenant_tier` so slow routes can be filtered beside errors and logs.
|
|
272
|
-
- Instrumentation audit: open Insights after deploy and confirm errors, logs, metrics, transactions, and check-ins all appear in the recent stream.
|
|
292
|
+
- Instrumentation audit: open Insights after deploy and confirm errors, logs, metrics, transactions, spans, and check-ins all appear in the recent stream.
|
|
273
293
|
|
|
274
294
|
Keep dashboard dimensions stable and low-cardinality. Good custom attribute keys include `service`, `region`, `queue`, `route`, `tenant_tier`, `provider`, and `feature_flag`. Avoid raw IDs, emails, request bodies, SQL text, and per-user values as top-level Insights dimensions.
|
|
275
295
|
|
|
296
|
+
## GitHub source context and deployments
|
|
297
|
+
|
|
298
|
+
When a Logister project is connected to a GitHub repository, set source context once so error frames and releases can resolve to the exact commit:
|
|
299
|
+
|
|
300
|
+
```ruby
|
|
301
|
+
Logister.configure do |config|
|
|
302
|
+
config.repository = ENV["LOGISTER_REPOSITORY"] || ENV["GITHUB_REPOSITORY"]
|
|
303
|
+
config.commit_sha = ENV["LOGISTER_COMMIT_SHA"] || ENV["GITHUB_SHA"]
|
|
304
|
+
config.branch = ENV["LOGISTER_BRANCH"] || ENV["GITHUB_REF_NAME"]
|
|
305
|
+
end
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
CI/CD can also record the release-to-commit mapping directly:
|
|
309
|
+
|
|
310
|
+
```ruby
|
|
311
|
+
Logister.record_deployment(
|
|
312
|
+
release: "checkout@2026.06.18",
|
|
313
|
+
environment: "production",
|
|
314
|
+
repository: "acme/checkout",
|
|
315
|
+
commit_sha: "4f8c2d1a9b7e6c5d4a3b2c1d0e9f8a7b6c5d4e3f",
|
|
316
|
+
branch: "main",
|
|
317
|
+
workflow_run_url: "https://github.com/acme/checkout/actions/runs/123"
|
|
318
|
+
)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
`config.deployment_endpoint` defaults to the configured ingest endpoint with `/ingest_events` replaced by `/deployments`. Set `LOGISTER_DEPLOYMENT_ENDPOINT` when your deployment endpoint cannot be derived from `LOGISTER_ENDPOINT`.
|
|
322
|
+
|
|
276
323
|
## Documentation
|
|
277
324
|
|
|
278
325
|
- Ruby integration docs: https://docs.logister.org/integrations/ruby/
|
|
@@ -285,15 +332,15 @@ Keep dashboard dimensions stable and low-cardinality. Good custom attribute keys
|
|
|
285
332
|
|
|
286
333
|
## Release
|
|
287
334
|
|
|
288
|
-
This repo runs CI on commits and pull requests. Version tags run the release workflow so RubyGems and GitHub Releases stay aligned:
|
|
335
|
+
This repo runs CI on commits and pull requests. After CI passes on `main`, the release-from-main workflow creates the matching version tag. Version tags run the release workflow so RubyGems and GitHub Releases stay aligned:
|
|
289
336
|
|
|
290
337
|
```bash
|
|
291
338
|
# 1) bump version in lib/logister/version.rb
|
|
292
339
|
# 2) update CHANGELOG.md
|
|
293
340
|
# 3) commit changes
|
|
294
|
-
# 4) push a matching tag
|
|
295
|
-
git tag -a v0.2.
|
|
296
|
-
git push origin main v0.2.
|
|
341
|
+
# 4) merge to main, or push a matching tag manually:
|
|
342
|
+
git tag -a v0.2.8 -m "Release logister-ruby v0.2.8"
|
|
343
|
+
git push origin main v0.2.8
|
|
297
344
|
```
|
|
298
345
|
|
|
299
346
|
The `.github/workflows/release.yml` workflow verifies the tag matches `Logister::VERSION`, runs tests, builds the gem, publishes to RubyGems with trusted publishing, and then creates or updates the matching GitHub release from `CHANGELOG.md`.
|
data/lib/logister/client.rb
CHANGED
|
@@ -17,9 +17,11 @@ module Logister
|
|
|
17
17
|
|
|
18
18
|
# Cache values that are static for the lifetime of this client so we
|
|
19
19
|
# don't allocate on every send_request call.
|
|
20
|
-
@uri
|
|
21
|
-
@
|
|
22
|
-
@
|
|
20
|
+
@uri = URI.parse(@configuration.endpoint).freeze
|
|
21
|
+
@deployment_uri = URI.parse(@configuration.deployment_endpoint).freeze
|
|
22
|
+
@use_ssl = @uri.scheme == 'https'
|
|
23
|
+
@deployment_use_ssl = @deployment_uri.scheme == 'https'
|
|
24
|
+
@auth_header = "Bearer #{@configuration.api_key}".freeze
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
def publish(payload)
|
|
@@ -31,6 +33,12 @@ module Logister
|
|
|
31
33
|
enqueue(payload)
|
|
32
34
|
end
|
|
33
35
|
|
|
36
|
+
def publish_deployment(payload)
|
|
37
|
+
return false unless ready?
|
|
38
|
+
|
|
39
|
+
publish_deployment_sync(payload)
|
|
40
|
+
end
|
|
41
|
+
|
|
34
42
|
def flush(timeout: 2)
|
|
35
43
|
return true unless @configuration.async
|
|
36
44
|
|
|
@@ -112,6 +120,22 @@ module Logister
|
|
|
112
120
|
end
|
|
113
121
|
end
|
|
114
122
|
|
|
123
|
+
def publish_deployment_sync(payload)
|
|
124
|
+
attempts = 0
|
|
125
|
+
begin
|
|
126
|
+
attempts += 1
|
|
127
|
+
send_deployment_request(payload)
|
|
128
|
+
rescue StandardError => e
|
|
129
|
+
if attempts <= @configuration.max_retries
|
|
130
|
+
sleep(@configuration.retry_base_interval * (2**(attempts - 1)))
|
|
131
|
+
retry
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
@configuration.logger.warn("logister deployment publish failed: #{e.class} #{e.message}")
|
|
135
|
+
false
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
115
139
|
def send_request(payload)
|
|
116
140
|
request = Net::HTTP::Post.new(@uri)
|
|
117
141
|
request['Content-Type'] = CONTENT_TYPE
|
|
@@ -131,6 +155,25 @@ module Logister
|
|
|
131
155
|
raise "HTTP #{response.code}"
|
|
132
156
|
end
|
|
133
157
|
|
|
158
|
+
def send_deployment_request(payload)
|
|
159
|
+
request = Net::HTTP::Post.new(@deployment_uri)
|
|
160
|
+
request['Content-Type'] = CONTENT_TYPE
|
|
161
|
+
request['Authorization'] = @auth_header
|
|
162
|
+
request.body = { deployment: payload }.to_json
|
|
163
|
+
|
|
164
|
+
response = Net::HTTP.start(
|
|
165
|
+
@deployment_uri.host,
|
|
166
|
+
@deployment_uri.port,
|
|
167
|
+
use_ssl: @deployment_use_ssl,
|
|
168
|
+
open_timeout: @configuration.timeout_seconds,
|
|
169
|
+
read_timeout: @configuration.timeout_seconds
|
|
170
|
+
) { |http| http.request(request) }
|
|
171
|
+
|
|
172
|
+
return true if response.is_a?(Net::HTTPSuccess)
|
|
173
|
+
|
|
174
|
+
raise "HTTP #{response.code}"
|
|
175
|
+
end
|
|
176
|
+
|
|
134
177
|
def monotonic_now
|
|
135
178
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
136
179
|
end
|
|
@@ -2,20 +2,26 @@ require 'logger'
|
|
|
2
2
|
|
|
3
3
|
module Logister
|
|
4
4
|
class Configuration
|
|
5
|
-
attr_accessor :api_key, :endpoint, :environment, :service, :release,
|
|
5
|
+
attr_accessor :api_key, :endpoint, :environment, :service, :release,
|
|
6
|
+
:repository, :commit_sha, :branch, :enabled, :timeout_seconds, :logger,
|
|
6
7
|
:ignore_exceptions, :ignore_environments, :ignore_paths, :before_notify,
|
|
7
8
|
:async, :queue_size, :max_retries, :retry_base_interval,
|
|
8
9
|
:capture_db_metrics, :db_metric_min_duration_ms, :db_metric_sample_rate,
|
|
9
10
|
:feature_flags_resolver, :dependency_resolver, :anonymize_ip,
|
|
10
|
-
:max_breadcrumbs, :max_dependencies,
|
|
11
|
+
:max_breadcrumbs, :max_dependencies, :capture_request_spans,
|
|
11
12
|
:capture_sql_breadcrumbs, :sql_breadcrumb_min_duration_ms
|
|
13
|
+
attr_writer :deployment_endpoint
|
|
12
14
|
|
|
13
15
|
def initialize
|
|
14
16
|
@api_key = ENV['LOGISTER_API_KEY']
|
|
15
17
|
@endpoint = ENV.fetch('LOGISTER_ENDPOINT', 'https://logister.org/api/v1/ingest_events')
|
|
18
|
+
@deployment_endpoint = env_value('LOGISTER_DEPLOYMENT_ENDPOINT')
|
|
16
19
|
@environment = ENV.fetch('RAILS_ENV', ENV.fetch('RACK_ENV', 'development'))
|
|
17
20
|
@service = ENV.fetch('LOGISTER_SERVICE', 'ruby-app')
|
|
18
21
|
@release = ENV['LOGISTER_RELEASE']
|
|
22
|
+
@repository = env_value('LOGISTER_REPOSITORY') || env_value('GITHUB_REPOSITORY')
|
|
23
|
+
@commit_sha = env_value('LOGISTER_COMMIT_SHA') || env_value('GITHUB_SHA')
|
|
24
|
+
@branch = env_value('LOGISTER_BRANCH') || env_value('GITHUB_REF_NAME')
|
|
19
25
|
@enabled = true
|
|
20
26
|
@timeout_seconds = 2
|
|
21
27
|
@logger = Logger.new($stdout)
|
|
@@ -40,8 +46,20 @@ module Logister
|
|
|
40
46
|
@anonymize_ip = false
|
|
41
47
|
@max_breadcrumbs = 40
|
|
42
48
|
@max_dependencies = 20
|
|
49
|
+
@capture_request_spans = false
|
|
43
50
|
@capture_sql_breadcrumbs = true
|
|
44
51
|
@sql_breadcrumb_min_duration_ms = 25.0
|
|
45
52
|
end
|
|
53
|
+
|
|
54
|
+
def deployment_endpoint
|
|
55
|
+
@deployment_endpoint || endpoint.to_s.sub(%r{/ingest_events\z}, '/deployments')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def env_value(name)
|
|
61
|
+
value = ENV[name].to_s.strip
|
|
62
|
+
value.empty? ? nil : value
|
|
63
|
+
end
|
|
46
64
|
end
|
|
47
65
|
end
|
|
@@ -24,12 +24,18 @@ module Logister
|
|
|
24
24
|
environment = config&.respond_to?(:environment) ? config.environment.to_s.presence : nil
|
|
25
25
|
service = config&.respond_to?(:service) ? config.service.to_s.presence : nil
|
|
26
26
|
release = config&.respond_to?(:release) ? config.release.to_s.presence : nil
|
|
27
|
+
repository = config&.respond_to?(:repository) ? config.repository.to_s.presence : nil
|
|
28
|
+
commit_sha = config&.respond_to?(:commit_sha) ? config.commit_sha.to_s.presence : nil
|
|
29
|
+
branch = config&.respond_to?(:branch) ? config.branch.to_s.presence : nil
|
|
27
30
|
|
|
28
31
|
{
|
|
29
32
|
deployment: {
|
|
30
33
|
environment: environment || ENV["RAILS_ENV"].to_s.presence || ENV["RACK_ENV"].to_s.presence || "development",
|
|
31
34
|
service: service || ENV["LOGISTER_SERVICE"].to_s.presence || "ruby-app",
|
|
32
35
|
release: release || ENV["LOGISTER_RELEASE"].to_s.presence,
|
|
36
|
+
repository: repository || ENV["LOGISTER_REPOSITORY"].to_s.presence || ENV["GITHUB_REPOSITORY"].to_s.presence,
|
|
37
|
+
commit_sha: commit_sha || ENV["LOGISTER_COMMIT_SHA"].to_s.presence || ENV["GITHUB_SHA"].to_s.presence,
|
|
38
|
+
branch: branch || ENV["LOGISTER_BRANCH"].to_s.presence || ENV["GITHUB_REF_NAME"].to_s.presence,
|
|
33
39
|
region: ENV["FLY_REGION"].to_s.presence || ENV["RAILS_REGION"].to_s.presence || ENV["AWS_REGION"].to_s.presence,
|
|
34
40
|
hostname: Socket.gethostname.to_s.presence,
|
|
35
41
|
processPid: Process.pid
|
data/lib/logister/railtie.rb
CHANGED
|
@@ -30,6 +30,7 @@ module Logister
|
|
|
30
30
|
copy_setting(app, config, :anonymize_ip)
|
|
31
31
|
copy_setting(app, config, :max_breadcrumbs)
|
|
32
32
|
copy_setting(app, config, :max_dependencies)
|
|
33
|
+
copy_setting(app, config, :capture_request_spans)
|
|
33
34
|
copy_setting(app, config, :capture_sql_breadcrumbs)
|
|
34
35
|
copy_setting(app, config, :sql_breadcrumb_min_duration_ms)
|
|
35
36
|
end
|
data/lib/logister/reporter.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'digest'
|
|
4
4
|
require 'time'
|
|
5
5
|
require 'set'
|
|
6
|
+
require 'securerandom'
|
|
6
7
|
require_relative 'context_helpers'
|
|
7
8
|
require_relative 'context_store'
|
|
8
9
|
|
|
@@ -17,8 +18,11 @@ module Logister
|
|
|
17
18
|
@static_context = {
|
|
18
19
|
environment: @configuration.environment,
|
|
19
20
|
service: @configuration.service,
|
|
20
|
-
release: @configuration.release
|
|
21
|
-
|
|
21
|
+
release: @configuration.release,
|
|
22
|
+
repository: @configuration.repository,
|
|
23
|
+
commit_sha: @configuration.commit_sha,
|
|
24
|
+
branch: @configuration.branch
|
|
25
|
+
}.compact.freeze
|
|
22
26
|
|
|
23
27
|
# Normalise ignore_environments once into a frozen Set of Strings so
|
|
24
28
|
# ignored_environment? never allocates a mapped Array.
|
|
@@ -118,6 +122,65 @@ module Logister
|
|
|
118
122
|
@client.publish(payload)
|
|
119
123
|
end
|
|
120
124
|
|
|
125
|
+
def report_span(
|
|
126
|
+
name:,
|
|
127
|
+
duration_ms:,
|
|
128
|
+
trace_id: nil,
|
|
129
|
+
request_id: nil,
|
|
130
|
+
span_id: nil,
|
|
131
|
+
parent_span_id: nil,
|
|
132
|
+
kind: 'internal',
|
|
133
|
+
status: nil,
|
|
134
|
+
started_at: nil,
|
|
135
|
+
ended_at: nil,
|
|
136
|
+
context: {},
|
|
137
|
+
tags: {},
|
|
138
|
+
fingerprint: nil
|
|
139
|
+
)
|
|
140
|
+
return false if ignored_environment?
|
|
141
|
+
return false if ignored_path?(context)
|
|
142
|
+
|
|
143
|
+
started_at ||= Time.now.utc - (duration_ms.to_f / 1000.0)
|
|
144
|
+
span_id ||= SecureRandom.hex(8)
|
|
145
|
+
trace_id ||= span_id
|
|
146
|
+
|
|
147
|
+
payload = build_payload(
|
|
148
|
+
event_type: 'span',
|
|
149
|
+
level: status.to_s == 'error' ? 'error' : 'info',
|
|
150
|
+
message: name,
|
|
151
|
+
fingerprint: fingerprint || metric_fingerprint("span:#{kind}:#{name}"),
|
|
152
|
+
context: context.merge(
|
|
153
|
+
name: name,
|
|
154
|
+
trace_id: trace_id,
|
|
155
|
+
request_id: request_id,
|
|
156
|
+
span_id: span_id,
|
|
157
|
+
parent_span_id: parent_span_id,
|
|
158
|
+
span_kind: kind,
|
|
159
|
+
kind: kind,
|
|
160
|
+
status: status,
|
|
161
|
+
duration_ms: duration_ms,
|
|
162
|
+
started_at: normalize_timestamp(started_at),
|
|
163
|
+
ended_at: ended_at && normalize_timestamp(ended_at),
|
|
164
|
+
tags: tags
|
|
165
|
+
).compact
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
payload[:started_at] = normalize_timestamp(started_at)
|
|
169
|
+
payload[:ended_at] = normalize_timestamp(ended_at) if ended_at
|
|
170
|
+
payload[:duration_ms] = duration_ms
|
|
171
|
+
payload[:trace_id] = trace_id
|
|
172
|
+
payload[:request_id] = request_id if request_id
|
|
173
|
+
payload[:span_id] = span_id
|
|
174
|
+
payload[:parent_span_id] = parent_span_id if parent_span_id
|
|
175
|
+
payload[:kind] = kind
|
|
176
|
+
payload[:status] = status if status
|
|
177
|
+
|
|
178
|
+
payload = apply_before_notify(payload)
|
|
179
|
+
return false unless payload
|
|
180
|
+
|
|
181
|
+
@client.publish(payload)
|
|
182
|
+
end
|
|
183
|
+
|
|
121
184
|
def report_log(message:, level: 'info', context: {}, tags: {}, fingerprint: nil)
|
|
122
185
|
return false if ignored_environment?
|
|
123
186
|
return false if ignored_path?(context)
|
|
@@ -175,6 +238,40 @@ module Logister
|
|
|
175
238
|
@client.publish(payload)
|
|
176
239
|
end
|
|
177
240
|
|
|
241
|
+
def record_deployment(
|
|
242
|
+
release: nil,
|
|
243
|
+
environment: nil,
|
|
244
|
+
repository: nil,
|
|
245
|
+
commit_sha: nil,
|
|
246
|
+
branch: nil,
|
|
247
|
+
deployed_at: nil,
|
|
248
|
+
pull_request_number: nil,
|
|
249
|
+
pull_request_url: nil,
|
|
250
|
+
release_tag: nil,
|
|
251
|
+
release_url: nil,
|
|
252
|
+
compare_url: nil,
|
|
253
|
+
workflow_run_url: nil,
|
|
254
|
+
deployment_url: nil
|
|
255
|
+
)
|
|
256
|
+
payload = {
|
|
257
|
+
release: release || @configuration.release,
|
|
258
|
+
environment: environment || @configuration.environment,
|
|
259
|
+
repository: repository || @configuration.repository,
|
|
260
|
+
commit_sha: commit_sha || @configuration.commit_sha,
|
|
261
|
+
branch: branch || @configuration.branch,
|
|
262
|
+
deployed_at: deployed_at && normalize_timestamp(deployed_at),
|
|
263
|
+
pull_request_number: pull_request_number,
|
|
264
|
+
pull_request_url: pull_request_url,
|
|
265
|
+
release_tag: release_tag,
|
|
266
|
+
release_url: release_url,
|
|
267
|
+
compare_url: compare_url,
|
|
268
|
+
workflow_run_url: workflow_run_url,
|
|
269
|
+
deployment_url: deployment_url
|
|
270
|
+
}.compact
|
|
271
|
+
|
|
272
|
+
@client.publish_deployment(payload)
|
|
273
|
+
end
|
|
274
|
+
|
|
178
275
|
# Store user info for the current thread so it is automatically attached to
|
|
179
276
|
# every error reported during this request.
|
|
180
277
|
#
|
|
@@ -53,10 +53,41 @@ module Logister
|
|
|
53
53
|
viewRuntimeMs: numeric(payload[:view_runtime])
|
|
54
54
|
}.compact
|
|
55
55
|
)
|
|
56
|
+
|
|
57
|
+
report_request_span(payload, request_id) if capture_request_spans?
|
|
56
58
|
rescue StandardError => e
|
|
57
59
|
logger.warn("logister request subscriber (process_action) failed: #{e.class} #{e.message}")
|
|
58
60
|
end
|
|
59
61
|
|
|
62
|
+
def report_request_span(payload, request_id)
|
|
63
|
+
duration_ms = numeric(payload[:duration])
|
|
64
|
+
return unless duration_ms&.positive?
|
|
65
|
+
|
|
66
|
+
route = "#{payload[:controller]}##{payload[:action]}"
|
|
67
|
+
started_at = Time.now.utc - (duration_ms / 1000.0)
|
|
68
|
+
|
|
69
|
+
Logister.report_span(
|
|
70
|
+
name: route,
|
|
71
|
+
kind: "server",
|
|
72
|
+
status: payload[:status].to_i >= 500 ? "error" : "ok",
|
|
73
|
+
trace_id: request_id,
|
|
74
|
+
request_id: request_id,
|
|
75
|
+
duration_ms: duration_ms,
|
|
76
|
+
started_at: started_at,
|
|
77
|
+
context: {
|
|
78
|
+
route: route,
|
|
79
|
+
request_id: request_id,
|
|
80
|
+
method: payload[:method],
|
|
81
|
+
path: payload[:path],
|
|
82
|
+
status: payload[:status],
|
|
83
|
+
timing_breakdown: {
|
|
84
|
+
db: numeric(payload[:db_runtime]),
|
|
85
|
+
render: numeric(payload[:view_runtime])
|
|
86
|
+
}.compact
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
|
|
60
91
|
def handle_sql_breadcrumb(started, finished, payload)
|
|
61
92
|
config = configuration
|
|
62
93
|
return unless config&.capture_sql_breadcrumbs
|
|
@@ -94,6 +125,12 @@ module Logister
|
|
|
94
125
|
nil
|
|
95
126
|
end
|
|
96
127
|
|
|
128
|
+
def capture_request_spans?
|
|
129
|
+
configuration&.capture_request_spans
|
|
130
|
+
rescue StandardError
|
|
131
|
+
false
|
|
132
|
+
end
|
|
133
|
+
|
|
97
134
|
def logger
|
|
98
135
|
configuration&.logger || Logger.new($stdout)
|
|
99
136
|
rescue StandardError
|
data/lib/logister/version.rb
CHANGED
data/lib/logister.rb
CHANGED
|
@@ -35,6 +35,10 @@ module Logister
|
|
|
35
35
|
reporter.report_transaction(**kwargs)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
def report_span(**kwargs)
|
|
39
|
+
reporter.report_span(**kwargs)
|
|
40
|
+
end
|
|
41
|
+
|
|
38
42
|
def report_log(**kwargs)
|
|
39
43
|
reporter.report_log(**kwargs)
|
|
40
44
|
end
|
|
@@ -43,6 +47,10 @@ module Logister
|
|
|
43
47
|
reporter.report_check_in(**kwargs)
|
|
44
48
|
end
|
|
45
49
|
|
|
50
|
+
def record_deployment(**kwargs)
|
|
51
|
+
reporter.record_deployment(**kwargs)
|
|
52
|
+
end
|
|
53
|
+
|
|
46
54
|
def flush(timeout: 2)
|
|
47
55
|
reporter.flush(timeout: timeout)
|
|
48
56
|
end
|
data/logister-ruby.gemspec
CHANGED
|
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
|
7
7
|
spec.email = ['support@logister.org']
|
|
8
8
|
|
|
9
9
|
spec.summary = 'Ruby and Rails client for sending events to Logister'
|
|
10
|
-
spec.description = 'Ruby and Rails client for reporting errors, logs, metrics, transactions, and check-ins to the Logister backend, including self-hosted installs.'
|
|
10
|
+
spec.description = 'Ruby and Rails client for reporting errors, logs, metrics, transactions, spans, and check-ins to the Logister backend, including self-hosted installs.'
|
|
11
11
|
spec.homepage = 'https://github.com/taimoorq/logister-ruby'
|
|
12
12
|
spec.license = 'MIT'
|
|
13
13
|
spec.required_ruby_version = '>= 3.1.0'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: logister-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Logister
|
|
@@ -52,7 +52,7 @@ dependencies:
|
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '13.0'
|
|
54
54
|
description: Ruby and Rails client for reporting errors, logs, metrics, transactions,
|
|
55
|
-
and check-ins to the Logister backend, including self-hosted installs.
|
|
55
|
+
spans, and check-ins to the Logister backend, including self-hosted installs.
|
|
56
56
|
email:
|
|
57
57
|
- support@logister.org
|
|
58
58
|
executables: []
|