@mihari/logger-core 0.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/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/batcher.d.ts +32 -0
- package/dist/batcher.d.ts.map +1 -0
- package/dist/batcher.js +85 -0
- package/dist/batcher.js.map +1 -0
- package/dist/client.d.ts +53 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +98 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/transport.d.ts +21 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +81 -0
- package/dist/transport.js.map +1 -0
- package/dist/utils.d.ts +17 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +35 -0
- package/dist/utils.js.map +1 -0
- package/package.json +28 -0
- package/src/index.ts +15 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mihari Contributors
|
|
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,40 @@
|
|
|
1
|
+
# @mihari/logger-core
|
|
2
|
+
|
|
3
|
+
Core transport, batching, and client logic for the mihari log collection library.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @mihari/logger-core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { MihariClient } from "@mihari/logger-core";
|
|
15
|
+
|
|
16
|
+
const client = new MihariClient({
|
|
17
|
+
token: "your-api-token",
|
|
18
|
+
endpoint: "https://logs.example.com",
|
|
19
|
+
batchSize: 10,
|
|
20
|
+
flushInterval: 5000,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
client.info("Hello from core", { module: "auth" });
|
|
24
|
+
|
|
25
|
+
// Flush manually
|
|
26
|
+
await client.flush();
|
|
27
|
+
|
|
28
|
+
// Shutdown gracefully
|
|
29
|
+
await client.shutdown();
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Components
|
|
33
|
+
|
|
34
|
+
- **MihariClient** - Base client with info/warn/error/debug/fatal methods
|
|
35
|
+
- **HttpTransport** - HTTP POST with Bearer auth, gzip support, and retry with exponential backoff
|
|
36
|
+
- **Batcher** - Configurable batching with flush intervals and queue size limits
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
MIT
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { LogEntry, BatchOptions } from "@mihari/logger-types";
|
|
2
|
+
export type FlushCallback = (logs: readonly LogEntry[]) => Promise<void>;
|
|
3
|
+
export declare class Batcher {
|
|
4
|
+
private queue;
|
|
5
|
+
private readonly batchSize;
|
|
6
|
+
private readonly flushIntervalMs;
|
|
7
|
+
private readonly maxQueueSize;
|
|
8
|
+
private readonly onFlush;
|
|
9
|
+
private timer;
|
|
10
|
+
constructor(options: BatchOptions, onFlush: FlushCallback);
|
|
11
|
+
/**
|
|
12
|
+
* Adds a log entry to the queue. Triggers a flush if the
|
|
13
|
+
* batch size threshold is reached.
|
|
14
|
+
*/
|
|
15
|
+
add(entry: LogEntry): void;
|
|
16
|
+
/**
|
|
17
|
+
* Flushes all queued log entries by calling the onFlush callback.
|
|
18
|
+
* Returns a promise that resolves when the flush is complete.
|
|
19
|
+
*/
|
|
20
|
+
flush(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the number of entries currently in the queue.
|
|
23
|
+
*/
|
|
24
|
+
get size(): number;
|
|
25
|
+
/**
|
|
26
|
+
* Stops the periodic flush timer and flushes remaining entries.
|
|
27
|
+
*/
|
|
28
|
+
shutdown(): Promise<void>;
|
|
29
|
+
private startTimer;
|
|
30
|
+
private stopTimer;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=batcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batcher.d.ts","sourceRoot":"","sources":["../src/batcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAM9D,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzE,qBAAa,OAAO;IAClB,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,KAAK,CAA+C;gBAEhD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa;IAQzD;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAa1B;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB5B;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,SAAS;CAMlB"}
|
package/dist/batcher.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Batcher = void 0;
|
|
4
|
+
const DEFAULT_BATCH_SIZE = 10;
|
|
5
|
+
const DEFAULT_FLUSH_INTERVAL_MS = 5000;
|
|
6
|
+
const DEFAULT_MAX_QUEUE_SIZE = 1000;
|
|
7
|
+
class Batcher {
|
|
8
|
+
constructor(options, onFlush) {
|
|
9
|
+
this.queue = [];
|
|
10
|
+
this.timer = null;
|
|
11
|
+
this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
12
|
+
this.flushIntervalMs = options.flushInterval ?? DEFAULT_FLUSH_INTERVAL_MS;
|
|
13
|
+
this.maxQueueSize = options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;
|
|
14
|
+
this.onFlush = onFlush;
|
|
15
|
+
this.startTimer();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Adds a log entry to the queue. Triggers a flush if the
|
|
19
|
+
* batch size threshold is reached.
|
|
20
|
+
*/
|
|
21
|
+
add(entry) {
|
|
22
|
+
if (this.queue.length >= this.maxQueueSize) {
|
|
23
|
+
// Drop the oldest entry when the queue is full
|
|
24
|
+
this.queue.shift();
|
|
25
|
+
}
|
|
26
|
+
this.queue = [...this.queue, entry];
|
|
27
|
+
if (this.queue.length >= this.batchSize) {
|
|
28
|
+
void this.flush();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Flushes all queued log entries by calling the onFlush callback.
|
|
33
|
+
* Returns a promise that resolves when the flush is complete.
|
|
34
|
+
*/
|
|
35
|
+
async flush() {
|
|
36
|
+
if (this.queue.length === 0) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const batch = [...this.queue];
|
|
40
|
+
this.queue = [];
|
|
41
|
+
try {
|
|
42
|
+
await this.onFlush(batch);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
// Re-add entries to the front of the queue on failure,
|
|
46
|
+
// respecting the max queue size
|
|
47
|
+
const combined = [...batch, ...this.queue];
|
|
48
|
+
this.queue = combined.slice(0, this.maxQueueSize);
|
|
49
|
+
// Rethrow so callers know the flush failed
|
|
50
|
+
throw err;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns the number of entries currently in the queue.
|
|
55
|
+
*/
|
|
56
|
+
get size() {
|
|
57
|
+
return this.queue.length;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Stops the periodic flush timer and flushes remaining entries.
|
|
61
|
+
*/
|
|
62
|
+
async shutdown() {
|
|
63
|
+
this.stopTimer();
|
|
64
|
+
await this.flush();
|
|
65
|
+
}
|
|
66
|
+
startTimer() {
|
|
67
|
+
if (this.flushIntervalMs > 0) {
|
|
68
|
+
this.timer = setInterval(() => {
|
|
69
|
+
void this.flush();
|
|
70
|
+
}, this.flushIntervalMs);
|
|
71
|
+
// Allow the Node.js process to exit even if the timer is active
|
|
72
|
+
if (typeof this.timer === "object" && "unref" in this.timer) {
|
|
73
|
+
this.timer.unref();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
stopTimer() {
|
|
78
|
+
if (this.timer !== null) {
|
|
79
|
+
clearInterval(this.timer);
|
|
80
|
+
this.timer = null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.Batcher = Batcher;
|
|
85
|
+
//# 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,53 @@
|
|
|
1
|
+
import { LogLevel, MihariConfig, CompressFn } from "@mihari/logger-types";
|
|
2
|
+
import { HttpTransport } from "./transport";
|
|
3
|
+
import { Batcher } from "./batcher";
|
|
4
|
+
export declare class MihariClient {
|
|
5
|
+
protected readonly config: MihariConfig;
|
|
6
|
+
protected readonly transport: HttpTransport;
|
|
7
|
+
protected readonly batcher: Batcher;
|
|
8
|
+
constructor(config: MihariConfig);
|
|
9
|
+
/**
|
|
10
|
+
* Sets the compression function used by the transport layer.
|
|
11
|
+
*/
|
|
12
|
+
setCompressFn(fn: CompressFn): void;
|
|
13
|
+
/**
|
|
14
|
+
* Logs a debug-level message.
|
|
15
|
+
*/
|
|
16
|
+
debug(message: string, metadata?: Record<string, unknown>): void;
|
|
17
|
+
/**
|
|
18
|
+
* Logs an info-level message.
|
|
19
|
+
*/
|
|
20
|
+
info(message: string, metadata?: Record<string, unknown>): void;
|
|
21
|
+
/**
|
|
22
|
+
* Logs a warn-level message.
|
|
23
|
+
*/
|
|
24
|
+
warn(message: string, metadata?: Record<string, unknown>): void;
|
|
25
|
+
/**
|
|
26
|
+
* Logs an error-level message.
|
|
27
|
+
*/
|
|
28
|
+
error(message: string, metadata?: Record<string, unknown>): void;
|
|
29
|
+
/**
|
|
30
|
+
* Logs a fatal-level message.
|
|
31
|
+
*/
|
|
32
|
+
fatal(message: string, metadata?: Record<string, unknown>): void;
|
|
33
|
+
/**
|
|
34
|
+
* Flushes all pending log entries.
|
|
35
|
+
*/
|
|
36
|
+
flush(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Shuts down the client, flushing remaining entries.
|
|
39
|
+
*/
|
|
40
|
+
shutdown(): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Creates a log entry and adds it to the batch queue.
|
|
43
|
+
* Subclasses can override getDefaultMetadata() to inject
|
|
44
|
+
* environment-specific fields.
|
|
45
|
+
*/
|
|
46
|
+
log(level: LogLevel, message: string, metadata?: Record<string, unknown>): void;
|
|
47
|
+
/**
|
|
48
|
+
* Returns default metadata to include with every log entry.
|
|
49
|
+
* Override in subclasses to add environment-specific fields.
|
|
50
|
+
*/
|
|
51
|
+
protected getDefaultMetadata(): Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAY,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,qBAAa,YAAY;IACvB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IACxC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAC5C,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAExB,MAAM,EAAE,YAAY;IAsBhC;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI;IAInC;;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;IAIhE;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B;;;;OAIG;IACI,GAAG,CACR,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,IAAI;IAaP;;;OAGG;IACH,SAAS,CAAC,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAGxD"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MihariClient = void 0;
|
|
4
|
+
const logger_types_1 = require("@mihari/logger-types");
|
|
5
|
+
const transport_1 = require("./transport");
|
|
6
|
+
const batcher_1 = require("./batcher");
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
class MihariClient {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
this.transport = new transport_1.HttpTransport({
|
|
12
|
+
token: config.token,
|
|
13
|
+
endpoint: config.endpoint,
|
|
14
|
+
compression: config.compression,
|
|
15
|
+
retries: config.retries,
|
|
16
|
+
});
|
|
17
|
+
this.batcher = new batcher_1.Batcher({
|
|
18
|
+
batchSize: config.batchSize,
|
|
19
|
+
flushInterval: config.flushInterval,
|
|
20
|
+
maxQueueSize: config.maxQueueSize,
|
|
21
|
+
}, async (logs) => {
|
|
22
|
+
await this.transport.send(logs);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Sets the compression function used by the transport layer.
|
|
27
|
+
*/
|
|
28
|
+
setCompressFn(fn) {
|
|
29
|
+
this.transport.setCompressFn(fn);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Logs a debug-level message.
|
|
33
|
+
*/
|
|
34
|
+
debug(message, metadata) {
|
|
35
|
+
this.log(logger_types_1.LogLevel.Debug, message, metadata);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Logs an info-level message.
|
|
39
|
+
*/
|
|
40
|
+
info(message, metadata) {
|
|
41
|
+
this.log(logger_types_1.LogLevel.Info, message, metadata);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Logs a warn-level message.
|
|
45
|
+
*/
|
|
46
|
+
warn(message, metadata) {
|
|
47
|
+
this.log(logger_types_1.LogLevel.Warn, message, metadata);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Logs an error-level message.
|
|
51
|
+
*/
|
|
52
|
+
error(message, metadata) {
|
|
53
|
+
this.log(logger_types_1.LogLevel.Error, message, metadata);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Logs a fatal-level message.
|
|
57
|
+
*/
|
|
58
|
+
fatal(message, metadata) {
|
|
59
|
+
this.log(logger_types_1.LogLevel.Fatal, message, metadata);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Flushes all pending log entries.
|
|
63
|
+
*/
|
|
64
|
+
async flush() {
|
|
65
|
+
await this.batcher.flush();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Shuts down the client, flushing remaining entries.
|
|
69
|
+
*/
|
|
70
|
+
async shutdown() {
|
|
71
|
+
await this.batcher.shutdown();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Creates a log entry and adds it to the batch queue.
|
|
75
|
+
* Subclasses can override getDefaultMetadata() to inject
|
|
76
|
+
* environment-specific fields.
|
|
77
|
+
*/
|
|
78
|
+
log(level, message, metadata) {
|
|
79
|
+
const entry = {
|
|
80
|
+
dt: (0, utils_1.isoTimestamp)(),
|
|
81
|
+
level,
|
|
82
|
+
message,
|
|
83
|
+
...this.getDefaultMetadata(),
|
|
84
|
+
...(this.config.metadata ?? {}),
|
|
85
|
+
...(metadata ?? {}),
|
|
86
|
+
};
|
|
87
|
+
this.batcher.add(entry);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Returns default metadata to include with every log entry.
|
|
91
|
+
* Override in subclasses to add environment-specific fields.
|
|
92
|
+
*/
|
|
93
|
+
getDefaultMetadata() {
|
|
94
|
+
return {};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.MihariClient = MihariClient;
|
|
98
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,uDAAoF;AACpF,2CAA4C;AAC5C,uCAAoC;AACpC,mCAAuC;AAEvC,MAAa,YAAY;IAKvB,YAAY,MAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC,SAAS,GAAG,IAAI,yBAAa,CAAC;YACjC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAO,CACxB;YACE,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;YACb,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,EAAc;QAC1B,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAe,EAAE,QAAkC;QACvD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,OAAe,EAAE,QAAkC;QACtD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,OAAe,EAAE,QAAkC;QACtD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAe,EAAE,QAAkC;QACvD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAe,EAAE,QAAkC;QACvD,IAAI,CAAC,GAAG,CAAC,uBAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACI,GAAG,CACR,KAAe,EACf,OAAe,EACf,QAAkC;QAElC,MAAM,KAAK,GAAa;YACtB,EAAE,EAAE,IAAA,oBAAY,GAAE;YAClB,KAAK;YACL,OAAO;YACP,GAAG,IAAI,CAAC,kBAAkB,EAAE;YAC5B,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;YAC/B,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;SACpB,CAAC;QAEF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACO,kBAAkB;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAhHD,oCAgHC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { MihariClient } from "./client";
|
|
2
|
+
export { HttpTransport } from "./transport";
|
|
3
|
+
export { Batcher } from "./batcher";
|
|
4
|
+
export type { FlushCallback } from "./batcher";
|
|
5
|
+
export { isoTimestamp, isBrowser, isNode, sleep } from "./utils";
|
|
6
|
+
export { LogLevel, LogEntry, MihariConfig, TransportOptions, BatchOptions, TransportResponse, TransportError, CompressFn, } from "@mihari/logger-types";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,UAAU,GACX,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LogLevel = exports.sleep = exports.isNode = exports.isBrowser = exports.isoTimestamp = exports.Batcher = exports.HttpTransport = exports.MihariClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "MihariClient", { enumerable: true, get: function () { return client_1.MihariClient; } });
|
|
6
|
+
var transport_1 = require("./transport");
|
|
7
|
+
Object.defineProperty(exports, "HttpTransport", { enumerable: true, get: function () { return transport_1.HttpTransport; } });
|
|
8
|
+
var batcher_1 = require("./batcher");
|
|
9
|
+
Object.defineProperty(exports, "Batcher", { enumerable: true, get: function () { return batcher_1.Batcher; } });
|
|
10
|
+
var utils_1 = require("./utils");
|
|
11
|
+
Object.defineProperty(exports, "isoTimestamp", { enumerable: true, get: function () { return utils_1.isoTimestamp; } });
|
|
12
|
+
Object.defineProperty(exports, "isBrowser", { enumerable: true, get: function () { return utils_1.isBrowser; } });
|
|
13
|
+
Object.defineProperty(exports, "isNode", { enumerable: true, get: function () { return utils_1.isNode; } });
|
|
14
|
+
Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return utils_1.sleep; } });
|
|
15
|
+
var logger_types_1 = require("@mihari/logger-types");
|
|
16
|
+
Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return logger_types_1.LogLevel; } });
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAwC;AAA/B,sGAAA,YAAY,OAAA;AACrB,yCAA4C;AAAnC,0GAAA,aAAa,OAAA;AACtB,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAEhB,iCAAiE;AAAxD,qGAAA,YAAY,OAAA;AAAE,kGAAA,SAAS,OAAA;AAAE,+FAAA,MAAM,OAAA;AAAE,8FAAA,KAAK,OAAA;AAC/C,qDAS8B;AAR5B,wGAAA,QAAQ,OAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LogEntry, TransportOptions, TransportResponse, CompressFn } from "@mihari/logger-types";
|
|
2
|
+
export declare class HttpTransport {
|
|
3
|
+
private readonly token;
|
|
4
|
+
private readonly endpoint;
|
|
5
|
+
private readonly compression;
|
|
6
|
+
private readonly maxRetries;
|
|
7
|
+
private compressFn;
|
|
8
|
+
constructor(options: TransportOptions);
|
|
9
|
+
/**
|
|
10
|
+
* Sets the compression function. This allows node and browser
|
|
11
|
+
* environments to inject their own gzip implementation.
|
|
12
|
+
*/
|
|
13
|
+
setCompressFn(fn: CompressFn): void;
|
|
14
|
+
/**
|
|
15
|
+
* Sends an array of log entries to the ingestion endpoint with
|
|
16
|
+
* retry logic using exponential backoff.
|
|
17
|
+
*/
|
|
18
|
+
send(logs: readonly LogEntry[]): Promise<TransportResponse>;
|
|
19
|
+
private doFetch;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAMjG,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,UAAU,CAA2B;gBAEjC,OAAO,EAAE,gBAAgB;IAOrC;;;OAGG;IACH,aAAa,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI;IAInC;;;OAGG;IACG,IAAI,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAsDnD,OAAO;CAetB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpTransport = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
const DEFAULT_RETRIES = 3;
|
|
6
|
+
const RETRY_BASE_DELAY_MS = 1000;
|
|
7
|
+
class HttpTransport {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.compressFn = null;
|
|
10
|
+
this.token = options.token;
|
|
11
|
+
this.endpoint = options.endpoint.replace(/\/+$/, "");
|
|
12
|
+
this.compression = options.compression ?? true;
|
|
13
|
+
this.maxRetries = options.retries ?? DEFAULT_RETRIES;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Sets the compression function. This allows node and browser
|
|
17
|
+
* environments to inject their own gzip implementation.
|
|
18
|
+
*/
|
|
19
|
+
setCompressFn(fn) {
|
|
20
|
+
this.compressFn = fn;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Sends an array of log entries to the ingestion endpoint with
|
|
24
|
+
* retry logic using exponential backoff.
|
|
25
|
+
*/
|
|
26
|
+
async send(logs) {
|
|
27
|
+
const payload = JSON.stringify(logs);
|
|
28
|
+
let body = payload;
|
|
29
|
+
const headers = {
|
|
30
|
+
"Authorization": `Bearer ${this.token}`,
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
};
|
|
33
|
+
if (this.compression && this.compressFn) {
|
|
34
|
+
const encoded = new TextEncoder().encode(payload);
|
|
35
|
+
body = await this.compressFn(encoded);
|
|
36
|
+
headers["Content-Encoding"] = "gzip";
|
|
37
|
+
}
|
|
38
|
+
let lastError = null;
|
|
39
|
+
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
40
|
+
try {
|
|
41
|
+
const response = await this.doFetch(body, headers);
|
|
42
|
+
if (response.status === 202) {
|
|
43
|
+
return response.json;
|
|
44
|
+
}
|
|
45
|
+
if (response.status === 401) {
|
|
46
|
+
throw new Error("Invalid or missing authentication token");
|
|
47
|
+
}
|
|
48
|
+
if (response.status === 400) {
|
|
49
|
+
throw new Error("No valid logs found");
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`Unexpected response status: ${response.status}`);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
55
|
+
// Do not retry auth or validation errors
|
|
56
|
+
if (lastError.message === "Invalid or missing authentication token" ||
|
|
57
|
+
lastError.message === "No valid logs found") {
|
|
58
|
+
throw lastError;
|
|
59
|
+
}
|
|
60
|
+
if (attempt < this.maxRetries - 1) {
|
|
61
|
+
const delay = RETRY_BASE_DELAY_MS * Math.pow(2, attempt);
|
|
62
|
+
await (0, utils_1.sleep)(delay);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
throw lastError ?? new Error("Transport failed after retries");
|
|
67
|
+
}
|
|
68
|
+
async doFetch(body, headers) {
|
|
69
|
+
// Use global fetch (available in Node 18+ and all modern browsers)
|
|
70
|
+
const res = await fetch(`${this.endpoint}`, {
|
|
71
|
+
method: "POST",
|
|
72
|
+
headers,
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
74
|
+
body: body,
|
|
75
|
+
});
|
|
76
|
+
const json = await res.json().catch(() => ({}));
|
|
77
|
+
return { status: res.status, json };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.HttpTransport = HttpTransport;
|
|
81
|
+
//# 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/utils.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the current timestamp in ISO 8601 format.
|
|
3
|
+
*/
|
|
4
|
+
export declare function isoTimestamp(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Detects whether the current runtime is a browser environment.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isBrowser(): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Detects whether the current runtime is Node.js.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isNode(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Waits for the specified number of milliseconds.
|
|
15
|
+
*/
|
|
16
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAMnC;AAED;;GAEG;AACH,wBAAgB,MAAM,IAAI,OAAO,CAMhC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isoTimestamp = isoTimestamp;
|
|
4
|
+
exports.isBrowser = isBrowser;
|
|
5
|
+
exports.isNode = isNode;
|
|
6
|
+
exports.sleep = sleep;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the current timestamp in ISO 8601 format.
|
|
9
|
+
*/
|
|
10
|
+
function isoTimestamp() {
|
|
11
|
+
return new Date().toISOString();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Detects whether the current runtime is a browser environment.
|
|
15
|
+
*/
|
|
16
|
+
function isBrowser() {
|
|
17
|
+
return (typeof globalThis !== "undefined" &&
|
|
18
|
+
typeof globalThis.window !== "undefined" &&
|
|
19
|
+
typeof globalThis.document !== "undefined");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Detects whether the current runtime is Node.js.
|
|
23
|
+
*/
|
|
24
|
+
function isNode() {
|
|
25
|
+
return (typeof process !== "undefined" &&
|
|
26
|
+
process.versions != null &&
|
|
27
|
+
process.versions.node != null);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Waits for the specified number of milliseconds.
|
|
31
|
+
*/
|
|
32
|
+
function sleep(ms) {
|
|
33
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAGA,oCAEC;AAKD,8BAMC;AAKD,wBAMC;AAKD,sBAEC;AAlCD;;GAEG;AACH,SAAgB,YAAY;IAC1B,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS;IACvB,OAAO,CACL,OAAO,UAAU,KAAK,WAAW;QACjC,OAAQ,UAAsC,CAAC,MAAM,KAAK,WAAW;QACrE,OAAQ,UAAsC,CAAC,QAAQ,KAAK,WAAW,CACxE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,MAAM;IACpB,OAAO,CACL,OAAO,OAAO,KAAK,WAAW;QAC9B,OAAO,CAAC,QAAQ,IAAI,IAAI;QACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAC9B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mihari/logger-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Core transport, batching, and client logic for mihari",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"types": "src/index.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"clean": "rm -rf dist",
|
|
13
|
+
"test": "cd ../.. && npx vitest run --config vitest.config.ts packages/core"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@mihari/logger-types": "^0.1.0"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/mihari/mihari-js",
|
|
25
|
+
"directory": "packages/core"
|
|
26
|
+
},
|
|
27
|
+
"gitHead": "dc10a3217caa819965eb3a1e2ff3901a16e510aa"
|
|
28
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { MihariClient } from "./client";
|
|
2
|
+
export { HttpTransport } from "./transport";
|
|
3
|
+
export { Batcher } from "./batcher";
|
|
4
|
+
export type { FlushCallback } from "./batcher";
|
|
5
|
+
export { isoTimestamp, isBrowser, isNode, sleep } from "./utils";
|
|
6
|
+
export {
|
|
7
|
+
LogLevel,
|
|
8
|
+
LogEntry,
|
|
9
|
+
MihariConfig,
|
|
10
|
+
TransportOptions,
|
|
11
|
+
BatchOptions,
|
|
12
|
+
TransportResponse,
|
|
13
|
+
TransportError,
|
|
14
|
+
CompressFn,
|
|
15
|
+
} from "@mihari/logger-types";
|