tinylogs 0.1.0 → 0.3.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 +21 -1
- package/dist/cli.js +384 -49
- package/dist/cli.js.map +4 -4
- package/dist/server/index.js +38 -30
- package/dist/server/index.js.map +2 -2
- package/package.json +8 -13
- package/dist/client/index.d.ts +0 -30
- package/dist/client/index.js +0 -65
- package/dist/client/index.js.map +0 -7
- package/dist/src/types.d.ts +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tinylogs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A tiny self-hosted central log receiver + live dashboard.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Nikita Medvedev",
|
|
@@ -24,16 +24,14 @@
|
|
|
24
24
|
"bin": {
|
|
25
25
|
"tinylogs": "dist/cli.js"
|
|
26
26
|
},
|
|
27
|
-
"types": "dist/client/index.d.ts",
|
|
28
27
|
"exports": {
|
|
29
|
-
".": "./dist/cli.js"
|
|
30
|
-
"./client": {
|
|
31
|
-
"types": "./dist/client/index.d.ts",
|
|
32
|
-
"import": "./dist/client/index.js"
|
|
33
|
-
}
|
|
28
|
+
".": "./dist/cli.js"
|
|
34
29
|
},
|
|
30
|
+
"workspaces": [
|
|
31
|
+
"packages/client"
|
|
32
|
+
],
|
|
35
33
|
"engines": {
|
|
36
|
-
"node": ">=
|
|
34
|
+
"node": ">=22.13"
|
|
37
35
|
},
|
|
38
36
|
"files": [
|
|
39
37
|
"dist",
|
|
@@ -45,8 +43,7 @@
|
|
|
45
43
|
"dev:cli": "tsx src/cli.ts",
|
|
46
44
|
"build:server": "node esbuild.config.mjs",
|
|
47
45
|
"build:ui": "node esbuild.ui.mjs",
|
|
48
|
-
"build
|
|
49
|
-
"build": "npm run build:server && npm run build:ui && npm run build:types",
|
|
46
|
+
"build": "npm run build:server && npm run build:ui",
|
|
50
47
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
51
48
|
"dev:ui": "node esbuild.ui.mjs --watch",
|
|
52
49
|
"test": "vitest run",
|
|
@@ -55,7 +52,6 @@
|
|
|
55
52
|
},
|
|
56
53
|
"dependencies": {
|
|
57
54
|
"bcryptjs": "^2.4.3",
|
|
58
|
-
"better-sqlite3": "^11.3.0",
|
|
59
55
|
"cookie": "^0.7.2",
|
|
60
56
|
"express": "^4.19.2",
|
|
61
57
|
"ws": "^8.18.0"
|
|
@@ -63,10 +59,9 @@
|
|
|
63
59
|
"devDependencies": {
|
|
64
60
|
"@testing-library/svelte": "^5.2.0",
|
|
65
61
|
"@types/bcryptjs": "^2.4.6",
|
|
66
|
-
"@types/better-sqlite3": "^7.6.11",
|
|
67
62
|
"@types/cookie": "^0.6.0",
|
|
68
63
|
"@types/express": "^4.17.21",
|
|
69
|
-
"@types/node": "^
|
|
64
|
+
"@types/node": "^22.13.0",
|
|
70
65
|
"@types/supertest": "^6.0.2",
|
|
71
66
|
"@types/ws": "^8.5.12",
|
|
72
67
|
"esbuild": "^0.25.0",
|
package/dist/client/index.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export interface TinyLogsOptions {
|
|
2
|
-
url: string;
|
|
3
|
-
token: string;
|
|
4
|
-
service: string;
|
|
5
|
-
batchSize?: number;
|
|
6
|
-
flushInterval?: number;
|
|
7
|
-
onError?: (err: unknown) => void;
|
|
8
|
-
fetchImpl?: typeof fetch;
|
|
9
|
-
}
|
|
10
|
-
export interface LogInput {
|
|
11
|
-
message: string;
|
|
12
|
-
labels?: Record<string, string>;
|
|
13
|
-
ts?: number;
|
|
14
|
-
}
|
|
15
|
-
export declare class TinyLogsClient {
|
|
16
|
-
private opts;
|
|
17
|
-
private buf;
|
|
18
|
-
private readonly batchSize;
|
|
19
|
-
private readonly flushInterval;
|
|
20
|
-
private readonly fetchImpl;
|
|
21
|
-
private timer;
|
|
22
|
-
private closed;
|
|
23
|
-
constructor(opts: TinyLogsOptions);
|
|
24
|
-
log(input: LogInput): void;
|
|
25
|
-
info(message: string, labels?: Record<string, string>): void;
|
|
26
|
-
warn(message: string, labels?: Record<string, string>): void;
|
|
27
|
-
error(message: string, labels?: Record<string, string>): void;
|
|
28
|
-
flush(): Promise<void>;
|
|
29
|
-
close(): Promise<void>;
|
|
30
|
-
}
|
package/dist/client/index.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
// client/index.ts
|
|
2
|
-
var TinyLogsClient = class {
|
|
3
|
-
constructor(opts) {
|
|
4
|
-
this.opts = opts;
|
|
5
|
-
this.batchSize = opts.batchSize ?? 50;
|
|
6
|
-
this.flushInterval = opts.flushInterval ?? 1e3;
|
|
7
|
-
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
8
|
-
this.timer = setInterval(() => {
|
|
9
|
-
void this.flush();
|
|
10
|
-
}, this.flushInterval);
|
|
11
|
-
if (typeof this.timer?.unref === "function") this.timer.unref();
|
|
12
|
-
}
|
|
13
|
-
buf = [];
|
|
14
|
-
batchSize;
|
|
15
|
-
flushInterval;
|
|
16
|
-
fetchImpl;
|
|
17
|
-
timer = null;
|
|
18
|
-
closed = false;
|
|
19
|
-
log(input) {
|
|
20
|
-
if (this.closed) return;
|
|
21
|
-
const rec = { service: this.opts.service, message: input.message, labels: input.labels ?? {} };
|
|
22
|
-
if (input.ts !== void 0) rec.ts = input.ts;
|
|
23
|
-
this.buf.push(rec);
|
|
24
|
-
if (this.buf.length >= this.batchSize) void this.flush();
|
|
25
|
-
}
|
|
26
|
-
info(message, labels = {}) {
|
|
27
|
-
this.log({ message, labels: { level: "info", ...labels } });
|
|
28
|
-
}
|
|
29
|
-
warn(message, labels = {}) {
|
|
30
|
-
this.log({ message, labels: { level: "warn", ...labels } });
|
|
31
|
-
}
|
|
32
|
-
error(message, labels = {}) {
|
|
33
|
-
this.log({ message, labels: { level: "error", ...labels } });
|
|
34
|
-
}
|
|
35
|
-
async flush() {
|
|
36
|
-
if (this.buf.length === 0) return;
|
|
37
|
-
const batch = this.buf;
|
|
38
|
-
this.buf = [];
|
|
39
|
-
try {
|
|
40
|
-
const res = await this.fetchImpl(`${this.opts.url}/ingest`, {
|
|
41
|
-
method: "POST",
|
|
42
|
-
headers: { "Content-Type": "application/json", Authorization: `Bearer ${this.opts.token}` },
|
|
43
|
-
body: JSON.stringify(batch)
|
|
44
|
-
});
|
|
45
|
-
if (!res.ok) throw new Error(`tinylogs ingest failed: ${res.status}`);
|
|
46
|
-
} catch (err) {
|
|
47
|
-
try {
|
|
48
|
-
this.opts.onError?.(err);
|
|
49
|
-
} catch {
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
async close() {
|
|
54
|
-
this.closed = true;
|
|
55
|
-
if (this.timer) {
|
|
56
|
-
clearInterval(this.timer);
|
|
57
|
-
this.timer = null;
|
|
58
|
-
}
|
|
59
|
-
await this.flush();
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
export {
|
|
63
|
-
TinyLogsClient
|
|
64
|
-
};
|
|
65
|
-
//# sourceMappingURL=index.js.map
|
package/dist/client/index.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../client/index.ts"],
|
|
4
|
-
"sourcesContent": ["export interface TinyLogsOptions {\n url: string;\n token: string;\n service: string;\n batchSize?: number;\n flushInterval?: number;\n onError?: (err: unknown) => void;\n fetchImpl?: typeof fetch;\n}\n\nexport interface LogInput { message: string; labels?: Record<string, string>; ts?: number; }\n\ninterface WireRecord { service: string; message: string; labels: Record<string, string>; ts?: number; }\n\nexport class TinyLogsClient {\n private buf: WireRecord[] = [];\n private readonly batchSize: number;\n private readonly flushInterval: number;\n private readonly fetchImpl: typeof fetch;\n private timer: ReturnType<typeof setInterval> | null = null;\n private closed = false;\n\n constructor(private opts: TinyLogsOptions) {\n this.batchSize = opts.batchSize ?? 50;\n this.flushInterval = opts.flushInterval ?? 1000;\n this.fetchImpl = opts.fetchImpl ?? fetch;\n this.timer = setInterval(() => { void this.flush(); }, this.flushInterval);\n // Do not keep the event loop alive just for logging.\n if (typeof (this.timer as any)?.unref === 'function') (this.timer as any).unref();\n }\n\n log(input: LogInput): void {\n if (this.closed) return;\n const rec: WireRecord = { service: this.opts.service, message: input.message, labels: input.labels ?? {} };\n if (input.ts !== undefined) rec.ts = input.ts;\n this.buf.push(rec);\n if (this.buf.length >= this.batchSize) void this.flush();\n }\n\n info(message: string, labels: Record<string, string> = {}): void { this.log({ message, labels: { level: 'info', ...labels } }); }\n warn(message: string, labels: Record<string, string> = {}): void { this.log({ message, labels: { level: 'warn', ...labels } }); }\n error(message: string, labels: Record<string, string> = {}): void { this.log({ message, labels: { level: 'error', ...labels } }); }\n\n async flush(): Promise<void> {\n if (this.buf.length === 0) return;\n const batch = this.buf;\n this.buf = [];\n try {\n const res = await this.fetchImpl(`${this.opts.url}/ingest`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.opts.token}` },\n body: JSON.stringify(batch),\n });\n if (!res.ok) throw new Error(`tinylogs ingest failed: ${res.status}`);\n } catch (err) {\n // Fire-and-forget: never propagate. Optionally notify.\n try { this.opts.onError?.(err); } catch {}\n }\n }\n\n async close(): Promise<void> {\n this.closed = true;\n if (this.timer) { clearInterval(this.timer); this.timer = null; }\n await this.flush();\n }\n}\n"],
|
|
5
|
-
"mappings": ";AAcO,IAAM,iBAAN,MAAqB;AAAA,EAQ1B,YAAoB,MAAuB;AAAvB;AAClB,SAAK,YAAY,KAAK,aAAa;AACnC,SAAK,gBAAgB,KAAK,iBAAiB;AAC3C,SAAK,YAAY,KAAK,aAAa;AACnC,SAAK,QAAQ,YAAY,MAAM;AAAE,WAAK,KAAK,MAAM;AAAA,IAAG,GAAG,KAAK,aAAa;AAEzE,QAAI,OAAQ,KAAK,OAAe,UAAU,WAAY,CAAC,KAAK,MAAc,MAAM;AAAA,EAClF;AAAA,EAdQ,MAAoB,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACT,QAA+C;AAAA,EAC/C,SAAS;AAAA,EAWjB,IAAI,OAAuB;AACzB,QAAI,KAAK,OAAQ;AACjB,UAAM,MAAkB,EAAE,SAAS,KAAK,KAAK,SAAS,SAAS,MAAM,SAAS,QAAQ,MAAM,UAAU,CAAC,EAAE;AACzG,QAAI,MAAM,OAAO,OAAW,KAAI,KAAK,MAAM;AAC3C,SAAK,IAAI,KAAK,GAAG;AACjB,QAAI,KAAK,IAAI,UAAU,KAAK,UAAW,MAAK,KAAK,MAAM;AAAA,EACzD;AAAA,EAEA,KAAK,SAAiB,SAAiC,CAAC,GAAS;AAAE,SAAK,IAAI,EAAE,SAAS,QAAQ,EAAE,OAAO,QAAQ,GAAG,OAAO,EAAE,CAAC;AAAA,EAAG;AAAA,EAChI,KAAK,SAAiB,SAAiC,CAAC,GAAS;AAAE,SAAK,IAAI,EAAE,SAAS,QAAQ,EAAE,OAAO,QAAQ,GAAG,OAAO,EAAE,CAAC;AAAA,EAAG;AAAA,EAChI,MAAM,SAAiB,SAAiC,CAAC,GAAS;AAAE,SAAK,IAAI,EAAE,SAAS,QAAQ,EAAE,OAAO,SAAS,GAAG,OAAO,EAAE,CAAC;AAAA,EAAG;AAAA,EAElI,MAAM,QAAuB;AAC3B,QAAI,KAAK,IAAI,WAAW,EAAG;AAC3B,UAAM,QAAQ,KAAK;AACnB,SAAK,MAAM,CAAC;AACZ,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,UAAU,GAAG,KAAK,KAAK,GAAG,WAAW;AAAA,QAC1D,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,KAAK,KAAK,KAAK,GAAG;AAAA,QAC1F,MAAM,KAAK,UAAU,KAAK;AAAA,MAC5B,CAAC;AACD,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,2BAA2B,IAAI,MAAM,EAAE;AAAA,IACtE,SAAS,KAAK;AAEZ,UAAI;AAAE,aAAK,KAAK,UAAU,GAAG;AAAA,MAAG,QAAQ;AAAA,MAAC;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB;AAC3B,SAAK,SAAS;AACd,QAAI,KAAK,OAAO;AAAE,oBAAc,KAAK,KAAK;AAAG,WAAK,QAAQ;AAAA,IAAM;AAChE,UAAM,KAAK,MAAM;AAAA,EACnB;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/src/types.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export interface LogRecord {
|
|
2
|
-
id?: number;
|
|
3
|
-
ts: number;
|
|
4
|
-
service: string;
|
|
5
|
-
message: string;
|
|
6
|
-
labels: Record<string, string>;
|
|
7
|
-
}
|
|
8
|
-
export interface Config {
|
|
9
|
-
port: number;
|
|
10
|
-
host: string;
|
|
11
|
-
dbPath: string;
|
|
12
|
-
retentionDays: number;
|
|
13
|
-
maxSizeMB: number;
|
|
14
|
-
bufferSize: number;
|
|
15
|
-
sessionSecret: string;
|
|
16
|
-
ingestTokenHash: string;
|
|
17
|
-
}
|