logister-ruby 0.2.7 → 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 +5 -0
- data/README.md +31 -4
- data/lib/logister/client.rb +46 -3
- data/lib/logister/configuration.rb +18 -1
- data/lib/logister/context_helpers.rb +6 -0
- data/lib/logister/reporter.rb +39 -2
- data/lib/logister/version.rb +1 -1
- data/lib/logister.rb +4 -0
- metadata +1 -1
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,10 @@
|
|
|
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
|
+
|
|
3
8
|
## v0.2.7 - 2026-05-22
|
|
4
9
|
|
|
5
10
|
- Added `Logister.report_span` and opt-in Rails request span capture for request load waterfall charts.
|
data/README.md
CHANGED
|
@@ -293,6 +293,33 @@ Practical Insights recipes:
|
|
|
293
293
|
|
|
294
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.
|
|
295
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
|
+
|
|
296
323
|
## Documentation
|
|
297
324
|
|
|
298
325
|
- Ruby integration docs: https://docs.logister.org/integrations/ruby/
|
|
@@ -305,15 +332,15 @@ Keep dashboard dimensions stable and low-cardinality. Good custom attribute keys
|
|
|
305
332
|
|
|
306
333
|
## Release
|
|
307
334
|
|
|
308
|
-
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:
|
|
309
336
|
|
|
310
337
|
```bash
|
|
311
338
|
# 1) bump version in lib/logister/version.rb
|
|
312
339
|
# 2) update CHANGELOG.md
|
|
313
340
|
# 3) commit changes
|
|
314
|
-
# 4) push a matching tag
|
|
315
|
-
git tag -a v0.2.
|
|
316
|
-
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
|
|
317
344
|
```
|
|
318
345
|
|
|
319
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
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)
|
|
@@ -44,5 +50,16 @@ module Logister
|
|
|
44
50
|
@capture_sql_breadcrumbs = true
|
|
45
51
|
@sql_breadcrumb_min_duration_ms = 25.0
|
|
46
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
|
|
47
64
|
end
|
|
48
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/reporter.rb
CHANGED
|
@@ -18,8 +18,11 @@ module Logister
|
|
|
18
18
|
@static_context = {
|
|
19
19
|
environment: @configuration.environment,
|
|
20
20
|
service: @configuration.service,
|
|
21
|
-
release: @configuration.release
|
|
22
|
-
|
|
21
|
+
release: @configuration.release,
|
|
22
|
+
repository: @configuration.repository,
|
|
23
|
+
commit_sha: @configuration.commit_sha,
|
|
24
|
+
branch: @configuration.branch
|
|
25
|
+
}.compact.freeze
|
|
23
26
|
|
|
24
27
|
# Normalise ignore_environments once into a frozen Set of Strings so
|
|
25
28
|
# ignored_environment? never allocates a mapped Array.
|
|
@@ -235,6 +238,40 @@ module Logister
|
|
|
235
238
|
@client.publish(payload)
|
|
236
239
|
end
|
|
237
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
|
+
|
|
238
275
|
# Store user info for the current thread so it is automatically attached to
|
|
239
276
|
# every error reported during this request.
|
|
240
277
|
#
|
data/lib/logister/version.rb
CHANGED
data/lib/logister.rb
CHANGED