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 +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +2 -0
- data/lib/forge_ops_tracker/query_explainer.rb +2 -1
- data/lib/forge_ops_tracker/strict_privacy.rb +9 -2
- data/lib/forge_ops_tracker/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d0c84fc309e7191793314f8b54488442383610eefe41df5f793cbfeb660bd9d5
|
|
4
|
+
data.tar.gz: e0cb23777cadde88f2c47180d86beede097d904f592e344b20703c4cc1a19541
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
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.
|
|
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
|