forge_ops_tracker 0.19.0 → 0.20.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: 3d585c1acbde6c8bb06ec05505e21bf4d784974ed8e655c9398fef0c7e595d03
4
- data.tar.gz: af67478c90a33dd594bbccf712e48dc817d5e99ae6b61edf0a0fca62e816e4ec
3
+ metadata.gz: d0c84fc309e7191793314f8b54488442383610eefe41df5f793cbfeb660bd9d5
4
+ data.tar.gz: e0cb23777cadde88f2c47180d86beede097d904f592e344b20703c4cc1a19541
5
5
  SHA512:
6
- metadata.gz: ae806f1ba9cb14102494df6f6efca7685ce4900c281fda85c72fe9ad595f5ce3b03b7daf74762ef69de002e0c229d3155027eee4bd3c8d876646b824f4ee1ab4
7
- data.tar.gz: b774e7abc22663d23f728c71ee7d358180994ccc31b23eb334d393c39da7d403561456b4b484bbe34f3f1678c7f619a40ac94c977a4086ccac66f852790cdb85
6
+ metadata.gz: d0be76c8e1855c31d3949e7c8ef337bf90a34067c78be75c30498a8b0624083c2df69a61ecae76f793cfe15e30552ca66410dc2a527a6d18768760247621573b
7
+ data.tar.gz: 7345a1130c32bc7cc8a261d2c1d0f3940edf3b92f99a8472521211805d6a282a65e445d6b03e12819516b89537c292c8fe9f0800a9117afb944073b3f465044d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.20.0 (2026-10-22)
4
+
5
+ - Strict privacy: the message fingerprint now also replaces email addresses with `<email>` and quoted
6
+ values (`"..."`, and `'...'` when the quotes aren't part of a word) with `<str>`, before the existing
7
+ steps. `KeyError: 'Jane Doe'` and `KeyError: 'Bob Smith'` now group together, and no guessable value sits
8
+ behind the hash. Errors whose messages contain quotes or emails get new fingerprints once, so they open
9
+ new issues after upgrading.
10
+
11
+ ## 0.19.1 (2026-10-22)
12
+
13
+ - Strict privacy now also turns off slow query plans (`explain_slow_queries`): no EXPLAIN is run and no
14
+ plan is sent, since a plan carries the SQL. Before, a plan could still be sent, with its values masked.
15
+ - The README says what strict privacy does in its opening lines.
16
+ - The source is public at https://github.com/Luke-Popwell/forge-ops-tracker-ruby, and the package links to it.
17
+
3
18
  ## 0.19.0 (2026-10-20)
4
19
 
5
20
  - Strict privacy: a raw request path now keeps only its first segment, and the rest is sent as
data/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  Exception reporting client for [ForgeOps](https://getforgeops.net), for Rails, plain Rack and
4
4
  Sinatra apps, and scripts.
5
5
 
6
+ > For health or personal data, turn on [strict privacy](#strict-privacy): the SDK then sends only structured facts about each error (its type, stack trace, release and route), never the message, a raw path, breadcrumbs, or context you haven't allowed.
7
+
6
8
  ## Installation
7
9
 
8
10
  ```ruby
@@ -98,7 +98,8 @@ module ForgeOpsTracker
98
98
  # checks first, so a fast query costs one comparison. Returns true only when an EXPLAIN was
99
99
  # queued; never raises.
100
100
  def consider(payload, duration_ms:)
101
- return false unless configuration.explain_slow_queries
101
+ # Strict privacy sends no SQL at all, masked or not (sdks/STRICT_PRIVACY.md).
102
+ return false unless configuration.explain_slow_queries && !configuration.strict_privacy
102
103
  return false unless duration_ms && duration_ms >= configuration.explain_threshold_ms.to_f
103
104
 
104
105
  connection = payload[:connection]
@@ -18,6 +18,11 @@ module ForgeOpsTracker
18
18
  # ASCII "word" characters; boundaries are defined against these, the same in every SDK, so
19
19
  # Ruby's own idea of a word never changes the result.
20
20
  WORD = "A-Za-z0-9_".freeze
21
+ EMAIL = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/
22
+ # A quoted value (KeyError: 'Jane Doe') is data, not the shape of the error. Single quotes only open
23
+ # and close at a word boundary, so a contraction (Couldn't) or the `email' style never starts one.
24
+ DOUBLE_QUOTED = /"[^"\r\n]*"/
25
+ SINGLE_QUOTED = /(?<![#{WORD}])'[^'\r\n]*'(?![#{WORD}])/
21
26
  HEX_OBJECT_ID = /0x[0-9a-fA-F]{4,}/
22
27
  UUID = /(?<![#{WORD}])[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}(?![#{WORD}])/
23
28
  NUMBER = /(?<![#{WORD}])[0-9]+(?![#{WORD}])/
@@ -34,9 +39,11 @@ module ForgeOpsTracker
34
39
 
35
40
  module_function
36
41
 
37
- # The message with hex object ids, UUIDs and standalone numbers replaced, in that order.
42
+ # The message with emails, quoted values, hex object ids, UUIDs and standalone numbers replaced, in
43
+ # that order (sdks/STRICT_PRIVACY.md).
38
44
  def normalize_message(message)
39
- message.to_s.gsub(HEX_OBJECT_ID, "0x").gsub(UUID, "<uuid>").gsub(NUMBER, "<n>")
45
+ message.to_s.gsub(EMAIL, "<email>").gsub(DOUBLE_QUOTED, "<str>").gsub(SINGLE_QUOTED, "<str>")
46
+ .gsub(HEX_OBJECT_ID, "0x").gsub(UUID, "<uuid>").gsub(NUMBER, "<n>")
40
47
  end
41
48
 
42
49
  # Lets ForgeOps group errors without ever seeing their message: the first 32 hex characters of
@@ -1,3 +1,3 @@
1
1
  module ForgeOpsTracker
2
- VERSION = "0.19.0"
2
+ VERSION = "0.20.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forge_ops_tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ForgeOps
@@ -147,6 +147,8 @@ licenses:
147
147
  metadata:
148
148
  homepage_uri: https://getforgeops.net
149
149
  rubygems_mfa_required: 'true'
150
+ source_code_uri: https://github.com/Luke-Popwell/forge-ops-tracker-ruby
151
+ changelog_uri: https://github.com/Luke-Popwell/forge-ops-tracker-ruby/blob/main/CHANGELOG.md
150
152
  rdoc_options: []
151
153
  require_paths:
152
154
  - lib