loggily 0.6.0 → 0.6.2
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 +70 -90
- package/dist/index.d.mts +333 -4
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +733 -3
- package/dist/index.mjs.map +1 -0
- package/package.json +22 -39
- package/dist/context.d.mts +0 -91
- package/dist/context.d.mts.map +0 -1
- package/dist/context.mjs +0 -145
- package/dist/context.mjs.map +0 -1
- package/dist/core-7D7sstHl.d.mts +0 -239
- package/dist/core-7D7sstHl.d.mts.map +0 -1
- package/dist/core-BDFU50FQ.mjs +0 -570
- package/dist/core-BDFU50FQ.mjs.map +0 -1
- package/dist/file-writer-BuQGFGRs.d.mts +0 -46
- package/dist/file-writer-BuQGFGRs.d.mts.map +0 -1
- package/dist/file-writer.d.mts +0 -2
- package/dist/file-writer.mjs +0 -75
- package/dist/file-writer.mjs.map +0 -1
- package/dist/metrics.d.mts +0 -48
- package/dist/metrics.d.mts.map +0 -1
- package/dist/metrics.mjs +0 -130
- package/dist/metrics.mjs.map +0 -1
- package/dist/tracing-2kv3HZ07.d.mts +0 -65
- package/dist/tracing-2kv3HZ07.d.mts.map +0 -1
- package/dist/tracing.d.mts +0 -2
- package/dist/tracing.mjs +0 -96
- package/dist/tracing.mjs.map +0 -1
- package/dist/worker.d.mts +0 -173
- package/dist/worker.d.mts.map +0 -1
- package/dist/worker.mjs +0 -468
- package/dist/worker.mjs.map +0 -1
- package/src/colors.ts +0 -27
- package/src/context.ts +0 -170
- package/src/core.ts +0 -880
- package/src/file-writer.ts +0 -110
- package/src/index.browser.ts +0 -72
- package/src/index.ts +0 -18
- package/src/metrics.ts +0 -201
- package/src/tracing.ts +0 -150
- package/src/worker.ts +0 -674
package/README.md
CHANGED
|
@@ -2,42 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
**Clarity without the clutter.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Debugs, logs, and spans — one API.
|
|
6
6
|
|
|
7
7
|
[](https://github.com/beorn/loggily/actions/workflows/test.yml)
|
|
8
|
-
[](https://www.npmjs.com/package/loggily)
|
|
9
|
+
[](https://bundlephobia.com/package/loggily)
|
|
9
10
|
[](LICENSE)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Most apps end up with three logging tools: `debug` for local troubleshooting, a JSON logger like Pino for production, and ad-hoc timers or a tracing SDK for performance. Three APIs, three configs, three output formats.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm install loggily
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
| Requirement | Version |
|
|
20
|
-
| ------------- | ------------------------------------------------- |
|
|
21
|
-
| Node.js | >= 23.6 |
|
|
22
|
-
| Bun | 1.0+ |
|
|
23
|
-
| TypeScript | 5.2+ (for `using`; `.end()` works on any version) |
|
|
24
|
-
| Module format | ESM-only |
|
|
25
|
-
| Browser | Supported via conditional export |
|
|
26
|
-
|
|
27
|
-
## Quick Start
|
|
14
|
+
Loggily replaces all three with one namespace tree and one output pipeline. Pure TypeScript, zero dependencies, ~3 KB.
|
|
28
15
|
|
|
29
16
|
```typescript
|
|
30
17
|
import { createLogger } from "loggily"
|
|
31
18
|
|
|
32
19
|
const log = createLogger("myapp")
|
|
33
20
|
|
|
34
|
-
// ?. skips the entire call — including argument evaluation — when the level is disabled
|
|
35
21
|
log.info?.("server started", { port: 3000 })
|
|
36
22
|
log.debug?.("cache hit", { key: "user:42" })
|
|
37
23
|
log.error?.(new Error("connection lost"))
|
|
38
24
|
```
|
|
39
25
|
|
|
40
|
-
|
|
26
|
+
Readable, colorized output in development:
|
|
41
27
|
|
|
42
28
|
```
|
|
43
29
|
14:32:15 INFO myapp server started {port: 3000}
|
|
@@ -45,75 +31,95 @@ Output in development (colorized with timestamps and clickable source lines):
|
|
|
45
31
|
14:32:15 ERROR myapp connection lost
|
|
46
32
|
```
|
|
47
33
|
|
|
48
|
-
Set `NODE_ENV=production`
|
|
34
|
+
Set `NODE_ENV=production` and the same calls emit structured JSON:
|
|
49
35
|
|
|
50
36
|
```json
|
|
51
37
|
{ "time": "2024-01-15T14:32:15.123Z", "level": "info", "name": "myapp", "msg": "server started", "port": 3000 }
|
|
52
38
|
```
|
|
53
39
|
|
|
54
|
-
|
|
40
|
+
## Why the `?.`
|
|
55
41
|
|
|
56
|
-
|
|
42
|
+
Disabled logs should not build strings, serialize objects, or compute snapshots just to throw them away.
|
|
57
43
|
|
|
58
|
-
|
|
59
|
-
// With `using` (TS 5.2+, Bun 1.0+, Node 22+)
|
|
60
|
-
{
|
|
61
|
-
using span = log.span("db:query", { table: "users" })
|
|
62
|
-
const users = await db.query("SELECT * FROM users")
|
|
63
|
-
span.spanData.count = users.length
|
|
64
|
-
}
|
|
65
|
-
// Output: SPAN myapp:db:query (45ms) {count: 100, table: "users"}
|
|
44
|
+
With most loggers, this work still happens:
|
|
66
45
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const users = await db.query("SELECT * FROM users")
|
|
71
|
-
span.spanData.count = users.length
|
|
72
|
-
} finally {
|
|
73
|
-
span.end()
|
|
74
|
-
}
|
|
46
|
+
```typescript
|
|
47
|
+
log.debug(`state: ${JSON.stringify(computeExpensiveState())}`)
|
|
48
|
+
// computeExpensiveState() runs even when debug is off
|
|
75
49
|
```
|
|
76
50
|
|
|
77
|
-
|
|
51
|
+
With Loggily, optional chaining short-circuits the entire call:
|
|
78
52
|
|
|
79
|
-
|
|
53
|
+
```typescript
|
|
54
|
+
log.debug?.(`state: ${JSON.stringify(computeExpensiveState())}`)
|
|
55
|
+
// nothing runs when debug is off — not the function, not the stringify, not the template
|
|
56
|
+
```
|
|
80
57
|
|
|
81
|
-
|
|
58
|
+
In benchmarks with expensive disabled log arguments, this is [~22x faster](https://beorn.codes/loggily/guide/benchmarks) than a conventional noop logger.
|
|
82
59
|
|
|
83
|
-
|
|
60
|
+
## Install
|
|
84
61
|
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
log.debug(`state: ${JSON.stringify(computeExpensiveState())}`)
|
|
62
|
+
```bash
|
|
63
|
+
npm install loggily
|
|
88
64
|
```
|
|
89
65
|
|
|
90
|
-
|
|
66
|
+
| Requirement | Version |
|
|
67
|
+
|---|---|
|
|
68
|
+
| Node.js | >= 23.6 |
|
|
69
|
+
| Bun | 1.0+ |
|
|
70
|
+
| TypeScript | 5.2+ for `using`; `.end()` works on any version |
|
|
71
|
+
| Module format | ESM-only |
|
|
72
|
+
| Browser | Supported via conditional export |
|
|
73
|
+
|
|
74
|
+
Loggily uses `Symbol.dispose` (TC39 Explicit Resource Management) for span cleanup, which requires a modern runtime.
|
|
75
|
+
|
|
76
|
+
## Features
|
|
77
|
+
|
|
78
|
+
- **Namespace hierarchy** — organize logs with `:` separators. `DEBUG=myapp:db` shows only database output, just like the `debug` package.
|
|
79
|
+
- **Lightweight spans** — time any operation with `using span = log.span("name")`. Automatic duration, parent-child tracking, and trace IDs.
|
|
80
|
+
- **Dev & production** — colorized console in development, structured JSON in production. Same code, zero config.
|
|
81
|
+
- **Child context** — `log.child({ requestId })` adds structured fields to every message in the chain.
|
|
82
|
+
- **Automatic async context** — enable `AsyncLocalStorage`-based propagation and every log in a request's async chain inherits trace/span IDs without passing loggers around.
|
|
83
|
+
- **Lazy messages** — `log.debug?.(() => expensiveString())` skips the function entirely when disabled.
|
|
84
|
+
- **File writer** — `addWriter()` + `createFileWriter()` for buffered file output.
|
|
85
|
+
- **Worker threads** — forward logs from workers to the main thread with full type safety.
|
|
86
|
+
|
|
87
|
+
### Spans
|
|
91
88
|
|
|
92
89
|
```typescript
|
|
93
|
-
|
|
94
|
-
log.
|
|
90
|
+
{
|
|
91
|
+
using span = log.span("db:query", { table: "users" })
|
|
92
|
+
const users = await db.query("SELECT * FROM users")
|
|
93
|
+
span.spanData.count = users.length
|
|
94
|
+
}
|
|
95
|
+
// SPAN myapp:db:query (45ms) {count: 100, table: "users"}
|
|
96
|
+
|
|
97
|
+
// Without `using` — call .end() manually
|
|
98
|
+
const span = log.span("db:query")
|
|
99
|
+
try { /* ... */ } finally { span.end() }
|
|
95
100
|
```
|
|
96
101
|
|
|
97
|
-
|
|
102
|
+
### Common configuration
|
|
98
103
|
|
|
99
|
-
|
|
104
|
+
| Variable | Example | Effect |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `DEBUG` | `myapp:db,-myapp:sql` | Namespace filter (same syntax as the `debug` package) |
|
|
107
|
+
| `LOG_LEVEL` | `debug`, `info`, `warn` | Minimum output level |
|
|
108
|
+
| `LOG_FORMAT` | `console`, `json` | Override output format |
|
|
109
|
+
| `TRACE` | `1` or namespace prefixes | Enable span output |
|
|
100
110
|
|
|
101
|
-
|
|
111
|
+
See the [full environment variable reference](https://beorn.codes/loggily/api/configuration).
|
|
102
112
|
|
|
103
|
-
|
|
104
|
-
- **Lightweight spans and trace IDs** — time any operation with `using span = log.span("name")`. Automatic duration, parent-child tracking, and trace IDs. For full OpenTelemetry interoperability with exporters and propagation, use OpenTelemetry.
|
|
105
|
-
- **Lazy messages** — `log.debug?.(() => expensiveString())` skips the function entirely when disabled.
|
|
106
|
-
- **Child context** — `log.child({ requestId })` adds structured fields to every message in the chain.
|
|
107
|
-
- **Dev & production** — colorized console with timestamps, level colors, and clickable source lines in development. Structured JSON in production. Switches automatically via `NODE_ENV` — same code, zero config.
|
|
108
|
-
- **File writer** — `addWriter()` + `createFileWriter()` for buffered file output with auto-flush.
|
|
109
|
-
- **Worker threads** — forward logs from workers to the main thread with full type safety (`loggily/worker`).
|
|
110
|
-
- **debug-compatible namespace filtering** — reads `DEBUG=myapp:*` just like the debug package. Easy migration from debug — see the [migration guide](https://beorn.codes/loggily/guide/migration-from-debug).
|
|
113
|
+
## Why this exists
|
|
111
114
|
|
|
112
|
-
|
|
115
|
+
Loggily was built while developing a terminal UI where disabled debug logs inside the render loop were eating frame time. No existing logger solved the "disabled calls should cost nothing" problem at the language level, so `?.` became the foundation.
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
+
> **Status:** Early release (0.x). The core API is stable, but details may evolve before 1.0.
|
|
118
|
+
|
|
119
|
+
## When not to use Loggily
|
|
120
|
+
|
|
121
|
+
- **You need the absolute fastest structured logger with a transport ecosystem.** Use [Pino](https://getpino.io/) for worker-thread transports, custom serializers, and log rotation.
|
|
122
|
+
- **You need distributed tracing with vendor exporters and auto-instrumentation.** Use [OpenTelemetry](https://opentelemetry.io/).
|
|
117
123
|
|
|
118
124
|
## Documentation
|
|
119
125
|
|
|
@@ -122,32 +128,6 @@ For trivial arguments the difference is negligible. But for real-world logging
|
|
|
122
128
|
- [Comparison](https://beorn.codes/loggily/guide/comparison) — vs Pino, Winston, Bunyan, debug
|
|
123
129
|
- [Migration from debug](https://beorn.codes/loggily/guide/migration-from-debug) — step-by-step migration guide
|
|
124
130
|
|
|
125
|
-
## Environment Variables
|
|
126
|
-
|
|
127
|
-
| Variable | Values | Effect |
|
|
128
|
-
| -------------- | --------------------------------------- | --------------------------------------- |
|
|
129
|
-
| `LOG_LEVEL` | trace, debug, info, warn, error, silent | Minimum output level |
|
|
130
|
-
| `LOG_FORMAT` | console, json | Output format |
|
|
131
|
-
| `DEBUG` | `*`, namespace prefixes, `-prefix` | Namespace filter (like `debug` package) |
|
|
132
|
-
| `TRACE` | `1`, `true`, or namespace prefixes | Enable span output |
|
|
133
|
-
| `TRACE_FORMAT` | json | Force JSON for spans |
|
|
134
|
-
| `NODE_ENV` | production | Auto-enable JSON format |
|
|
135
|
-
|
|
136
|
-
## API
|
|
137
|
-
|
|
138
|
-
| Function | Description |
|
|
139
|
-
| ---------------------------------------------------------------------- | ------------------------------------------------------------- |
|
|
140
|
-
| `createLogger(name, props?)` | Create a logger (disabled levels return `undefined` for `?.`) |
|
|
141
|
-
| `.trace?.()` / `.debug?.()` / `.info?.()` / `.warn?.()` / `.error?.()` | Log at level (message + optional data) |
|
|
142
|
-
| `.logger(namespace)` | Create child logger with extended namespace |
|
|
143
|
-
| `.span(namespace, props?)` | Create timed span (implements `Disposable`) |
|
|
144
|
-
| `.child(context)` | Create child with structured context fields |
|
|
145
|
-
| `addWriter(fn)` / `createFileWriter(path)` | Custom output writers |
|
|
146
|
-
| `setLogLevel()` / `setLogFormat()` / `enableSpans()` | Runtime configuration |
|
|
147
|
-
| `createWorkerLogger()` / `createWorkerLogHandler()` | Worker thread support (`loggily/worker`) |
|
|
148
|
-
|
|
149
|
-
See the [full API reference](https://beorn.codes/loggily/api/) for all functions and options.
|
|
150
|
-
|
|
151
131
|
## License
|
|
152
132
|
|
|
153
133
|
[MIT](LICENSE)
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,333 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
//#region src/core.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* loggily - Structured logging with spans
|
|
4
|
+
*
|
|
5
|
+
* Logger-first architecture: Span = Logger + Duration
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const log = createLogger('myapp')
|
|
9
|
+
*
|
|
10
|
+
* // Simple logging
|
|
11
|
+
* log.info('starting')
|
|
12
|
+
*
|
|
13
|
+
* // Lazy messages (function not called when level is disabled)
|
|
14
|
+
* log.debug?.(() => `expensive: ${computeState()}`)
|
|
15
|
+
*
|
|
16
|
+
* // Child loggers with context fields
|
|
17
|
+
* const reqLog = log.child({ requestId: 'abc' })
|
|
18
|
+
* reqLog.info('handling request') // includes requestId in every message
|
|
19
|
+
*
|
|
20
|
+
* // With timing (span)
|
|
21
|
+
* {
|
|
22
|
+
* using task = log.span('import', { file: 'data.csv' })
|
|
23
|
+
* task.info('importing')
|
|
24
|
+
* task.spanData.count = 42 // Set span attributes
|
|
25
|
+
* // Auto-disposal on block exit → SPAN myapp:import (15ms)
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
/** Data passed to span recorders on disposal */
|
|
29
|
+
interface SpanRecord {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly durationMs: number;
|
|
32
|
+
}
|
|
33
|
+
/** Interface for span duration recording — implemented by createMetricsCollector() in metrics.ts */
|
|
34
|
+
interface SpanRecorder {
|
|
35
|
+
recordSpan(data: SpanRecord): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Ambient span recorder — auto-records when TRACE is active.
|
|
39
|
+
* Set by metrics.ts on import; can be replaced for testing.
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
declare let _ambientRecorder: SpanRecorder | null;
|
|
43
|
+
declare function _setAmbientRecorder(recorder: SpanRecorder | null): void;
|
|
44
|
+
/** Log levels that produce output */
|
|
45
|
+
type OutputLogLevel = "trace" | "debug" | "info" | "warn" | "error";
|
|
46
|
+
/** All log levels including silent (for filtering) */
|
|
47
|
+
type LogLevel = OutputLogLevel | "silent";
|
|
48
|
+
/** Message can be a string or a lazy function that returns a string */
|
|
49
|
+
type LazyMessage = string | (() => string);
|
|
50
|
+
/** Span props can be an object or a lazy function (skipped entirely via ?. when tracing is off) */
|
|
51
|
+
type LazyProps = Record<string, unknown> | (() => Record<string, unknown>);
|
|
52
|
+
/** Span data accessible via logger.spanData */
|
|
53
|
+
interface SpanData {
|
|
54
|
+
readonly id: string;
|
|
55
|
+
readonly traceId: string;
|
|
56
|
+
readonly parentId: string | null;
|
|
57
|
+
readonly startTime: number;
|
|
58
|
+
readonly endTime: number | null;
|
|
59
|
+
readonly duration: number | null;
|
|
60
|
+
/** Custom attributes - set via direct property assignment */
|
|
61
|
+
[key: string]: unknown;
|
|
62
|
+
}
|
|
63
|
+
/** Logger interface */
|
|
64
|
+
interface Logger {
|
|
65
|
+
/** Logger namespace (e.g., 'myapp:import') */
|
|
66
|
+
readonly name: string;
|
|
67
|
+
/** Props inherited from parent + own props */
|
|
68
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
69
|
+
/** Span data (non-null for span loggers, null for regular loggers) */
|
|
70
|
+
readonly spanData: SpanData | null;
|
|
71
|
+
trace(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
72
|
+
debug(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
73
|
+
info(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
74
|
+
warn(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
75
|
+
error(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
76
|
+
/** Error overload - extracts message, stack, code from Error */
|
|
77
|
+
error(error: Error, data?: Record<string, unknown>): void;
|
|
78
|
+
/** Create child logger (extends namespace, inherits props) */
|
|
79
|
+
logger(namespace?: string, props?: Record<string, unknown>): Logger;
|
|
80
|
+
/** Create child span (extends namespace, inherits props, adds timing). Props can be lazy. */
|
|
81
|
+
span(namespace?: string, props?: LazyProps): SpanLogger;
|
|
82
|
+
/** Create child logger with context fields merged into every message */
|
|
83
|
+
child(context: Record<string, unknown>): Logger;
|
|
84
|
+
/** @deprecated Use .logger() instead for namespace-based children */
|
|
85
|
+
child(context: string): Logger;
|
|
86
|
+
/** End span manually (alternative to using keyword) */
|
|
87
|
+
end(): void;
|
|
88
|
+
}
|
|
89
|
+
/** Span logger - Logger with active span (spanData is non-null, implements Disposable) */
|
|
90
|
+
interface SpanLogger extends Logger, Disposable {
|
|
91
|
+
readonly spanData: SpanData & {
|
|
92
|
+
/** Mutable attributes - set directly */[key: string]: unknown;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
type LogWriter = (formatted: string, level: string) => void;
|
|
96
|
+
/** Add a writer that receives all formatted log output. Returns unsubscribe. */
|
|
97
|
+
declare function addWriter(writer: LogWriter): () => void;
|
|
98
|
+
/** Suppress console output from the logger (writers still receive output). */
|
|
99
|
+
declare function setSuppressConsole(value: boolean): void;
|
|
100
|
+
/** Output mode for writeLog */
|
|
101
|
+
type OutputMode = "console" | "stderr" | "writers-only";
|
|
102
|
+
/** Set output mode for log messages (not spans — spans always use stderr). */
|
|
103
|
+
declare function setOutputMode(mode: OutputMode): void;
|
|
104
|
+
/** Get current output mode */
|
|
105
|
+
declare function getOutputMode(): OutputMode;
|
|
106
|
+
/** Set minimum log level */
|
|
107
|
+
declare function setLogLevel(level: LogLevel): void;
|
|
108
|
+
/** Get current log level */
|
|
109
|
+
declare function getLogLevel(): LogLevel;
|
|
110
|
+
/** Enable span output */
|
|
111
|
+
declare function enableSpans(): void;
|
|
112
|
+
/** Disable span output */
|
|
113
|
+
declare function disableSpans(): void;
|
|
114
|
+
/** Check if spans are enabled */
|
|
115
|
+
declare function spansAreEnabled(): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Set trace filter for namespace-based span output control.
|
|
118
|
+
* Only spans matching these namespace prefixes will be output.
|
|
119
|
+
* @param namespaces - Array of namespace prefixes, or null to disable filtering
|
|
120
|
+
*/
|
|
121
|
+
declare function setTraceFilter(namespaces: string[] | null): void;
|
|
122
|
+
/** Get current trace filter (null means no filtering) */
|
|
123
|
+
declare function getTraceFilter(): string[] | null;
|
|
124
|
+
/**
|
|
125
|
+
* Set debug namespace filter (like the `debug` npm package).
|
|
126
|
+
* When set, only loggers matching these namespace prefixes produce output.
|
|
127
|
+
* Supports negative patterns with `-` prefix (e.g., ["-km:noisy"]).
|
|
128
|
+
* Also ensures log level is at least `debug`.
|
|
129
|
+
* @param namespaces - Array of namespace prefixes (prefix with `-` to exclude), or null to disable
|
|
130
|
+
*/
|
|
131
|
+
declare function setDebugFilter(namespaces: string[] | null): void;
|
|
132
|
+
/** Get current debug namespace filter (null means no filtering) */
|
|
133
|
+
declare function getDebugFilter(): string[] | null;
|
|
134
|
+
/** Output format: human-readable console or structured JSON */
|
|
135
|
+
type LogFormat = "console" | "json";
|
|
136
|
+
/** Set log output format */
|
|
137
|
+
declare function setLogFormat(format: LogFormat): void;
|
|
138
|
+
/** Get current log output format */
|
|
139
|
+
declare function getLogFormat(): LogFormat;
|
|
140
|
+
declare function resetIds(): void;
|
|
141
|
+
/**
|
|
142
|
+
* Register context propagation hooks (called by context.ts).
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
145
|
+
declare function _setContextHooks(hooks: {
|
|
146
|
+
getContextTags: () => Record<string, string>;
|
|
147
|
+
getContextParent: () => {
|
|
148
|
+
spanId: string;
|
|
149
|
+
traceId: string;
|
|
150
|
+
} | null;
|
|
151
|
+
enterContext: (spanId: string, traceId: string, parentId: string | null) => void;
|
|
152
|
+
exitContext: (spanId: string) => void;
|
|
153
|
+
}): void;
|
|
154
|
+
/**
|
|
155
|
+
* Clear context propagation hooks (called by disableContextPropagation).
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
declare function _clearContextHooks(): void;
|
|
159
|
+
declare function writeSpan(namespace: string, duration: number, attrs: Record<string, unknown>): void;
|
|
160
|
+
interface SpanDataFields {
|
|
161
|
+
id: string;
|
|
162
|
+
traceId: string;
|
|
163
|
+
parentId: string | null;
|
|
164
|
+
startTime: number;
|
|
165
|
+
endTime: number | null;
|
|
166
|
+
duration: number | null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Create a proxy that exposes span metadata as readonly and custom attributes as writable.
|
|
170
|
+
* Shared between core logger spans and worker logger spans.
|
|
171
|
+
*/
|
|
172
|
+
declare function createSpanDataProxy(getFields: () => SpanDataFields, attrs: Record<string, unknown>): SpanData;
|
|
173
|
+
/** Enable span collection for analysis */
|
|
174
|
+
declare function startCollecting(): void;
|
|
175
|
+
/** Stop collecting and return collected spans */
|
|
176
|
+
declare function stopCollecting(): SpanData[];
|
|
177
|
+
/** Get collected spans */
|
|
178
|
+
declare function getCollectedSpans(): SpanData[];
|
|
179
|
+
/** Clear collected spans */
|
|
180
|
+
declare function clearCollectedSpans(): void;
|
|
181
|
+
/**
|
|
182
|
+
* Logger with optional methods — returns undefined for disabled levels.
|
|
183
|
+
* Use with optional chaining: `log.debug?.("msg")` for zero-overhead when disabled.
|
|
184
|
+
*
|
|
185
|
+
* Defined as an explicit interface (not Omit<Logger,...>) so that
|
|
186
|
+
* oxlint's type-aware mode can resolve it without advanced type inference.
|
|
187
|
+
*/
|
|
188
|
+
interface ConditionalLogger {
|
|
189
|
+
readonly name: string;
|
|
190
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
191
|
+
readonly spanData: SpanData | null;
|
|
192
|
+
trace?: (message: LazyMessage, data?: Record<string, unknown>) => void;
|
|
193
|
+
debug?: (message: LazyMessage, data?: Record<string, unknown>) => void;
|
|
194
|
+
info?: (message: LazyMessage, data?: Record<string, unknown>) => void;
|
|
195
|
+
warn?: (message: LazyMessage, data?: Record<string, unknown>) => void;
|
|
196
|
+
error?: {
|
|
197
|
+
(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
198
|
+
(error: Error, data?: Record<string, unknown>): void;
|
|
199
|
+
};
|
|
200
|
+
logger(namespace?: string, props?: Record<string, unknown>): Logger;
|
|
201
|
+
span(namespace?: string, props?: LazyProps): SpanLogger;
|
|
202
|
+
child(context: Record<string, unknown>): Logger;
|
|
203
|
+
child(context: string): Logger;
|
|
204
|
+
end(): void;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Create a logger for a component.
|
|
208
|
+
* Returns undefined for disabled levels - use with optional chaining for zero overhead.
|
|
209
|
+
*
|
|
210
|
+
* Log levels (most → least verbose): trace < debug < info < warn < error < silent
|
|
211
|
+
* Default level: info (trace and debug disabled)
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* const log = createLogger('myapp')
|
|
215
|
+
*
|
|
216
|
+
* // All methods support ?. for zero-overhead when disabled
|
|
217
|
+
* log.trace?.(`very verbose: ${expensiveDebug()}`) // Skipped at info level
|
|
218
|
+
* log.debug?.(`debug: ${getState()}`) // Skipped at info level
|
|
219
|
+
* log.info?.('starting') // Enabled at info level
|
|
220
|
+
* log.warn?.('deprecated') // Enabled at info level
|
|
221
|
+
* log.error?.('failed') // Enabled at info level
|
|
222
|
+
*
|
|
223
|
+
* // With -q flag or LOG_LEVEL=warn:
|
|
224
|
+
* log.info?.('starting') // Now skipped - info < warn
|
|
225
|
+
*
|
|
226
|
+
* // With initial props
|
|
227
|
+
* const log = createLogger('myapp', { version: '1.0' })
|
|
228
|
+
*
|
|
229
|
+
* // Create spans
|
|
230
|
+
* {
|
|
231
|
+
* using task = log.span('import', { file: 'data.csv' })
|
|
232
|
+
* task.info?.('importing')
|
|
233
|
+
* task.spanData.count = 42
|
|
234
|
+
* }
|
|
235
|
+
*/
|
|
236
|
+
declare function createLogger(name: string, props?: Record<string, unknown>): ConditionalLogger;
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region src/file-writer.d.ts
|
|
239
|
+
/**
|
|
240
|
+
* File writer for loggily — Node.js/Bun only.
|
|
241
|
+
*
|
|
242
|
+
* Separated from core logger to allow tree-shaking in browser bundles.
|
|
243
|
+
* Uses dynamic import("node:fs") to avoid static dependency on Node APIs.
|
|
244
|
+
*/
|
|
245
|
+
/** Options for creating an async buffered file writer */
|
|
246
|
+
interface FileWriterOptions {
|
|
247
|
+
/** Buffer size threshold in bytes before flushing (default: 4096) */
|
|
248
|
+
bufferSize?: number;
|
|
249
|
+
/** Flush interval in milliseconds (default: 100) */
|
|
250
|
+
flushInterval?: number;
|
|
251
|
+
}
|
|
252
|
+
/** An async buffered file writer with automatic flushing */
|
|
253
|
+
interface FileWriter {
|
|
254
|
+
/** Write a line to the buffer (appends newline) */
|
|
255
|
+
write(line: string): void;
|
|
256
|
+
/** Flush the buffer immediately */
|
|
257
|
+
flush(): void;
|
|
258
|
+
/** Close the writer and flush remaining buffer */
|
|
259
|
+
close(): void;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Create an async buffered file writer for log output.
|
|
263
|
+
* Buffers writes and flushes on size threshold or interval.
|
|
264
|
+
* Registers a process.on('exit') handler to flush remaining buffer.
|
|
265
|
+
*
|
|
266
|
+
* **Node.js/Bun only** — not available in browser environments.
|
|
267
|
+
*
|
|
268
|
+
* @param filePath - Path to the log file (opened in append mode)
|
|
269
|
+
* @param options - Buffer size and flush interval configuration
|
|
270
|
+
* @returns FileWriter with write, flush, and close methods
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* const writer = createFileWriter('/tmp/app.log')
|
|
274
|
+
* const unsubscribe = addWriter((formatted) => writer.write(formatted))
|
|
275
|
+
*
|
|
276
|
+
* // On shutdown:
|
|
277
|
+
* unsubscribe()
|
|
278
|
+
* writer.close()
|
|
279
|
+
*/
|
|
280
|
+
declare function createFileWriter(filePath: string, options?: FileWriterOptions): FileWriter;
|
|
281
|
+
//#endregion
|
|
282
|
+
//#region src/tracing.d.ts
|
|
283
|
+
/** Supported ID formats */
|
|
284
|
+
type IdFormat = "simple" | "w3c";
|
|
285
|
+
/**
|
|
286
|
+
* Set the ID format for new spans and traces.
|
|
287
|
+
* - "simple": sp_1, sp_2, tr_1, tr_2 (default, lightweight)
|
|
288
|
+
* - "w3c": 32-char hex trace ID, 16-char hex span ID (W3C Trace Context compatible)
|
|
289
|
+
*/
|
|
290
|
+
declare function setIdFormat(format: IdFormat): void;
|
|
291
|
+
/** Get the current ID format */
|
|
292
|
+
declare function getIdFormat(): IdFormat;
|
|
293
|
+
/** Options for traceparent header formatting */
|
|
294
|
+
interface TraceparentOptions {
|
|
295
|
+
/** Whether this span is sampled. Defaults to true for backwards compatibility. */
|
|
296
|
+
sampled?: boolean;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Format a W3C traceparent header from span data.
|
|
300
|
+
*
|
|
301
|
+
* Format: `{version}-{trace-id}-{span-id}-{trace-flags}`
|
|
302
|
+
* - version: "00" (current W3C spec version)
|
|
303
|
+
* - trace-id: 32 hex chars (128 bits)
|
|
304
|
+
* - span-id: 16 hex chars (64 bits)
|
|
305
|
+
* - trace-flags: "01" (sampled) or "00" (not sampled)
|
|
306
|
+
*
|
|
307
|
+
* Works with both simple and W3C ID formats. Simple IDs are zero-padded to spec length.
|
|
308
|
+
*
|
|
309
|
+
* @param spanData - Span data with id and traceId
|
|
310
|
+
* @param options - Optional settings (sampled flag). Defaults to sampled=true.
|
|
311
|
+
* @returns W3C traceparent header string
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```typescript
|
|
315
|
+
* const span = log.span("http-request")
|
|
316
|
+
* const header = traceparent(span.spanData)
|
|
317
|
+
* // → "00-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6-1a2b3c4d5e6f7a8b-01"
|
|
318
|
+
* fetch(url, { headers: { traceparent: header } })
|
|
319
|
+
* ```
|
|
320
|
+
*/
|
|
321
|
+
declare function traceparent(spanData: SpanData, options?: TraceparentOptions): string;
|
|
322
|
+
/**
|
|
323
|
+
* Set the head-based sampling rate for new traces.
|
|
324
|
+
* Applied at trace creation — all spans within a sampled trace are kept.
|
|
325
|
+
*
|
|
326
|
+
* @param rate - Sampling rate from 0.0 (sample nothing) to 1.0 (sample everything, default)
|
|
327
|
+
*/
|
|
328
|
+
declare function setSampleRate(rate: number): void;
|
|
329
|
+
/** Get the current sampling rate */
|
|
330
|
+
declare function getSampleRate(): number;
|
|
331
|
+
//#endregion
|
|
332
|
+
export { ConditionalLogger, type FileWriter, type FileWriterOptions, type IdFormat, LazyMessage, LazyProps, LogFormat, LogLevel, Logger, OutputLogLevel, OutputMode, SpanData, SpanLogger, SpanRecord, SpanRecorder, type TraceparentOptions, _ambientRecorder, _clearContextHooks, _setAmbientRecorder, _setContextHooks, addWriter, clearCollectedSpans, createFileWriter, createLogger, createSpanDataProxy, disableSpans, enableSpans, getCollectedSpans, getDebugFilter, getIdFormat, getLogFormat, getLogLevel, getOutputMode, getSampleRate, getTraceFilter, resetIds, setDebugFilter, setIdFormat, setLogFormat, setLogLevel, setOutputMode, setSampleRate, setSuppressConsole, setTraceFilter, spansAreEnabled, startCollecting, stopCollecting, traceparent, writeSpan };
|
|
333
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/core.ts","../src/file-writer.ts","../src/tracing.ts"],"mappings":"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"}
|