pinqloq 1.2.0 → 1.2.1
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 +24 -0
- data/README.md +9 -14
- data/lib/pinqloq/client.rb +1 -1
- data/lib/pinqloq/http/ingest_api_client.rb +1 -1
- data/lib/pinqloq/logger.rb +1 -19
- data/lib/pinqloq/options.rb +2 -4
- data/lib/pinqloq/rack/request_logging.rb +1 -11
- data/lib/pinqloq/version.rb +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: 914e5824e9dd8331e2c0ccb92e166d8e4f00ac14e49c19430d0106bf2eb1dd53
|
|
4
|
+
data.tar.gz: 7c3de9222525f8f1ee6d7faf746065711a49da6af8f57b3d2f34467427e6d957
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b81217eb46cbec0af99e1a03c0d09a4bd62c7b6122ed8c542ddb81693b4c1bba3ad3541aa11b10ab2ca27ec4a83fc475c512948602cafccc651f7b1209cec0d7
|
|
7
|
+
data.tar.gz: f83ff0b79f361ab163449c75ae131e4d200d2417471639e884be798a372641f746905c154fef79128b8ebdc3f73a80d52501e0b614570facb98d14f7e9f9863b
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ All notable changes to the `pinqloq` gem are documented here. This gem follows
|
|
|
5
5
|
`pinqloq` NuGet package and the `pinqloq` npm package — all three ship on separate cadences for
|
|
6
6
|
the same platform, and mirror each other's feature set rather than their version numbers.
|
|
7
7
|
|
|
8
|
+
## 1.2.1 — 2026-09-18
|
|
9
|
+
|
|
10
|
+
**Changed:**
|
|
11
|
+
|
|
12
|
+
- `device_identifier` is now optional.
|
|
13
|
+
- The request-logging middleware no longer rejects a request with HTTP 400 when no
|
|
14
|
+
`device_identifier` resolves. The log is sent without one.
|
|
15
|
+
- `enqueue` / `enqueue_many` no longer raise when an entry has no `device_identifier`.
|
|
16
|
+
- A blank `device_identifier` is now sent as `null` instead of an empty string. The ingest API
|
|
17
|
+
accepts logs without one and stores `null`.
|
|
18
|
+
|
|
19
|
+
**Changed (breaking):**
|
|
20
|
+
|
|
21
|
+
- `Pinqloq::Options#device_identifier` removed ([pinqponq/pinqloq-dashboard#57](https://github.com/pinqponq/pinqloq-dashboard/issues/57)).
|
|
22
|
+
With the field optional, a global fallback for it had nothing left to guarantee.
|
|
23
|
+
`device_identifier` is now set per entry on a manual `enqueue`, and resolved per request by
|
|
24
|
+
`resolve_device_identifier` then the `device-identifier` header — nothing after that. Drop
|
|
25
|
+
`device_identifier:` from `Pinqloq.create(...)`; it now raises `ArgumentError: unknown keyword`.
|
|
26
|
+
If you relied on it to guarantee a value, pass `resolve_device_identifier:` instead.
|
|
27
|
+
- `Pinqloq::Rack::RequestLogging` no longer takes `pinqloq_options:`. It only read that object to
|
|
28
|
+
reach the removed fallback, so the keyword is gone; remove
|
|
29
|
+
`pinqloq_options: pinqloq_client.options` from your `use` line or Rack raises
|
|
30
|
+
`ArgumentError: unknown keyword`.
|
|
31
|
+
|
|
8
32
|
## 1.2.0 — 2026-09-12
|
|
9
33
|
|
|
10
34
|
**Added:**
|
data/README.md
CHANGED
|
@@ -49,14 +49,12 @@ require "pinqloq"
|
|
|
49
49
|
|
|
50
50
|
pinqloq_client = Pinqloq.create(
|
|
51
51
|
secret_key: ENV.fetch("PINQLOQ_SECRET_KEY"),
|
|
52
|
-
api_logs_collection_name: "myapp_api_logs"
|
|
53
|
-
device_identifier: "myapp-instance-1"
|
|
52
|
+
api_logs_collection_name: "myapp_api_logs"
|
|
54
53
|
)
|
|
55
54
|
|
|
56
55
|
# Rack app / Rails config/application.rb / config.ru
|
|
57
56
|
use Pinqloq::Rack::RequestLogging,
|
|
58
57
|
logger: pinqloq_client.logger,
|
|
59
|
-
pinqloq_options: pinqloq_client.options,
|
|
60
58
|
exclude_paths: ["/health"]
|
|
61
59
|
|
|
62
60
|
at_exit { pinqloq_client.shutdown }
|
|
@@ -82,26 +80,24 @@ pinqloq_client.enqueue(
|
|
|
82
80
|
)
|
|
83
81
|
```
|
|
84
82
|
|
|
85
|
-
`event`
|
|
86
|
-
|
|
87
|
-
`device_identifier` and no global fallback
|
|
88
|
-
|
|
83
|
+
`event` is required on every entry.
|
|
84
|
+
|
|
85
|
+
`device_identifier` is optional and has no global fallback: set it per entry, and an entry that
|
|
86
|
+
leaves it unset is stored without one.
|
|
89
87
|
|
|
90
88
|
`pinqloq_client.logger` still returns the same `Logger` — useful when you want to pass just the
|
|
91
89
|
logging capability into a function without handing it the whole client.
|
|
92
90
|
|
|
93
91
|
## Add Request Metadata
|
|
94
92
|
|
|
95
|
-
By default the middleware reads the
|
|
96
|
-
request header
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
middleware rejects the request with **HTTP 400** before it runs.
|
|
93
|
+
By default the middleware reads the optional `device_identifier` from the `device-identifier`
|
|
94
|
+
request header. Override how it is resolved with `resolve_device_identifier`. The override wins;
|
|
95
|
+
if it returns nil/blank, the middleware falls back to the `device-identifier` header. If neither
|
|
96
|
+
resolves a value, the log is stored without a `device_identifier`.
|
|
100
97
|
|
|
101
98
|
```ruby
|
|
102
99
|
use Pinqloq::Rack::RequestLogging,
|
|
103
100
|
logger: pinqloq_client.logger,
|
|
104
|
-
pinqloq_options: pinqloq_client.options,
|
|
105
101
|
exclude_paths: ["/health"],
|
|
106
102
|
resolve_device_identifier: ->(request) { request.session[:user_id] },
|
|
107
103
|
resolve_app_version_name: ->(request) { request.get_header("HTTP_X_APP_VERSION") },
|
|
@@ -146,7 +142,6 @@ redacts by **name**, exactly like the Node.js SDK:
|
|
|
146
142
|
```ruby
|
|
147
143
|
use Pinqloq::Rack::RequestLogging,
|
|
148
144
|
logger: pinqloq_client.logger,
|
|
149
|
-
pinqloq_options: pinqloq_client.options,
|
|
150
145
|
redact_fields: ["ssn_last_four"],
|
|
151
146
|
redact_paths: ["/payment"]
|
|
152
147
|
```
|
data/lib/pinqloq/client.rb
CHANGED
|
@@ -16,7 +16,7 @@ module Pinqloq
|
|
|
16
16
|
@buffer = Buffering::LogBuffer.new(options.queue_capacity)
|
|
17
17
|
api_client = Http::IngestApiClient.new(options)
|
|
18
18
|
@dispatcher = Buffering::LogDispatcher.new(@buffer, api_client, options)
|
|
19
|
-
@logger = Logger.new(@buffer, @dispatcher
|
|
19
|
+
@logger = Logger.new(@buffer, @dispatcher)
|
|
20
20
|
|
|
21
21
|
@dispatcher.start
|
|
22
22
|
end
|
|
@@ -137,7 +137,7 @@ module Pinqloq
|
|
|
137
137
|
app_version_name = (app_version_name && !app_version_name.empty?) ? entry.app_version_name : @options.app_version_name
|
|
138
138
|
|
|
139
139
|
device_identifier = entry.device_identifier&.strip
|
|
140
|
-
device_identifier =
|
|
140
|
+
device_identifier = nil if device_identifier&.empty?
|
|
141
141
|
|
|
142
142
|
{
|
|
143
143
|
logLevel: entry.log_level,
|
data/lib/pinqloq/logger.rb
CHANGED
|
@@ -2,39 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
module Pinqloq
|
|
4
4
|
class Logger
|
|
5
|
-
|
|
6
|
-
"Pinqloq: device_identifier is required. Set it on the entry, or configure the global " \
|
|
7
|
-
"Options#device_identifier fallback."
|
|
8
|
-
|
|
9
|
-
def initialize(buffer, dispatcher, options)
|
|
5
|
+
def initialize(buffer, dispatcher)
|
|
10
6
|
@buffer = buffer
|
|
11
7
|
@dispatcher = dispatcher
|
|
12
|
-
@options = options
|
|
13
8
|
end
|
|
14
9
|
|
|
15
10
|
def enqueue(entry, on_sent: nil, on_failed: nil)
|
|
16
|
-
ensure_device_identifier!(entry)
|
|
17
11
|
written = @buffer.enqueue(entry, on_sent: on_sent, on_failed: on_failed)
|
|
18
12
|
@dispatcher.notify_enqueued
|
|
19
13
|
written
|
|
20
14
|
end
|
|
21
15
|
|
|
22
16
|
def enqueue_many(entries, on_sent: nil, on_failed: nil)
|
|
23
|
-
entries.each { |entry| ensure_device_identifier!(entry) }
|
|
24
17
|
written = @buffer.enqueue_many(entries, on_sent: on_sent, on_failed: on_failed)
|
|
25
18
|
@dispatcher.notify_enqueued
|
|
26
19
|
written
|
|
27
20
|
end
|
|
28
|
-
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
def ensure_device_identifier!(entry)
|
|
32
|
-
entry_value = entry.device_identifier&.strip
|
|
33
|
-
global_value = @options.device_identifier&.strip
|
|
34
|
-
|
|
35
|
-
return if (entry_value && !entry_value.empty?) || (global_value && !global_value.empty?)
|
|
36
|
-
|
|
37
|
-
raise DEVICE_IDENTIFIER_REQUIRED_MESSAGE
|
|
38
|
-
end
|
|
39
21
|
end
|
|
40
22
|
end
|
data/lib/pinqloq/options.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Pinqloq
|
|
|
11
11
|
DEFAULT_HTTP_TIMEOUT = 10.0
|
|
12
12
|
|
|
13
13
|
attr_reader :secret_key, :api_logs_collection_name, :bulk_path, :batch_size,
|
|
14
|
-
:flush_interval, :queue_capacity, :http_timeout, :app_version_name
|
|
14
|
+
:flush_interval, :queue_capacity, :http_timeout, :app_version_name
|
|
15
15
|
|
|
16
16
|
def initialize(
|
|
17
17
|
secret_key:,
|
|
@@ -21,8 +21,7 @@ module Pinqloq
|
|
|
21
21
|
flush_interval: DEFAULT_FLUSH_INTERVAL,
|
|
22
22
|
queue_capacity: DEFAULT_QUEUE_CAPACITY,
|
|
23
23
|
http_timeout: DEFAULT_HTTP_TIMEOUT,
|
|
24
|
-
app_version_name: nil
|
|
25
|
-
device_identifier: nil
|
|
24
|
+
app_version_name: nil
|
|
26
25
|
)
|
|
27
26
|
raise ArgumentError, "Pinqloq: secret_key is required." if secret_key.nil? || secret_key.strip.empty?
|
|
28
27
|
|
|
@@ -34,7 +33,6 @@ module Pinqloq
|
|
|
34
33
|
@queue_capacity = [1, queue_capacity].max
|
|
35
34
|
@http_timeout = [0.001, http_timeout].max
|
|
36
35
|
@app_version_name = app_version_name
|
|
37
|
-
@device_identifier = device_identifier
|
|
38
36
|
end
|
|
39
37
|
end
|
|
40
38
|
end
|
|
@@ -19,11 +19,6 @@ module Pinqloq
|
|
|
19
19
|
DEVICE_IDENTIFIER_HEADER_NAME = "device-identifier"
|
|
20
20
|
CORRELATION_ID_HEADER_NAME = "correlation-id"
|
|
21
21
|
|
|
22
|
-
DEVICE_IDENTIFIER_REQUIRED_MESSAGE =
|
|
23
|
-
"Pinqloq: the required device_identifier could not be resolved. Send the " \
|
|
24
|
-
"'device-identifier' request header, or configure resolve_device_identifier, or set " \
|
|
25
|
-
"Options#device_identifier."
|
|
26
|
-
|
|
27
22
|
SERVER_ERROR_STATUS_THRESHOLD = 500
|
|
28
23
|
CLIENT_ERROR_STATUS_THRESHOLD = 400
|
|
29
24
|
|
|
@@ -32,7 +27,6 @@ module Pinqloq
|
|
|
32
27
|
def initialize(
|
|
33
28
|
app,
|
|
34
29
|
logger:,
|
|
35
|
-
pinqloq_options:,
|
|
36
30
|
exclude_paths: [],
|
|
37
31
|
resolve_device_identifier: nil,
|
|
38
32
|
resolve_app_version_name: nil,
|
|
@@ -43,7 +37,6 @@ module Pinqloq
|
|
|
43
37
|
)
|
|
44
38
|
@app = app
|
|
45
39
|
@logger = logger
|
|
46
|
-
@pinqloq_options = pinqloq_options
|
|
47
40
|
@exclude_paths = exclude_paths
|
|
48
41
|
@resolve_device_identifier = resolve_device_identifier
|
|
49
42
|
@resolve_app_version_name = resolve_app_version_name
|
|
@@ -60,9 +53,6 @@ module Pinqloq
|
|
|
60
53
|
return @app.call(env) if PathMatch.matches_any_prefix?(path, @exclude_paths)
|
|
61
54
|
|
|
62
55
|
device_identifier = resolve_device_identifier(request)
|
|
63
|
-
if device_identifier.nil? || device_identifier.strip.empty?
|
|
64
|
-
return [400, { "Content-Type" => "text/plain" }, [DEVICE_IDENTIFIER_REQUIRED_MESSAGE]]
|
|
65
|
-
end
|
|
66
56
|
|
|
67
57
|
redact_plan = build_redact_plan(path)
|
|
68
58
|
started_at = monotonic_now
|
|
@@ -157,7 +147,7 @@ module Pinqloq
|
|
|
157
147
|
header = request.get_header(rack_header_key(DEVICE_IDENTIFIER_HEADER_NAME))
|
|
158
148
|
return header unless header.nil? || header.strip.empty?
|
|
159
149
|
|
|
160
|
-
|
|
150
|
+
nil
|
|
161
151
|
end
|
|
162
152
|
|
|
163
153
|
def resolve_correlation_id(request)
|
data/lib/pinqloq/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pinqloq
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- pinqponq
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|