@trace-stack/node 1.0.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/README.md +141 -0
- package/dist/batcher.d.ts +51 -0
- package/dist/batcher.d.ts.map +1 -0
- package/dist/batcher.js +127 -0
- package/dist/batcher.js.map +1 -0
- package/dist/client.d.ts +71 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +193 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/transport.d.ts +28 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +126 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# @trace-stack/node
|
|
2
|
+
|
|
3
|
+
Official Node.js SDK for [TraceStack](https://tracestack.dev) — a multi-tenant observability and log monitoring platform.
|
|
4
|
+
|
|
5
|
+
**Zero dependencies** · Batching · Exponential backoff retry · Graceful shutdown · TypeScript-first
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @trace-stack/node
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
> **Requires Node.js 18+** (uses native `fetch` API)
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { TraceStack } from "@trace-stack/node";
|
|
21
|
+
|
|
22
|
+
const logger = new TraceStack({
|
|
23
|
+
apiKey: "ts_live_xxxx",
|
|
24
|
+
serviceName: "payment-service",
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Log at different severity levels
|
|
28
|
+
logger.debug("Debugging payment flow", { step: "init" });
|
|
29
|
+
logger.info("User logged in", { userId: "u_123" });
|
|
30
|
+
logger.warn("High memory usage", { memoryMB: 450 });
|
|
31
|
+
logger.error("Payment failed", { orderId: "ord_456", amount: 999 });
|
|
32
|
+
logger.fatal("Database connection lost", { host: "db-primary" });
|
|
33
|
+
|
|
34
|
+
// Graceful shutdown (flushes remaining logs)
|
|
35
|
+
process.on("SIGTERM", async () => {
|
|
36
|
+
await logger.destroy();
|
|
37
|
+
process.exit(0);
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Configuration
|
|
42
|
+
|
|
43
|
+
| Option | Type | Default | Description |
|
|
44
|
+
|--------|------|---------|-------------|
|
|
45
|
+
| `apiKey` | `string` | **required** | Your TraceStack API key (must start with `ts_`) |
|
|
46
|
+
| `serviceName` | `string` | `"default"` | Identifies the sending service |
|
|
47
|
+
| `endpoint` | `string` | `"http://localhost:5000"` | Ingestion API URL |
|
|
48
|
+
| `batchSize` | `number` | `50` | Logs to buffer before auto-flush |
|
|
49
|
+
| `flushInterval` | `number` | `5000` | Auto-flush interval in ms |
|
|
50
|
+
| `maxRetries` | `number` | `3` | Max retry attempts on failure |
|
|
51
|
+
| `timeout` | `number` | `10000` | HTTP request timeout in ms |
|
|
52
|
+
| `debug` | `boolean` | `false` | Log SDK internals to console |
|
|
53
|
+
|
|
54
|
+
## Features
|
|
55
|
+
|
|
56
|
+
### Batching
|
|
57
|
+
|
|
58
|
+
Logs are buffered in memory and flushed in batches for efficiency. Flushes happen when:
|
|
59
|
+
- The buffer reaches `batchSize` (default: 50 logs)
|
|
60
|
+
- The `flushInterval` timer fires (default: every 5 seconds)
|
|
61
|
+
- You call `logger.flush()` manually
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// Manual flush before a critical operation
|
|
65
|
+
await logger.flush();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Retry with Exponential Backoff
|
|
69
|
+
|
|
70
|
+
Failed HTTP requests are retried up to `maxRetries` times with exponential backoff:
|
|
71
|
+
- Attempt 1: immediate
|
|
72
|
+
- Retry 1: wait 1s
|
|
73
|
+
- Retry 2: wait 2s
|
|
74
|
+
- Retry 3: wait 4s
|
|
75
|
+
|
|
76
|
+
Rate-limited requests (HTTP 429) respect the `Retry-After` header. Client errors (4xx) are **not** retried.
|
|
77
|
+
|
|
78
|
+
### Auto-Metadata
|
|
79
|
+
|
|
80
|
+
Every log entry automatically includes:
|
|
81
|
+
- `hostname` — machine hostname
|
|
82
|
+
- `pid` — Node.js process ID
|
|
83
|
+
- `nodeVersion` — Node.js runtime version
|
|
84
|
+
|
|
85
|
+
Custom metadata is merged with system metadata:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
logger.info("Order placed", { orderId: "123", amount: 49.99 });
|
|
89
|
+
// metadata = { hostname: "...", pid: 1234, nodeVersion: "v20.0.0", orderId: "123", amount: 49.99 }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Graceful Shutdown
|
|
93
|
+
|
|
94
|
+
The SDK registers `SIGTERM`, `SIGINT`, and `beforeExit` handlers to flush remaining logs before the process exits.
|
|
95
|
+
|
|
96
|
+
You can also manually trigger shutdown:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
await logger.destroy();
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
After `destroy()`, no new logs are accepted.
|
|
103
|
+
|
|
104
|
+
## API Reference
|
|
105
|
+
|
|
106
|
+
### `new TraceStack(config: TraceStackConfig)`
|
|
107
|
+
|
|
108
|
+
Creates a new TraceStack logger instance.
|
|
109
|
+
|
|
110
|
+
### `logger.debug(message, metadata?)`
|
|
111
|
+
### `logger.info(message, metadata?)`
|
|
112
|
+
### `logger.warn(message, metadata?)`
|
|
113
|
+
### `logger.error(message, metadata?)`
|
|
114
|
+
### `logger.fatal(message, metadata?)`
|
|
115
|
+
|
|
116
|
+
Log a message at the specified severity level.
|
|
117
|
+
|
|
118
|
+
- `message: string` — Log message (required)
|
|
119
|
+
- `metadata?: Record<string, unknown>` — Optional structured data
|
|
120
|
+
|
|
121
|
+
### `logger.flush(): Promise<void>`
|
|
122
|
+
|
|
123
|
+
Manually flush all buffered logs to the ingestion API.
|
|
124
|
+
|
|
125
|
+
### `logger.destroy(): Promise<void>`
|
|
126
|
+
|
|
127
|
+
Gracefully shut down the SDK. Flushes remaining logs and stops all timers.
|
|
128
|
+
|
|
129
|
+
## Log Levels
|
|
130
|
+
|
|
131
|
+
| Level | When to use |
|
|
132
|
+
|-------|-------------|
|
|
133
|
+
| `debug` | Detailed diagnostic information |
|
|
134
|
+
| `info` | General operational events |
|
|
135
|
+
| `warn` | Potential issues that aren't errors |
|
|
136
|
+
| `error` | Error events that might still allow the app to continue |
|
|
137
|
+
| `fatal` | Critical errors that require immediate attention |
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
MIT
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { LogEntry } from "./types";
|
|
2
|
+
import { Transport } from "./transport";
|
|
3
|
+
/**
|
|
4
|
+
* In-memory log buffer that accumulates entries and
|
|
5
|
+
* flushes them in batches via the Transport layer.
|
|
6
|
+
*
|
|
7
|
+
* Auto-flushes when:
|
|
8
|
+
* - Buffer reaches `batchSize` threshold
|
|
9
|
+
* - `flushInterval` timer fires
|
|
10
|
+
*
|
|
11
|
+
* Provides a mutex to prevent concurrent flushes.
|
|
12
|
+
*/
|
|
13
|
+
export declare class Batcher {
|
|
14
|
+
private buffer;
|
|
15
|
+
private flushTimer;
|
|
16
|
+
private flushing;
|
|
17
|
+
private destroyed;
|
|
18
|
+
private readonly batchSize;
|
|
19
|
+
private readonly flushInterval;
|
|
20
|
+
private readonly transport;
|
|
21
|
+
private readonly debug;
|
|
22
|
+
constructor(options: {
|
|
23
|
+
transport: Transport;
|
|
24
|
+
batchSize?: number;
|
|
25
|
+
flushInterval?: number;
|
|
26
|
+
debug?: boolean;
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Add a log entry to the buffer.
|
|
30
|
+
* Triggers an immediate flush if the buffer reaches batchSize.
|
|
31
|
+
*/
|
|
32
|
+
add(entry: LogEntry): void;
|
|
33
|
+
/**
|
|
34
|
+
* Flush all buffered logs to the transport.
|
|
35
|
+
* Thread-safe: only one flush can run at a time.
|
|
36
|
+
*/
|
|
37
|
+
flush(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Destroy the batcher: stop the timer and flush remaining logs.
|
|
40
|
+
* After destroy(), no new logs can be added.
|
|
41
|
+
*/
|
|
42
|
+
destroy(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Returns the current number of buffered logs.
|
|
45
|
+
*/
|
|
46
|
+
get size(): number;
|
|
47
|
+
private startTimer;
|
|
48
|
+
private stopTimer;
|
|
49
|
+
private log;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=batcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batcher.d.ts","sourceRoot":"","sources":["../src/batcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AASxC;;;;;;;;;GASG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;gBAEpB,OAAO,EAAE;QACnB,SAAS,EAAE,SAAS,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;IAUD;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAmB1B;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B5B;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAID,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,GAAG;CAKZ"}
|
package/dist/batcher.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Batcher = void 0;
|
|
4
|
+
// ─── Constants ───────────────────────────────────────────────
|
|
5
|
+
const DEFAULT_BATCH_SIZE = 50;
|
|
6
|
+
const DEFAULT_FLUSH_INTERVAL = 5000; // 5 seconds
|
|
7
|
+
// ─── Batcher ─────────────────────────────────────────────────
|
|
8
|
+
/**
|
|
9
|
+
* In-memory log buffer that accumulates entries and
|
|
10
|
+
* flushes them in batches via the Transport layer.
|
|
11
|
+
*
|
|
12
|
+
* Auto-flushes when:
|
|
13
|
+
* - Buffer reaches `batchSize` threshold
|
|
14
|
+
* - `flushInterval` timer fires
|
|
15
|
+
*
|
|
16
|
+
* Provides a mutex to prevent concurrent flushes.
|
|
17
|
+
*/
|
|
18
|
+
class Batcher {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.buffer = [];
|
|
21
|
+
this.flushTimer = null;
|
|
22
|
+
this.flushing = false;
|
|
23
|
+
this.destroyed = false;
|
|
24
|
+
this.transport = options.transport;
|
|
25
|
+
this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
26
|
+
this.flushInterval = options.flushInterval ?? DEFAULT_FLUSH_INTERVAL;
|
|
27
|
+
this.debug = options.debug ?? false;
|
|
28
|
+
// Start the periodic flush timer
|
|
29
|
+
this.startTimer();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Add a log entry to the buffer.
|
|
33
|
+
* Triggers an immediate flush if the buffer reaches batchSize.
|
|
34
|
+
*/
|
|
35
|
+
add(entry) {
|
|
36
|
+
if (this.destroyed) {
|
|
37
|
+
this.log("SDK destroyed — dropping log entry");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.buffer.push(entry);
|
|
41
|
+
this.log(`Buffered log [${entry.level}]: ${entry.message.substring(0, 80)}`);
|
|
42
|
+
// Auto-flush when batch size reached
|
|
43
|
+
if (this.buffer.length >= this.batchSize) {
|
|
44
|
+
this.log(`Batch size ${this.batchSize} reached — flushing`);
|
|
45
|
+
// Fire-and-forget flush (don't block the caller)
|
|
46
|
+
this.flush().catch((err) => {
|
|
47
|
+
this.log(`Flush error: ${err}`);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Flush all buffered logs to the transport.
|
|
53
|
+
* Thread-safe: only one flush can run at a time.
|
|
54
|
+
*/
|
|
55
|
+
async flush() {
|
|
56
|
+
// Mutex — prevent concurrent flushes
|
|
57
|
+
if (this.flushing) {
|
|
58
|
+
this.log("Flush already in progress — skipping");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (this.buffer.length === 0) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this.flushing = true;
|
|
65
|
+
try {
|
|
66
|
+
// Drain the buffer (take all current entries)
|
|
67
|
+
const batch = this.buffer.splice(0, this.buffer.length);
|
|
68
|
+
this.log(`Flushing ${batch.length} logs`);
|
|
69
|
+
const result = await this.transport.send({ logs: batch });
|
|
70
|
+
if (!result.success) {
|
|
71
|
+
this.log(`Flush failed: ${result.error}`);
|
|
72
|
+
// Note: we intentionally don't re-add failed logs to the buffer.
|
|
73
|
+
// This prevents unbounded memory growth if the server is persistently down.
|
|
74
|
+
// The transport layer already retried with backoff.
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
this.flushing = false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Destroy the batcher: stop the timer and flush remaining logs.
|
|
83
|
+
* After destroy(), no new logs can be added.
|
|
84
|
+
*/
|
|
85
|
+
async destroy() {
|
|
86
|
+
if (this.destroyed)
|
|
87
|
+
return;
|
|
88
|
+
this.destroyed = true;
|
|
89
|
+
this.stopTimer();
|
|
90
|
+
this.log("Destroying batcher — final flush");
|
|
91
|
+
await this.flush();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns the current number of buffered logs.
|
|
95
|
+
*/
|
|
96
|
+
get size() {
|
|
97
|
+
return this.buffer.length;
|
|
98
|
+
}
|
|
99
|
+
// ─── Timer Management ──────────────────────────────────
|
|
100
|
+
startTimer() {
|
|
101
|
+
if (this.flushInterval > 0) {
|
|
102
|
+
this.flushTimer = setInterval(() => {
|
|
103
|
+
this.flush().catch((err) => {
|
|
104
|
+
this.log(`Periodic flush error: ${err}`);
|
|
105
|
+
});
|
|
106
|
+
}, this.flushInterval);
|
|
107
|
+
// Allow the Node.js process to exit even if timer is running
|
|
108
|
+
if (this.flushTimer && typeof this.flushTimer === "object" && "unref" in this.flushTimer) {
|
|
109
|
+
this.flushTimer.unref();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
stopTimer() {
|
|
114
|
+
if (this.flushTimer) {
|
|
115
|
+
clearInterval(this.flushTimer);
|
|
116
|
+
this.flushTimer = null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ─── Debug ─────────────────────────────────────────────
|
|
120
|
+
log(message) {
|
|
121
|
+
if (this.debug) {
|
|
122
|
+
console.log(`[TraceStack:Batcher] ${message}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.Batcher = Batcher;
|
|
127
|
+
//# sourceMappingURL=batcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batcher.js","sourceRoot":"","sources":["../src/batcher.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { TraceStackConfig } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* TraceStack SDK client for Node.js.
|
|
4
|
+
*
|
|
5
|
+
* Captures logs and sends them to the TraceStack ingestion API
|
|
6
|
+
* with automatic batching, exponential backoff retry, and
|
|
7
|
+
* graceful shutdown support.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { TraceStack } from "@trace-stack/node";
|
|
12
|
+
*
|
|
13
|
+
* const logger = new TraceStack({
|
|
14
|
+
* apiKey: "ts_live_xxxx",
|
|
15
|
+
* serviceName: "payment-service",
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* logger.info("User logged in", { userId: "123" });
|
|
19
|
+
* logger.error("Payment failed", { orderId: "456", amount: 999 });
|
|
20
|
+
*
|
|
21
|
+
* // On shutdown
|
|
22
|
+
* await logger.destroy();
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class TraceStack {
|
|
26
|
+
private readonly config;
|
|
27
|
+
private readonly batcher;
|
|
28
|
+
private readonly shutdownHandlers;
|
|
29
|
+
private destroyed;
|
|
30
|
+
private readonly systemMeta;
|
|
31
|
+
constructor(config: TraceStackConfig);
|
|
32
|
+
/**
|
|
33
|
+
* Log a debug-level message.
|
|
34
|
+
*/
|
|
35
|
+
debug(message: string, metadata?: Record<string, unknown>): void;
|
|
36
|
+
/**
|
|
37
|
+
* Log an info-level message.
|
|
38
|
+
*/
|
|
39
|
+
info(message: string, metadata?: Record<string, unknown>): void;
|
|
40
|
+
/**
|
|
41
|
+
* Log a warning-level message.
|
|
42
|
+
*/
|
|
43
|
+
warn(message: string, metadata?: Record<string, unknown>): void;
|
|
44
|
+
/**
|
|
45
|
+
* Log an error-level message.
|
|
46
|
+
*/
|
|
47
|
+
error(message: string, metadata?: Record<string, unknown>): void;
|
|
48
|
+
/**
|
|
49
|
+
* Log a fatal-level message.
|
|
50
|
+
*/
|
|
51
|
+
fatal(message: string, metadata?: Record<string, unknown>): void;
|
|
52
|
+
/**
|
|
53
|
+
* Manually flush all buffered logs immediately.
|
|
54
|
+
* Useful before a critical operation or checkpoint.
|
|
55
|
+
*/
|
|
56
|
+
flush(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Gracefully shut down the SDK.
|
|
59
|
+
* Flushes all remaining logs and stops background timers.
|
|
60
|
+
* After calling destroy(), no new logs will be accepted.
|
|
61
|
+
*/
|
|
62
|
+
destroy(): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Capture a log entry and add it to the buffer.
|
|
65
|
+
*/
|
|
66
|
+
private capture;
|
|
67
|
+
private registerShutdownHandlers;
|
|
68
|
+
private removeShutdownHandlers;
|
|
69
|
+
private log;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,SAAS,CAAC;AAYpE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGJ;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0B;IAC3D,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0B;gBAEzC,MAAM,EAAE,gBAAgB;IAwDpC;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAMhE;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAY9B;;OAEG;IACH,OAAO,CAAC,OAAO;IAyBf,OAAO,CAAC,wBAAwB;IAwBhC,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,GAAG;CAMZ"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TraceStack = void 0;
|
|
7
|
+
const transport_1 = require("./transport");
|
|
8
|
+
const batcher_1 = require("./batcher");
|
|
9
|
+
const os_1 = __importDefault(require("os"));
|
|
10
|
+
// ─── Constants ───────────────────────────────────────────────
|
|
11
|
+
const API_KEY_PREFIX = "ts_";
|
|
12
|
+
const DEFAULT_ENDPOINT = "http://localhost:5000";
|
|
13
|
+
// ─── TraceStack Client ──────────────────────────────────────
|
|
14
|
+
/**
|
|
15
|
+
* TraceStack SDK client for Node.js.
|
|
16
|
+
*
|
|
17
|
+
* Captures logs and sends them to the TraceStack ingestion API
|
|
18
|
+
* with automatic batching, exponential backoff retry, and
|
|
19
|
+
* graceful shutdown support.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { TraceStack } from "@trace-stack/node";
|
|
24
|
+
*
|
|
25
|
+
* const logger = new TraceStack({
|
|
26
|
+
* apiKey: "ts_live_xxxx",
|
|
27
|
+
* serviceName: "payment-service",
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* logger.info("User logged in", { userId: "123" });
|
|
31
|
+
* logger.error("Payment failed", { orderId: "456", amount: 999 });
|
|
32
|
+
*
|
|
33
|
+
* // On shutdown
|
|
34
|
+
* await logger.destroy();
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
class TraceStack {
|
|
38
|
+
constructor(config) {
|
|
39
|
+
this.destroyed = false;
|
|
40
|
+
// ─── Validate API key ─────────────────────────────────
|
|
41
|
+
if (!config.apiKey) {
|
|
42
|
+
throw new Error("[TraceStack] apiKey is required");
|
|
43
|
+
}
|
|
44
|
+
if (!config.apiKey.startsWith(API_KEY_PREFIX)) {
|
|
45
|
+
throw new Error(`[TraceStack] apiKey must start with "${API_KEY_PREFIX}" — got "${config.apiKey.substring(0, 10)}..."`);
|
|
46
|
+
}
|
|
47
|
+
// ─── Merge defaults ──────────────────────────────────
|
|
48
|
+
this.config = {
|
|
49
|
+
...config,
|
|
50
|
+
serviceName: config.serviceName ?? "default",
|
|
51
|
+
endpoint: config.endpoint ?? DEFAULT_ENDPOINT,
|
|
52
|
+
debug: config.debug ?? false,
|
|
53
|
+
};
|
|
54
|
+
// ─── System metadata (captured once) ─────────────────
|
|
55
|
+
this.systemMeta = {
|
|
56
|
+
hostname: os_1.default.hostname(),
|
|
57
|
+
pid: process.pid,
|
|
58
|
+
nodeVersion: process.version,
|
|
59
|
+
};
|
|
60
|
+
// ─── Initialize transport + batcher ──────────────────
|
|
61
|
+
const transport = new transport_1.Transport({
|
|
62
|
+
endpoint: this.config.endpoint,
|
|
63
|
+
apiKey: this.config.apiKey,
|
|
64
|
+
maxRetries: config.maxRetries,
|
|
65
|
+
timeout: config.timeout,
|
|
66
|
+
debug: this.config.debug,
|
|
67
|
+
});
|
|
68
|
+
this.batcher = new batcher_1.Batcher({
|
|
69
|
+
transport,
|
|
70
|
+
batchSize: config.batchSize,
|
|
71
|
+
flushInterval: config.flushInterval,
|
|
72
|
+
debug: this.config.debug,
|
|
73
|
+
});
|
|
74
|
+
// ─── Graceful shutdown handlers ──────────────────────
|
|
75
|
+
this.shutdownHandlers = [];
|
|
76
|
+
this.registerShutdownHandlers();
|
|
77
|
+
this.log("Initialized", {
|
|
78
|
+
endpoint: this.config.endpoint,
|
|
79
|
+
serviceName: this.config.serviceName,
|
|
80
|
+
batchSize: config.batchSize ?? 50,
|
|
81
|
+
flushInterval: config.flushInterval ?? 5000,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// ─── Public Logging Methods ────────────────────────────
|
|
85
|
+
/**
|
|
86
|
+
* Log a debug-level message.
|
|
87
|
+
*/
|
|
88
|
+
debug(message, metadata) {
|
|
89
|
+
this.capture("debug", message, metadata);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Log an info-level message.
|
|
93
|
+
*/
|
|
94
|
+
info(message, metadata) {
|
|
95
|
+
this.capture("info", message, metadata);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Log a warning-level message.
|
|
99
|
+
*/
|
|
100
|
+
warn(message, metadata) {
|
|
101
|
+
this.capture("warn", message, metadata);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Log an error-level message.
|
|
105
|
+
*/
|
|
106
|
+
error(message, metadata) {
|
|
107
|
+
this.capture("error", message, metadata);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Log a fatal-level message.
|
|
111
|
+
*/
|
|
112
|
+
fatal(message, metadata) {
|
|
113
|
+
this.capture("fatal", message, metadata);
|
|
114
|
+
}
|
|
115
|
+
// ─── Buffer Control ────────────────────────────────────
|
|
116
|
+
/**
|
|
117
|
+
* Manually flush all buffered logs immediately.
|
|
118
|
+
* Useful before a critical operation or checkpoint.
|
|
119
|
+
*/
|
|
120
|
+
async flush() {
|
|
121
|
+
await this.batcher.flush();
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Gracefully shut down the SDK.
|
|
125
|
+
* Flushes all remaining logs and stops background timers.
|
|
126
|
+
* After calling destroy(), no new logs will be accepted.
|
|
127
|
+
*/
|
|
128
|
+
async destroy() {
|
|
129
|
+
if (this.destroyed)
|
|
130
|
+
return;
|
|
131
|
+
this.destroyed = true;
|
|
132
|
+
this.log("Shutting down...");
|
|
133
|
+
this.removeShutdownHandlers();
|
|
134
|
+
await this.batcher.destroy();
|
|
135
|
+
this.log("Shutdown complete");
|
|
136
|
+
}
|
|
137
|
+
// ─── Internal ──────────────────────────────────────────
|
|
138
|
+
/**
|
|
139
|
+
* Capture a log entry and add it to the buffer.
|
|
140
|
+
*/
|
|
141
|
+
capture(level, message, metadata) {
|
|
142
|
+
if (this.destroyed) {
|
|
143
|
+
this.log("SDK destroyed — dropping log");
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const entry = {
|
|
147
|
+
level,
|
|
148
|
+
message,
|
|
149
|
+
timestamp: new Date().toISOString(),
|
|
150
|
+
serviceName: this.config.serviceName,
|
|
151
|
+
metadata: metadata
|
|
152
|
+
? { ...this.systemMeta, ...metadata }
|
|
153
|
+
: { ...this.systemMeta },
|
|
154
|
+
};
|
|
155
|
+
this.batcher.add(entry);
|
|
156
|
+
}
|
|
157
|
+
// ─── Shutdown Handlers ─────────────────────────────────
|
|
158
|
+
registerShutdownHandlers() {
|
|
159
|
+
const handler = async () => {
|
|
160
|
+
this.log("Received shutdown signal — flushing logs");
|
|
161
|
+
await this.destroy();
|
|
162
|
+
};
|
|
163
|
+
// Wrap in a sync function for process event listeners
|
|
164
|
+
const syncHandler = () => {
|
|
165
|
+
handler().catch((err) => {
|
|
166
|
+
console.error("[TraceStack] Error during shutdown flush:", err);
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
process.on("SIGTERM", syncHandler);
|
|
170
|
+
process.on("SIGINT", syncHandler);
|
|
171
|
+
process.on("beforeExit", syncHandler);
|
|
172
|
+
this.shutdownHandlers.push(async () => {
|
|
173
|
+
process.removeListener("SIGTERM", syncHandler);
|
|
174
|
+
process.removeListener("SIGINT", syncHandler);
|
|
175
|
+
process.removeListener("beforeExit", syncHandler);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
removeShutdownHandlers() {
|
|
179
|
+
for (const remove of this.shutdownHandlers) {
|
|
180
|
+
remove().catch(() => { });
|
|
181
|
+
}
|
|
182
|
+
this.shutdownHandlers.length = 0;
|
|
183
|
+
}
|
|
184
|
+
// ─── Debug Logging ─────────────────────────────────────
|
|
185
|
+
log(message, data) {
|
|
186
|
+
if (this.config.debug) {
|
|
187
|
+
const suffix = data ? ` ${JSON.stringify(data)}` : "";
|
|
188
|
+
console.log(`[TraceStack] ${message}${suffix}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
exports.TraceStack = TraceStack;
|
|
193
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,YAAY,EACV,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── @trace-stack/node ───────────────────────────────────────
|
|
3
|
+
// Node.js SDK for TraceStack log ingestion.
|
|
4
|
+
//
|
|
5
|
+
// Usage:
|
|
6
|
+
// import { TraceStack } from "@trace-stack/node";
|
|
7
|
+
//
|
|
8
|
+
// const logger = new TraceStack({ apiKey: "ts_live_xxx" });
|
|
9
|
+
// logger.info("Hello world");
|
|
10
|
+
// ──────────────────────────────────────────────────────────────
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.TraceStack = void 0;
|
|
13
|
+
var client_1 = require("./client");
|
|
14
|
+
Object.defineProperty(exports, "TraceStack", { enumerable: true, get: function () { return client_1.TraceStack; } });
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,4CAA4C;AAC5C,EAAE;AACF,SAAS;AACT,oDAAoD;AACpD,EAAE;AACF,8DAA8D;AAC9D,gCAAgC;AAChC,iEAAiE;;;AAEjE,mCAAsC;AAA7B,oGAAA,UAAU,OAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IngestPayload, TransportResult } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* HTTP transport layer for the TraceStack SDK.
|
|
4
|
+
* Handles sending log batches to the ingestion API with
|
|
5
|
+
* exponential backoff retry on failures.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Transport {
|
|
8
|
+
private readonly endpoint;
|
|
9
|
+
private readonly apiKey;
|
|
10
|
+
private readonly maxRetries;
|
|
11
|
+
private readonly timeout;
|
|
12
|
+
private readonly debug;
|
|
13
|
+
constructor(options: {
|
|
14
|
+
endpoint: string;
|
|
15
|
+
apiKey: string;
|
|
16
|
+
maxRetries?: number;
|
|
17
|
+
timeout?: number;
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* Send a batch of logs to the ingestion API.
|
|
22
|
+
* Retries with exponential backoff on transient failures.
|
|
23
|
+
*/
|
|
24
|
+
send(payload: IngestPayload): Promise<TransportResult>;
|
|
25
|
+
private sleep;
|
|
26
|
+
private log;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAU9D;;;;GAIG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;gBAEpB,OAAO,EAAE;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;IAQD;;;OAGG;IACG,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC;IAmG5D,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,GAAG;CAKZ"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Transport = void 0;
|
|
4
|
+
// ─── Constants ───────────────────────────────────────────────
|
|
5
|
+
const DEFAULT_TIMEOUT = 10000; // 10 seconds
|
|
6
|
+
const DEFAULT_MAX_RETRIES = 3;
|
|
7
|
+
const BASE_RETRY_DELAY = 1000; // 1 second
|
|
8
|
+
// ─── Transport ───────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* HTTP transport layer for the TraceStack SDK.
|
|
11
|
+
* Handles sending log batches to the ingestion API with
|
|
12
|
+
* exponential backoff retry on failures.
|
|
13
|
+
*/
|
|
14
|
+
class Transport {
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.endpoint = options.endpoint;
|
|
17
|
+
this.apiKey = options.apiKey;
|
|
18
|
+
this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
19
|
+
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
20
|
+
this.debug = options.debug ?? false;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Send a batch of logs to the ingestion API.
|
|
24
|
+
* Retries with exponential backoff on transient failures.
|
|
25
|
+
*/
|
|
26
|
+
async send(payload) {
|
|
27
|
+
const url = `${this.endpoint}/api/v1/logs/ingest`;
|
|
28
|
+
let lastError;
|
|
29
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
30
|
+
try {
|
|
31
|
+
// Wait before retry (skip for first attempt)
|
|
32
|
+
if (attempt > 0) {
|
|
33
|
+
const delay = BASE_RETRY_DELAY * Math.pow(2, attempt - 1);
|
|
34
|
+
this.log(`Retry attempt ${attempt}/${this.maxRetries} after ${delay}ms`);
|
|
35
|
+
await this.sleep(delay);
|
|
36
|
+
}
|
|
37
|
+
const controller = new AbortController();
|
|
38
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
39
|
+
const response = await fetch(url, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: {
|
|
42
|
+
"Content-Type": "application/json",
|
|
43
|
+
"x-api-key": this.apiKey,
|
|
44
|
+
},
|
|
45
|
+
body: JSON.stringify(payload),
|
|
46
|
+
signal: controller.signal,
|
|
47
|
+
});
|
|
48
|
+
clearTimeout(timeoutId);
|
|
49
|
+
// Parse response body
|
|
50
|
+
const body = await response.json().catch(() => ({}));
|
|
51
|
+
// Success
|
|
52
|
+
if (response.ok) {
|
|
53
|
+
const data = body.data;
|
|
54
|
+
this.log(`Successfully sent ${payload.logs.length} logs`);
|
|
55
|
+
return {
|
|
56
|
+
success: true,
|
|
57
|
+
statusCode: response.status,
|
|
58
|
+
ingested: data?.ingested ?? payload.logs.length,
|
|
59
|
+
retries: attempt,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// Rate limited — retry with Retry-After if available
|
|
63
|
+
if (response.status === 429) {
|
|
64
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
65
|
+
if (retryAfter && attempt < this.maxRetries) {
|
|
66
|
+
const waitMs = parseInt(retryAfter, 10) * 1000;
|
|
67
|
+
if (!isNaN(waitMs) && waitMs > 0) {
|
|
68
|
+
this.log(`Rate limited. Waiting ${waitMs}ms (Retry-After header)`);
|
|
69
|
+
await this.sleep(waitMs);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
lastError = `Rate limited (429)`;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
// Client errors (4xx except 429) — don't retry
|
|
77
|
+
if (response.status >= 400 && response.status < 500) {
|
|
78
|
+
const errorMsg = body.error ?? `HTTP ${response.status}`;
|
|
79
|
+
this.log(`Client error: ${errorMsg} — not retrying`);
|
|
80
|
+
return {
|
|
81
|
+
success: false,
|
|
82
|
+
statusCode: response.status,
|
|
83
|
+
error: errorMsg,
|
|
84
|
+
retries: attempt,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Server errors (5xx) — retry
|
|
88
|
+
lastError = `Server error: HTTP ${response.status}`;
|
|
89
|
+
this.log(lastError);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
// Network error or timeout — retry
|
|
93
|
+
if (err instanceof Error) {
|
|
94
|
+
if (err.name === "AbortError") {
|
|
95
|
+
lastError = `Request timeout after ${this.timeout}ms`;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
lastError = `Network error: ${err.message}`;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
lastError = "Unknown transport error";
|
|
103
|
+
}
|
|
104
|
+
this.log(lastError);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// All retries exhausted
|
|
108
|
+
this.log(`All ${this.maxRetries} retries exhausted. Dropping ${payload.logs.length} logs.`);
|
|
109
|
+
return {
|
|
110
|
+
success: false,
|
|
111
|
+
error: lastError ?? "Max retries exhausted",
|
|
112
|
+
retries: this.maxRetries,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// ─── Helpers ─────────────────────────────────────────────
|
|
116
|
+
sleep(ms) {
|
|
117
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
118
|
+
}
|
|
119
|
+
log(message) {
|
|
120
|
+
if (this.debug) {
|
|
121
|
+
console.log(`[TraceStack] ${message}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.Transport = Transport;
|
|
126
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for the TraceStack SDK client.
|
|
3
|
+
*/
|
|
4
|
+
export interface TraceStackConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Your TraceStack API key.
|
|
7
|
+
* Must start with "ts_" (e.g., "ts_live_abc123...").
|
|
8
|
+
*/
|
|
9
|
+
apiKey: string;
|
|
10
|
+
/**
|
|
11
|
+
* Service name attached to every log entry.
|
|
12
|
+
* Identifies which service/app is sending logs.
|
|
13
|
+
* @example "payment-service", "api-gateway"
|
|
14
|
+
*/
|
|
15
|
+
serviceName?: string;
|
|
16
|
+
/**
|
|
17
|
+
* TraceStack ingestion API endpoint.
|
|
18
|
+
* @default "http://localhost:5000"
|
|
19
|
+
*/
|
|
20
|
+
endpoint?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Number of logs to buffer before auto-flushing.
|
|
23
|
+
* @default 50
|
|
24
|
+
*/
|
|
25
|
+
batchSize?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Interval (ms) between automatic flushes of the buffer.
|
|
28
|
+
* @default 5000
|
|
29
|
+
*/
|
|
30
|
+
flushInterval?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Maximum number of retry attempts for failed HTTP requests.
|
|
33
|
+
* Uses exponential backoff: 1s, 2s, 4s, ...
|
|
34
|
+
* @default 3
|
|
35
|
+
*/
|
|
36
|
+
maxRetries?: number;
|
|
37
|
+
/**
|
|
38
|
+
* HTTP request timeout in milliseconds.
|
|
39
|
+
* @default 10000
|
|
40
|
+
*/
|
|
41
|
+
timeout?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Enable debug logging to console.
|
|
44
|
+
* Useful during development to see SDK internals.
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
debug?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Supported log severity levels, ordered by severity.
|
|
51
|
+
*/
|
|
52
|
+
export type LogLevel = "debug" | "info" | "warn" | "error" | "fatal";
|
|
53
|
+
/**
|
|
54
|
+
* A single log entry to be sent to TraceStack.
|
|
55
|
+
*/
|
|
56
|
+
export interface LogEntry {
|
|
57
|
+
/** Log severity level */
|
|
58
|
+
level: LogLevel;
|
|
59
|
+
/** Human-readable log message */
|
|
60
|
+
message: string;
|
|
61
|
+
/** ISO 8601 timestamp */
|
|
62
|
+
timestamp: string;
|
|
63
|
+
/** Service name that generated the log */
|
|
64
|
+
serviceName: string;
|
|
65
|
+
/** Optional source identifier (file, module, function) */
|
|
66
|
+
source?: string;
|
|
67
|
+
/** Optional structured metadata */
|
|
68
|
+
metadata?: Record<string, unknown>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Payload sent to the ingestion API.
|
|
72
|
+
*/
|
|
73
|
+
export interface IngestPayload {
|
|
74
|
+
logs: LogEntry[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Response from the ingestion API.
|
|
78
|
+
*/
|
|
79
|
+
export interface IngestResponse {
|
|
80
|
+
success: boolean;
|
|
81
|
+
data?: {
|
|
82
|
+
ingested: number;
|
|
83
|
+
};
|
|
84
|
+
error?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Result of a transport send operation.
|
|
88
|
+
*/
|
|
89
|
+
export interface TransportResult {
|
|
90
|
+
success: boolean;
|
|
91
|
+
statusCode?: number;
|
|
92
|
+
ingested?: number;
|
|
93
|
+
error?: string;
|
|
94
|
+
retries: number;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAID;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,yBAAyB;IACzB,KAAK,EAAE,QAAQ,CAAC;IAEhB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAEhB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAElB,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IAEpB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAID;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,gEAAgE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trace-stack/node",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Node.js SDK for TraceStack — log ingestion with batching, retries, and graceful shutdown",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"typecheck": "tsc --noEmit"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"tracestack",
|
|
16
|
+
"logging",
|
|
17
|
+
"observability",
|
|
18
|
+
"sdk",
|
|
19
|
+
"monitoring"
|
|
20
|
+
],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"devDependencies": {},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"typescript": "^5.9.3"
|
|
25
|
+
}
|
|
26
|
+
}
|