pinqloq 1.1.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.
- package/CHANGELOG.md +43 -0
- package/LICENSE +21 -0
- package/README.md +172 -0
- package/dist/index.cjs +716 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +96 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.js +683 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the `pinqloq` npm package are documented here. This package follows
|
|
4
|
+
[Semantic Versioning](https://semver.org). Its version numbers are independent of the .NET
|
|
5
|
+
`pinqloq` NuGet package (`sdk/ClientLogs.Client/`) — the two ship on separate cadences for the
|
|
6
|
+
same platform, and mirror each other's feature set rather than their version numbers.
|
|
7
|
+
|
|
8
|
+
## 1.1.0 — 2026-09-08
|
|
9
|
+
|
|
10
|
+
**Added:**
|
|
11
|
+
|
|
12
|
+
- `PinqloqLogEntry.path` — a fixed, indexed field for the request path, matching the .NET SDK's
|
|
13
|
+
4.3.0 wire contract change ([pinqponq/pinqloq#108](https://github.com/pinqponq/pinqloq/issues/108)).
|
|
14
|
+
The request-logging middleware fills it automatically; on a manual `enqueue` it stays unset
|
|
15
|
+
unless set explicitly.
|
|
16
|
+
|
|
17
|
+
**Changed:**
|
|
18
|
+
|
|
19
|
+
- `event` and `path` are no longer duplicated into `metadata`. The request-logging middleware
|
|
20
|
+
used to also write `metadata.event`, `metadata.path`, and `metadata.RequestPath` — those keys
|
|
21
|
+
are gone from newly-sent logs now that `event` and `path` travel as their own fixed, indexed
|
|
22
|
+
fields. A `metadata: { event: ... }` enricher still overrides the event title; it just no
|
|
23
|
+
longer leaves a copy behind in `metadata`.
|
|
24
|
+
|
|
25
|
+
If you built a saved filter or dashboard on `metadata.event`, `metadata.path`, or
|
|
26
|
+
`metadata.RequestPath`, switch it to the `Event` / `Path` fields directly. No other consumer
|
|
27
|
+
action is needed — existing code compiles unchanged.
|
|
28
|
+
|
|
29
|
+
## 1.0.0 — 2026-09-04
|
|
30
|
+
|
|
31
|
+
**Added:**
|
|
32
|
+
|
|
33
|
+
- Initial release: feature parity with the .NET SDK's core surface.
|
|
34
|
+
- `createPinqloq(options)` — buffered, batched manual structured logging (`logger.enqueue` /
|
|
35
|
+
`logger.enqueueMany`), delivered to the same `/bulk` ingest endpoint the .NET SDK uses.
|
|
36
|
+
- `client.requestLogging(options)` — Express middleware for automatic HTTP request/response
|
|
37
|
+
logging: captures method/path/status/duration, request/response bodies (32KB cap) and headers,
|
|
38
|
+
resolves `deviceIdentifier` (selector → `device-identifier` header → global fallback, HTTP 400
|
|
39
|
+
if none resolve) and `correlationId` (`correlation-id` header → generated id).
|
|
40
|
+
- Redaction: a built-in, unconditional credential-name floor (password, token, Authorization,
|
|
41
|
+
...) plus `redactFields` (name-based, any nesting depth) and `redactPaths` (whole-body/header
|
|
42
|
+
masking, the `[PinqloqRedactEndpoint]` equivalent). Fails closed on a sensitive body that can't
|
|
43
|
+
be parsed as JSON, matching the .NET SDK's behavior.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pinqponq
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Pinqloq (Node.js / Express)
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/pinqloq)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Pinqloq is a structured logging and log shipping SDK for centralized application logs. It
|
|
7
|
+
captures HTTP request/response logs through Express middleware and sends manual application
|
|
8
|
+
events to the Pinqloq log management platform using in-memory buffering, batching, and HTTPS
|
|
9
|
+
delivery. This is the Node.js counterpart of the [.NET `pinqloq` SDK](https://www.nuget.org/packages/pinqloq) —
|
|
10
|
+
same platform, same wire protocol, idiomatic API on each side.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- Automatic Express request/response logging
|
|
15
|
+
- Correlation id read from the caller's header, falling back to a generated request id
|
|
16
|
+
- Name-based redaction of sensitive fields, headers, and whole endpoints
|
|
17
|
+
- Manual structured application events
|
|
18
|
+
- Buffered and batched HTTPS delivery
|
|
19
|
+
- Graceful shutdown flush
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
- Node.js 18 or later
|
|
24
|
+
- Express 4 or 5
|
|
25
|
+
- A Pinqloq project and secret key
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install pinqloq
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
Store your secret key in an environment variable or a secret manager. Do not hardcode production
|
|
36
|
+
credentials.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import express from "express";
|
|
40
|
+
import { createPinqloq } from "pinqloq";
|
|
41
|
+
|
|
42
|
+
const pinqloq = createPinqloq({
|
|
43
|
+
secretKey: process.env.PINQLOQ_SECRET_KEY!,
|
|
44
|
+
apiLogsCollectionName: "myapp_api_logs",
|
|
45
|
+
deviceIdentifier: "myapp-instance-1"
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const app = express();
|
|
49
|
+
app.use(express.json());
|
|
50
|
+
|
|
51
|
+
// Mount AFTER body-parsing middleware so req.body is populated when the log is captured.
|
|
52
|
+
app.use(
|
|
53
|
+
pinqloq.requestLogging({
|
|
54
|
+
excludePaths: ["/health"]
|
|
55
|
+
})
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
app.listen(3000);
|
|
59
|
+
|
|
60
|
+
process.on("SIGTERM", async () => {
|
|
61
|
+
await pinqloq.shutdown();
|
|
62
|
+
process.exit(0);
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The middleware captures the HTTP method, path, and status code as searchable metadata. The
|
|
67
|
+
request body, response body, request headers, and response headers go to the log detail as
|
|
68
|
+
`InputJson`, `OutputJson`, `RequestHeaders`, and `ResponseHeaders`. Bodies are truncated at 32 KB.
|
|
69
|
+
|
|
70
|
+
## Manual Logging
|
|
71
|
+
|
|
72
|
+
Use `pinqloq.logger` to send structured application events:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
pinqloq.logger.enqueue({
|
|
76
|
+
event: "order.created",
|
|
77
|
+
deviceIdentifier: order.customerId,
|
|
78
|
+
logLevel: PinqloqLogLevel.Information,
|
|
79
|
+
logSourceType: PinqloqLogSourceType.Backend,
|
|
80
|
+
metadata: { orderId: order.id }
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`event` and `deviceIdentifier` are required on every entry. Leave `deviceIdentifier` unset on an
|
|
85
|
+
entry to inherit the global `deviceIdentifier` option. `enqueue` throws if an entry has no
|
|
86
|
+
`deviceIdentifier` and no global fallback is set — a missing required field fails loudly rather
|
|
87
|
+
than being silently dropped.
|
|
88
|
+
|
|
89
|
+
## Add Request Metadata
|
|
90
|
+
|
|
91
|
+
By default the middleware reads the required `deviceIdentifier` from the `device-identifier`
|
|
92
|
+
request header automatically. Override how it is resolved with `resolveDeviceIdentifier`; the
|
|
93
|
+
override wins, and if it returns undefined/blank the middleware falls back to the
|
|
94
|
+
`device-identifier` header, then to the global `deviceIdentifier` option. If none of these resolve
|
|
95
|
+
a value, the middleware rejects the request with **HTTP 400** before it runs.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
app.use(
|
|
99
|
+
pinqloq.requestLogging({
|
|
100
|
+
excludePaths: ["/health"],
|
|
101
|
+
resolveDeviceIdentifier: (req) => req.user?.id,
|
|
102
|
+
resolveAppVersionName: (req) => req.header("x-app-version"),
|
|
103
|
+
metadata: {
|
|
104
|
+
userId: (req) => req.user?.id
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Use `metadata` for searchable values such as user and tenant IDs. Use `detail` for additional
|
|
111
|
+
drill-down information. The `event` key (the panel title) defaults to `"{method} {path}"` and can
|
|
112
|
+
be overridden via `metadata.event`.
|
|
113
|
+
|
|
114
|
+
## Correlation ID
|
|
115
|
+
|
|
116
|
+
Every log carries a `correlationId` that ties together the records of a single request or flow.
|
|
117
|
+
The request-logging middleware fills it with no configuration: the caller's `correlation-id`
|
|
118
|
+
request header when present, otherwise a generated id.
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
pinqloq.logger.enqueue({
|
|
122
|
+
event: "order.created",
|
|
123
|
+
deviceIdentifier: order.customerId,
|
|
124
|
+
correlationId: currentCorrelationId
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Redacting Sensitive Values
|
|
129
|
+
|
|
130
|
+
Request and response bodies and headers may contain credentials, tokens, or personal information.
|
|
131
|
+
Unlike the .NET SDK's attribute-based redaction (which relies on C# reflection over typed DTOs —
|
|
132
|
+
not available at runtime in TypeScript/Express), this SDK redacts by **name**:
|
|
133
|
+
|
|
134
|
+
- `redactFields` — case-insensitive field/header names masked with `*****REDACTED*****` wherever
|
|
135
|
+
they appear in a captured body or header, at any nesting depth.
|
|
136
|
+
- `redactPaths` — path prefixes (matched the same way as `excludePaths`) where every value in
|
|
137
|
+
`InputJson`, `OutputJson`, `RequestHeaders`, and `ResponseHeaders` is masked, keeping the JSON
|
|
138
|
+
structure and header names intact — the equivalent of the .NET SDK's `[PinqloqRedactEndpoint]`.
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
app.use(
|
|
142
|
+
pinqloq.requestLogging({
|
|
143
|
+
redactFields: ["ssnLastFour"],
|
|
144
|
+
redactPaths: ["/payment"]
|
|
145
|
+
})
|
|
146
|
+
);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
A built-in, unconditional floor of common credential names (password, token, `Authorization`,
|
|
150
|
+
card numbers, ...) is always masked, even with no configuration — see
|
|
151
|
+
[`src/redaction/plan.ts`](src/redaction/plan.ts) for the full list.
|
|
152
|
+
|
|
153
|
+
## Security and Reliability
|
|
154
|
+
|
|
155
|
+
Logs are buffered in memory and sent in batches. Buffered logs may be lost if the process is
|
|
156
|
+
terminated without a graceful shutdown — call `pinqloq.shutdown()` on `SIGTERM`/`SIGINT`.
|
|
157
|
+
|
|
158
|
+
Delivery failures are reported through `onFailed` callbacks and, even without callbacks, as
|
|
159
|
+
throttled `console.error`/`console.warn` output — never silently discarded, but also never
|
|
160
|
+
blocking. If your secret key is authorized for more than one collection, set
|
|
161
|
+
`apiLogsCollectionName` (or a per-entry `collectionName`); otherwise the batch is rejected.
|
|
162
|
+
|
|
163
|
+
## Documentation
|
|
164
|
+
|
|
165
|
+
- [.NET SDK](https://www.nuget.org/packages/pinqloq) — the reference implementation for this
|
|
166
|
+
platform's wire protocol and feature set.
|
|
167
|
+
- [Ruby SDK](https://rubygems.org/gems/pinqloq), [Go SDK](https://pkg.go.dev/github.com/pinqponq/pinqloq-go-sdk) — the other implementations.
|
|
168
|
+
- [Full documentation](https://pinqloq.pinqponq.io/documentation.html)
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
MIT
|