@glassops/scribe 1.0.2 → 1.0.4
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/README.md +90 -73
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types.d.ts +17 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,35 +20,42 @@ This ensures production, staging, and development never collide, and that multi
|
|
|
20
20
|
### Structured, operationally meaningful logs
|
|
21
21
|
|
|
22
22
|
- JSON‑structured entries with timestamps.
|
|
23
|
-
- Daily
|
|
24
|
-
- Semantic log levels (critical
|
|
25
|
-
- Request
|
|
23
|
+
- Daily-rotated files with configurable retention (default: 14 days).
|
|
24
|
+
- Semantic log levels (`critical`, `change`, `http`, etc.) mapped to dedicated transports.
|
|
25
|
+
- Request-scoped metadata (`tenant`, `service`, `environment`, `user`, `correlationId`, `requestId`).
|
|
26
26
|
|
|
27
27
|
### Deep, case‑insensitive redaction
|
|
28
28
|
|
|
29
29
|
Sensitive keys are removed at any depth, regardless of casing:
|
|
30
30
|
|
|
31
|
-
- password
|
|
32
|
-
- authorization
|
|
31
|
+
- `password`, `Password`, `PASSWORD`
|
|
32
|
+
- `authorization`, `Authorization`, etc.
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Other behaviors:
|
|
35
|
+
|
|
36
|
+
- Circular references → `"[Circular]"`
|
|
37
|
+
- Buffers → `"[Binary]"`
|
|
35
38
|
|
|
36
39
|
### Transport‑agnostic architecture
|
|
37
40
|
|
|
38
41
|
File transports are enabled by default, but Scribe supports:
|
|
39
42
|
|
|
40
|
-
- Console‑only mode
|
|
41
|
-
- Cloud‑only mode
|
|
42
|
-
- Hybrid mode
|
|
43
|
+
- Console‑only mode
|
|
44
|
+
- Cloud‑only mode
|
|
45
|
+
- Hybrid mode
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
Configurable through:
|
|
45
48
|
|
|
46
49
|
- `disableFileTransports`
|
|
47
50
|
- `extraTransports`
|
|
48
51
|
|
|
49
52
|
### Pure, re‑entrant API
|
|
50
53
|
|
|
51
|
-
No global state
|
|
54
|
+
- No global state
|
|
55
|
+
- No shared mutable configuration
|
|
56
|
+
- No hidden defaults
|
|
57
|
+
|
|
58
|
+
Every logger instance is fully deterministic and scoped.
|
|
52
59
|
|
|
53
60
|
## Installation
|
|
54
61
|
|
|
@@ -60,18 +67,16 @@ npm install @glassops/scribe
|
|
|
60
67
|
|
|
61
68
|
Scribe is built around three principles:
|
|
62
69
|
|
|
63
|
-
- Identity is explicit
|
|
64
|
-
- Streams are semantic
|
|
65
|
-
- Safety is mandatory
|
|
70
|
+
- **Identity is explicit**: Every log entry carries a complete scope describing tenant, environment, service, and correlation identifiers.
|
|
71
|
+
- **Streams are semantic**: Incidents, changes, HTTP traffic, and application logs are treated as distinct operational categories.
|
|
72
|
+
- **Safety is mandatory**: Redaction, sanitization, and directory grammar are enforced before logs reach any transport.
|
|
66
73
|
|
|
67
74
|
## Directory structure
|
|
68
75
|
|
|
69
|
-
|
|
76
|
+
All segments of the directory path are sanitized to prevent traversal or invalid characters.
|
|
70
77
|
|
|
71
|
-
With service: `<target>/<service>/<tenant>`
|
|
72
|
-
Without service: `<target>/<tenant>/<environment>`
|
|
73
|
-
|
|
74
|
-
All segments are sanitized to prevent traversal or invalid characters.
|
|
78
|
+
- With service: `<target>/<service>/<tenant>`
|
|
79
|
+
- Without service: `<target>/<tenant>/<environment>`
|
|
75
80
|
|
|
76
81
|
## Usage
|
|
77
82
|
|
|
@@ -92,20 +97,24 @@ const directory = createDirectory("/var/logs", {
|
|
|
92
97
|
```ts
|
|
93
98
|
import { createLogger } from "@glassops/scribe";
|
|
94
99
|
|
|
95
|
-
const logger = createLogger(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
100
|
+
const logger = createLogger(
|
|
101
|
+
directory,
|
|
102
|
+
{
|
|
103
|
+
tenant: "acme",
|
|
104
|
+
environment: "production",
|
|
105
|
+
service: "billing",
|
|
106
|
+
correlationId: "abc123",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
level: "info",
|
|
110
|
+
requestLog: "requests-%DATE%.log",
|
|
111
|
+
appLog: "app-%DATE%.log",
|
|
112
|
+
incidentLog: "incident-%DATE%.log",
|
|
113
|
+
changeLog: "change-%DATE%.log",
|
|
114
|
+
logToConsole: true,
|
|
115
|
+
sensitiveKeys: ["password", "token"],
|
|
116
|
+
}
|
|
117
|
+
);
|
|
109
118
|
```
|
|
110
119
|
|
|
111
120
|
## Logging methods
|
|
@@ -124,47 +133,62 @@ Example:
|
|
|
124
133
|
```ts
|
|
125
134
|
logger.logInfo("User updated profile", {
|
|
126
135
|
userId: "123",
|
|
127
|
-
password: "secret", // redacted
|
|
136
|
+
password: "secret", // redacted automatically
|
|
128
137
|
});
|
|
129
138
|
```
|
|
130
139
|
|
|
131
140
|
## HTTP logging (Morgan integration)
|
|
132
141
|
|
|
142
|
+
Scribe supports direct integration with Morgan. ANSI sequences are stripped before writing to ensure clean JSON logs:
|
|
143
|
+
|
|
133
144
|
```ts
|
|
134
145
|
app.use(morgan("combined", { stream: logger.createLoggerStream() }));
|
|
135
146
|
```
|
|
136
147
|
|
|
137
|
-
ANSI sequences are stripped before writing, ensuring clean machine‑readable logs.
|
|
138
|
-
|
|
139
148
|
## Redaction behavior
|
|
140
149
|
|
|
141
|
-
|
|
150
|
+
- Case-insensitive key matching
|
|
151
|
+
- Nested sensitive fields are recursively redacted
|
|
152
|
+
- **Circular references**: `"[Circular]"`
|
|
153
|
+
- **Buffers**: `"[Binary]"`
|
|
154
|
+
|
|
155
|
+
## Scoping
|
|
156
|
+
|
|
157
|
+
You can derive a new logger with additional metadata:
|
|
142
158
|
|
|
143
159
|
```ts
|
|
144
|
-
{
|
|
145
|
-
|
|
146
|
-
nested: {
|
|
147
|
-
token: "[REDACTED]"
|
|
148
|
-
}
|
|
149
|
-
}
|
|
160
|
+
const userLogger = await logger.scope({ user: "steven" });
|
|
161
|
+
userLogger.logInfo("User action");
|
|
150
162
|
```
|
|
151
163
|
|
|
152
|
-
|
|
153
|
-
- Circular references → "[Circular]"
|
|
154
|
-
- Buffers → "[Binary]"
|
|
164
|
+
Produces a new logger instance with merged scope. Logger directory may change if scope affects service or environment.
|
|
155
165
|
|
|
156
|
-
|
|
166
|
+
Existing transports are closed and rebuilt automatically if necessary.
|
|
157
167
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
168
|
+
## Logger API
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
interface ScribeLogger {
|
|
172
|
+
logError(error: string | Error, context?: Record<string, unknown>): void;
|
|
173
|
+
logWarn(message: string, context?: Record<string, unknown>): void;
|
|
174
|
+
logInfo(message: string, context?: Record<string, unknown>): void;
|
|
175
|
+
logDebug(message: string, context?: Record<string, unknown>): void;
|
|
176
|
+
logIncident(message: string, context?: Record<string, unknown>): void;
|
|
177
|
+
logChange(message: string, context?: Record<string, unknown>): void;
|
|
178
|
+
createLoggerStream(): { write: (message: string) => void };
|
|
179
|
+
scope(partial: Partial<LoggerScope>): Promise<void>;
|
|
180
|
+
close(): Promise<void>;
|
|
181
|
+
logger: Logger;
|
|
182
|
+
}
|
|
183
|
+
```
|
|
161
184
|
|
|
162
|
-
|
|
185
|
+
- `createLoggerStream()`: Returns a Morgan-compatible writable stream.
|
|
186
|
+
- `scope()`: Returns a `Promise<void>`; merges partial metadata into current logger.
|
|
187
|
+
- `close()`: Gracefully shuts down transports.
|
|
188
|
+
- `logger`: Exposes underlying Winston Logger instance.
|
|
163
189
|
|
|
164
190
|
## Transport configuration
|
|
165
191
|
|
|
166
|
-
Scribe supports file‑based, console‑only, cloud‑only, and hybrid modes.
|
|
167
|
-
|
|
168
192
|
```ts
|
|
169
193
|
interface LoggerOptions {
|
|
170
194
|
level: LogLevel;
|
|
@@ -175,7 +199,6 @@ interface LoggerOptions {
|
|
|
175
199
|
logToConsole?: boolean;
|
|
176
200
|
sensitiveKeys?: string[];
|
|
177
201
|
retention?: string;
|
|
178
|
-
|
|
179
202
|
disableFileTransports?: boolean;
|
|
180
203
|
extraTransports?: Transport[];
|
|
181
204
|
}
|
|
@@ -191,11 +214,13 @@ interface LoggerOptions {
|
|
|
191
214
|
- `change`
|
|
192
215
|
- `debug`
|
|
193
216
|
|
|
217
|
+
Each level is treated as a separate operational stream rather than a severity threshold.
|
|
218
|
+
|
|
194
219
|
## Build and publish
|
|
195
220
|
|
|
196
|
-
Scribe uses a strict file whitelist and
|
|
221
|
+
Scribe uses a strict file whitelist and deterministic build pipeline.
|
|
197
222
|
|
|
198
|
-
|
|
223
|
+
### Scripts
|
|
199
224
|
|
|
200
225
|
```json
|
|
201
226
|
{
|
|
@@ -207,13 +232,13 @@ Scribe uses a strict file whitelist and a deterministic build pipeline.
|
|
|
207
232
|
}
|
|
208
233
|
```
|
|
209
234
|
|
|
210
|
-
Prepack ensures
|
|
235
|
+
Prepack ensures dist/ is always built before:
|
|
211
236
|
|
|
212
237
|
- `npm publish`
|
|
213
238
|
- `npm publish --dry-run`
|
|
214
239
|
- `npm pack`
|
|
215
240
|
|
|
216
|
-
Files included in the package
|
|
241
|
+
Files included in the package:
|
|
217
242
|
|
|
218
243
|
```json
|
|
219
244
|
{
|
|
@@ -221,29 +246,21 @@ Files included in the package
|
|
|
221
246
|
}
|
|
222
247
|
```
|
|
223
248
|
|
|
224
|
-
|
|
249
|
+
Guarantees only compiled output and documentation are published.
|
|
225
250
|
|
|
226
251
|
## Design rationale
|
|
227
252
|
|
|
228
|
-
- Directory grammar prevents cross
|
|
253
|
+
- Directory grammar prevents cross-environment and cross-tenant collisions.
|
|
229
254
|
- Semantic log levels allow operational tooling to treat incidents, changes, and HTTP traffic as distinct streams.
|
|
230
|
-
- Deep, case
|
|
231
|
-
- Pure, re
|
|
255
|
+
- Deep, case-insensitive redaction prevents credential leakage.
|
|
256
|
+
- Pure, re-entrant API ensures deterministic behavior across multi-tenant and multi-service deployments.
|
|
232
257
|
- Daily rotation keeps log files predictable for ingestion pipelines.
|
|
233
|
-
- Transport
|
|
258
|
+
- Transport-agnostic design supports file, console, cloud, and hybrid logging.
|
|
234
259
|
|
|
235
260
|
## License
|
|
236
261
|
|
|
237
262
|
Copyright [2026] [GlassOps Limited]
|
|
238
263
|
|
|
239
|
-
Licensed under the Apache License, Version 2.0 (
|
|
240
|
-
you may not use this file except in compliance with the License.
|
|
241
|
-
You may obtain a copy of the License at
|
|
242
|
-
|
|
243
|
-
<http://www.apache.org/licenses/LICENSE-2.0>
|
|
264
|
+
Licensed under the Apache License, Version 2.0 (["License"](LICENSE)).
|
|
244
265
|
|
|
245
|
-
Unless required by applicable law or agreed to in writing, software
|
|
246
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
247
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
248
|
-
See the License for the specific language governing permissions and
|
|
249
|
-
limitations under the License.
|
|
266
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
/**
|
|
14
14
|
* Public authoring contracts for configuring logger scope and behavior.
|
|
15
15
|
*/
|
|
16
|
-
export type { LoggerScope, LoggerOptions, LogLevel } from './types.js';
|
|
16
|
+
export type { LoggerScope, LoggerOptions, LogLevel, ScribeLogger } from './types.js';
|
|
17
17
|
/**
|
|
18
18
|
* Pure, deterministic entrypoints for initializing the log directory and
|
|
19
19
|
* constructing a scoped logger instance. These are the primary runtime APIs.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;gFAWgF;AAKhF;;GAEG;AACH,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;gFAWgF;AAKhF;;GAEG;AACH,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKrF;;;GAGG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKlD;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -6,7 +6,22 @@
|
|
|
6
6
|
/* --------------------------------------------------------------------------
|
|
7
7
|
|* NPM Dependencies
|
|
8
8
|
\* -------------------------------------------------------------------------- */
|
|
9
|
-
import type
|
|
9
|
+
import type { Logger } from 'winston';
|
|
10
|
+
import type Transport from 'winston-transport';
|
|
11
|
+
export interface ScribeLogger {
|
|
12
|
+
logError: (error: string | Error, context?: Record<string, unknown>) => void;
|
|
13
|
+
logWarn: (message: string, context?: Record<string, unknown>) => void;
|
|
14
|
+
logInfo: (message: string, context?: Record<string, unknown>) => void;
|
|
15
|
+
logDebug: (message: string, context?: Record<string, unknown>) => void;
|
|
16
|
+
logIncident: (message: string, context?: Record<string, unknown>) => void;
|
|
17
|
+
logChange: (message: string, context?: Record<string, unknown>) => void;
|
|
18
|
+
createLoggerStream: () => {
|
|
19
|
+
write: (message: string) => void;
|
|
20
|
+
};
|
|
21
|
+
scope: (partial: Partial<LoggerScope>) => Promise<void>;
|
|
22
|
+
close: () => Promise<void>;
|
|
23
|
+
logger: Logger;
|
|
24
|
+
}
|
|
10
25
|
/**
|
|
11
26
|
* Describes the identity of the log stream. Every log entry is tagged with
|
|
12
27
|
* these fields to ensure deterministic partitioning across tenants,
|
|
@@ -62,5 +77,5 @@ export interface LoggerOptions {
|
|
|
62
77
|
* Supported semantic log levels. These map directly to Scribe's custom
|
|
63
78
|
* level hierarchy and determine which transport receives each log entry.
|
|
64
79
|
*/
|
|
65
|
-
export type LogLevel =
|
|
80
|
+
export type LogLevel = 'critical' | 'error' | 'warn' | 'info' | 'http' | 'change' | 'debug';
|
|
66
81
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;gFAOgF;AAChF,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAK/C;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACnC;AAKD;;;GAGG;AACH,MAAM,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;gFAOgF;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAK/C,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC7E,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACtE,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACtE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACvE,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC1E,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACxE,kBAAkB,EAAE,MAAM;QAAE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;IAC/D,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAClB;AAKD;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACnC;AAKD;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC"}
|