@jetstart/logs 1.5.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/.eslintrc.json +6 -0
- package/README.md +122 -0
- package/dist/cli/formatter.d.ts +8 -0
- package/dist/cli/formatter.js +60 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +24 -0
- package/dist/cli/viewer.d.ts +13 -0
- package/dist/cli/viewer.js +63 -0
- package/dist/filters/index.d.ts +10 -0
- package/dist/filters/index.js +45 -0
- package/dist/filters/level.d.ts +8 -0
- package/dist/filters/level.js +28 -0
- package/dist/filters/search.d.ts +7 -0
- package/dist/filters/search.js +29 -0
- package/dist/filters/source.d.ts +7 -0
- package/dist/filters/source.js +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +26 -0
- package/dist/server/index.d.ts +26 -0
- package/dist/server/index.js +119 -0
- package/dist/server/storage.d.ts +15 -0
- package/dist/server/storage.js +70 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.js +6 -0
- package/dist/utils/colors.d.ts +9 -0
- package/dist/utils/colors.js +50 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.js +21 -0
- package/package.json +65 -0
- package/src/cli/formatter.ts +63 -0
- package/src/cli/index.ts +24 -0
- package/src/cli/viewer.ts +64 -0
- package/src/filters/index.ts +51 -0
- package/src/filters/level.ts +28 -0
- package/src/filters/search.ts +32 -0
- package/src/filters/source.ts +10 -0
- package/src/index.ts +19 -0
- package/src/server/index.ts +134 -0
- package/src/server/storage.ts +77 -0
- package/src/types/index.ts +15 -0
- package/src/utils/colors.ts +45 -0
- package/src/utils/index.ts +5 -0
- package/tests/filters.test.ts +81 -0
- package/tests/storage.test.ts +89 -0
- package/tsconfig.json +25 -0
package/.eslintrc.json
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# @jetstart/logs
|
|
2
|
+
|
|
3
|
+
Logging infrastructure for JetStart.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Logs package provides:
|
|
8
|
+
|
|
9
|
+
- 📊 **Log Server** - WebSocket-based log streaming
|
|
10
|
+
- 💾 **Log Storage** - In-memory log storage with size limits
|
|
11
|
+
- 🔍 **Filtering** - Filter by level, source, tag, or search query
|
|
12
|
+
- 🖥️ **CLI Viewer** - Terminal-based log viewer
|
|
13
|
+
- 📈 **Statistics** - Log metrics and analytics
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Start Log Server
|
|
18
|
+
```typescript
|
|
19
|
+
import { LogsServer } from '@jetstart/logs';
|
|
20
|
+
|
|
21
|
+
const server = new LogsServer({ port: 8767 });
|
|
22
|
+
await server.start();
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### View Logs in CLI
|
|
26
|
+
```typescript
|
|
27
|
+
import { viewLogs } from '@jetstart/logs';
|
|
28
|
+
import { LogLevel, LogSource } from '@jetstart/shared';
|
|
29
|
+
|
|
30
|
+
await viewLogs({
|
|
31
|
+
levels: [LogLevel.ERROR, LogLevel.WARN],
|
|
32
|
+
sources: [LogSource.BUILD],
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Add Logs
|
|
37
|
+
```typescript
|
|
38
|
+
import { LogsServer } from '@jetstart/logs';
|
|
39
|
+
import { LogLevel, LogSource } from '@jetstart/shared';
|
|
40
|
+
|
|
41
|
+
const server = new LogsServer();
|
|
42
|
+
await server.start();
|
|
43
|
+
|
|
44
|
+
server.addLog({
|
|
45
|
+
id: '123',
|
|
46
|
+
timestamp: Date.now(),
|
|
47
|
+
level: LogLevel.INFO,
|
|
48
|
+
tag: 'Build',
|
|
49
|
+
message: 'Compilation complete',
|
|
50
|
+
source: LogSource.BUILD,
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Filter Logs
|
|
55
|
+
```typescript
|
|
56
|
+
import { applyFilters } from '@jetstart/logs';
|
|
57
|
+
import { LogLevel } from '@jetstart/shared';
|
|
58
|
+
|
|
59
|
+
const filtered = applyFilters(logs, {
|
|
60
|
+
levels: [LogLevel.ERROR],
|
|
61
|
+
searchQuery: 'compilation',
|
|
62
|
+
startTime: Date.now() - 3600000, // Last hour
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Log Levels
|
|
67
|
+
|
|
68
|
+
- `VERBOSE` - Very detailed information
|
|
69
|
+
- `DEBUG` - Debug information
|
|
70
|
+
- `INFO` - General information
|
|
71
|
+
- `WARN` - Warning messages
|
|
72
|
+
- `ERROR` - Error messages
|
|
73
|
+
- `FATAL` - Fatal errors
|
|
74
|
+
|
|
75
|
+
## Log Sources
|
|
76
|
+
|
|
77
|
+
- `CLI` - Command-line interface
|
|
78
|
+
- `CORE` - Build server
|
|
79
|
+
- `CLIENT` - Android client
|
|
80
|
+
- `BUILD` - Build system
|
|
81
|
+
- `NETWORK` - Network operations
|
|
82
|
+
- `SYSTEM` - System operations
|
|
83
|
+
|
|
84
|
+
## WebSocket Protocol
|
|
85
|
+
|
|
86
|
+
**Subscribe to logs:**
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"type": "subscribe",
|
|
90
|
+
"filter": {
|
|
91
|
+
"levels": ["error", "warn"],
|
|
92
|
+
"sources": ["build"]
|
|
93
|
+
},
|
|
94
|
+
"maxLines": 100
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Send log:**
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"type": "log",
|
|
102
|
+
"log": {
|
|
103
|
+
"id": "123",
|
|
104
|
+
"timestamp": 1234567890,
|
|
105
|
+
"level": "info",
|
|
106
|
+
"tag": "Build",
|
|
107
|
+
"message": "Build complete",
|
|
108
|
+
"source": "build"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Get statistics:**
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"type": "stats"
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
Apache-2.0
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log Formatter
|
|
3
|
+
* Formats log entries for terminal display
|
|
4
|
+
*/
|
|
5
|
+
import { LogEntry } from '@jetstart/shared';
|
|
6
|
+
export declare function formatLog(entry: LogEntry): void;
|
|
7
|
+
export declare function formatStats(stats: any): void;
|
|
8
|
+
//# sourceMappingURL=formatter.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Log Formatter
|
|
4
|
+
* Formats log entries for terminal display
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.formatLog = formatLog;
|
|
11
|
+
exports.formatStats = formatStats;
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
const date_fns_1 = require("date-fns");
|
|
14
|
+
const colors_1 = require("../utils/colors");
|
|
15
|
+
function formatLog(entry) {
|
|
16
|
+
const timestamp = formatTimestamp(entry.timestamp);
|
|
17
|
+
const level = formatLevel(entry.level);
|
|
18
|
+
const source = formatSource(entry.source);
|
|
19
|
+
const tag = formatTag(entry.tag);
|
|
20
|
+
const message = entry.message;
|
|
21
|
+
console.log(`${timestamp} ${level} ${source} ${tag} ${message}`);
|
|
22
|
+
}
|
|
23
|
+
function formatTimestamp(timestamp) {
|
|
24
|
+
return chalk_1.default.gray((0, date_fns_1.format)(timestamp, 'HH:mm:ss.SSS'));
|
|
25
|
+
}
|
|
26
|
+
function formatLevel(level) {
|
|
27
|
+
const color = (0, colors_1.getColorForLevel)(level);
|
|
28
|
+
const label = level.toUpperCase().padEnd(7);
|
|
29
|
+
return color(label);
|
|
30
|
+
}
|
|
31
|
+
function formatSource(source) {
|
|
32
|
+
const color = (0, colors_1.getColorForSource)(source);
|
|
33
|
+
const label = `[${source}]`.padEnd(10);
|
|
34
|
+
return color(label);
|
|
35
|
+
}
|
|
36
|
+
function formatTag(tag) {
|
|
37
|
+
return chalk_1.default.gray(`[${tag}]`);
|
|
38
|
+
}
|
|
39
|
+
function formatStats(stats) {
|
|
40
|
+
console.log();
|
|
41
|
+
console.log(chalk_1.default.bold('Log Statistics:'));
|
|
42
|
+
console.log();
|
|
43
|
+
console.log(`Total Logs: ${chalk_1.default.cyan(stats.totalLogs)}`);
|
|
44
|
+
console.log(`Errors: ${chalk_1.default.red(stats.errorCount)}`);
|
|
45
|
+
console.log(`Warnings: ${chalk_1.default.yellow(stats.warningCount)}`);
|
|
46
|
+
console.log();
|
|
47
|
+
console.log(chalk_1.default.bold('By Level:'));
|
|
48
|
+
Object.entries(stats.logsByLevel).forEach(([level, count]) => {
|
|
49
|
+
const color = (0, colors_1.getColorForLevel)(level);
|
|
50
|
+
console.log(` ${level.padEnd(10)}: ${color(count)}`);
|
|
51
|
+
});
|
|
52
|
+
console.log();
|
|
53
|
+
console.log(chalk_1.default.bold('By Source:'));
|
|
54
|
+
Object.entries(stats.logsBySource).forEach(([source, count]) => {
|
|
55
|
+
const color = (0, colors_1.getColorForSource)(source);
|
|
56
|
+
console.log(` ${source.padEnd(10)}: ${color(count)}`);
|
|
57
|
+
});
|
|
58
|
+
console.log();
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=formatter.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Log Viewer
|
|
3
|
+
* Terminal-based log viewer
|
|
4
|
+
*/
|
|
5
|
+
import { LogFilter } from '@jetstart/shared';
|
|
6
|
+
export declare function viewLogs(filter?: LogFilter): Promise<void>;
|
|
7
|
+
export { LogViewer } from './viewer';
|
|
8
|
+
export { formatLog } from './formatter';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CLI Log Viewer
|
|
4
|
+
* Terminal-based log viewer
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.formatLog = exports.LogViewer = void 0;
|
|
8
|
+
exports.viewLogs = viewLogs;
|
|
9
|
+
const viewer_1 = require("./viewer");
|
|
10
|
+
async function viewLogs(filter) {
|
|
11
|
+
const viewer = new viewer_1.LogViewer();
|
|
12
|
+
await viewer.connect();
|
|
13
|
+
viewer.subscribe(filter);
|
|
14
|
+
// Keep process alive
|
|
15
|
+
process.on('SIGINT', async () => {
|
|
16
|
+
await viewer.disconnect();
|
|
17
|
+
process.exit(0);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
var viewer_2 = require("./viewer");
|
|
21
|
+
Object.defineProperty(exports, "LogViewer", { enumerable: true, get: function () { return viewer_2.LogViewer; } });
|
|
22
|
+
var formatter_1 = require("./formatter");
|
|
23
|
+
Object.defineProperty(exports, "formatLog", { enumerable: true, get: function () { return formatter_1.formatLog; } });
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log Viewer
|
|
3
|
+
* Connects to logs service and displays logs
|
|
4
|
+
*/
|
|
5
|
+
import { LogFilter } from '@jetstart/shared';
|
|
6
|
+
export declare class LogViewer {
|
|
7
|
+
private ws?;
|
|
8
|
+
private connected;
|
|
9
|
+
connect(port?: number): Promise<void>;
|
|
10
|
+
subscribe(filter?: LogFilter, maxLines?: number): void;
|
|
11
|
+
disconnect(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=viewer.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Log Viewer
|
|
4
|
+
* Connects to logs service and displays logs
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.LogViewer = void 0;
|
|
11
|
+
const ws_1 = __importDefault(require("ws"));
|
|
12
|
+
const shared_1 = require("@jetstart/shared");
|
|
13
|
+
const formatter_1 = require("./formatter");
|
|
14
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
15
|
+
class LogViewer {
|
|
16
|
+
ws;
|
|
17
|
+
connected = false;
|
|
18
|
+
async connect(port = shared_1.DEFAULT_LOGS_PORT) {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
this.ws = new ws_1.default(`ws://localhost:${port}`);
|
|
21
|
+
this.ws.on('open', () => {
|
|
22
|
+
this.connected = true;
|
|
23
|
+
console.log(chalk_1.default.green('✔'), 'Connected to logs service');
|
|
24
|
+
console.log();
|
|
25
|
+
resolve();
|
|
26
|
+
});
|
|
27
|
+
this.ws.on('message', (data) => {
|
|
28
|
+
try {
|
|
29
|
+
const log = JSON.parse(data.toString());
|
|
30
|
+
(0, formatter_1.formatLog)(log);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.log(data.toString());
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
this.ws.on('error', (err) => {
|
|
37
|
+
reject(err);
|
|
38
|
+
});
|
|
39
|
+
this.ws.on('close', () => {
|
|
40
|
+
this.connected = false;
|
|
41
|
+
console.log();
|
|
42
|
+
console.log(chalk_1.default.yellow('⚠'), 'Disconnected from logs service');
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
subscribe(filter, maxLines) {
|
|
47
|
+
if (!this.ws || !this.connected) {
|
|
48
|
+
throw new Error('Not connected to logs service');
|
|
49
|
+
}
|
|
50
|
+
this.ws.send(JSON.stringify({
|
|
51
|
+
type: 'subscribe',
|
|
52
|
+
filter,
|
|
53
|
+
maxLines,
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
async disconnect() {
|
|
57
|
+
if (this.ws) {
|
|
58
|
+
this.ws.close();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.LogViewer = LogViewer;
|
|
63
|
+
//# sourceMappingURL=viewer.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log Filters
|
|
3
|
+
* Filter logs by level, source, tag, or search query
|
|
4
|
+
*/
|
|
5
|
+
import { LogEntry, LogFilter } from '@jetstart/shared';
|
|
6
|
+
export declare function applyFilters(logs: LogEntry[], filter: LogFilter): LogEntry[];
|
|
7
|
+
export { filterByLevel } from './level';
|
|
8
|
+
export { filterBySource } from './source';
|
|
9
|
+
export { filterBySearch } from './search';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Log Filters
|
|
4
|
+
* Filter logs by level, source, tag, or search query
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.filterBySearch = exports.filterBySource = exports.filterByLevel = void 0;
|
|
8
|
+
exports.applyFilters = applyFilters;
|
|
9
|
+
const level_1 = require("./level");
|
|
10
|
+
const source_1 = require("./source");
|
|
11
|
+
const search_1 = require("./search");
|
|
12
|
+
function applyFilters(logs, filter) {
|
|
13
|
+
let filtered = logs;
|
|
14
|
+
// Filter by level
|
|
15
|
+
if (filter.levels && filter.levels.length > 0) {
|
|
16
|
+
filtered = (0, level_1.filterByLevel)(filtered, filter.levels);
|
|
17
|
+
}
|
|
18
|
+
// Filter by source
|
|
19
|
+
if (filter.sources && filter.sources.length > 0) {
|
|
20
|
+
filtered = (0, source_1.filterBySource)(filtered, filter.sources);
|
|
21
|
+
}
|
|
22
|
+
// Filter by tags
|
|
23
|
+
if (filter.tags && filter.tags.length > 0) {
|
|
24
|
+
filtered = filtered.filter(log => filter.tags.includes(log.tag));
|
|
25
|
+
}
|
|
26
|
+
// Filter by search query
|
|
27
|
+
if (filter.searchQuery) {
|
|
28
|
+
filtered = (0, search_1.filterBySearch)(filtered, filter.searchQuery);
|
|
29
|
+
}
|
|
30
|
+
// Filter by time range
|
|
31
|
+
if (filter.startTime) {
|
|
32
|
+
filtered = filtered.filter(log => log.timestamp >= filter.startTime);
|
|
33
|
+
}
|
|
34
|
+
if (filter.endTime) {
|
|
35
|
+
filtered = filtered.filter(log => log.timestamp <= filter.endTime);
|
|
36
|
+
}
|
|
37
|
+
return filtered;
|
|
38
|
+
}
|
|
39
|
+
var level_2 = require("./level");
|
|
40
|
+
Object.defineProperty(exports, "filterByLevel", { enumerable: true, get: function () { return level_2.filterByLevel; } });
|
|
41
|
+
var source_2 = require("./source");
|
|
42
|
+
Object.defineProperty(exports, "filterBySource", { enumerable: true, get: function () { return source_2.filterBySource; } });
|
|
43
|
+
var search_2 = require("./search");
|
|
44
|
+
Object.defineProperty(exports, "filterBySearch", { enumerable: true, get: function () { return search_2.filterBySearch; } });
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Level Filter
|
|
3
|
+
* Filter logs by severity level
|
|
4
|
+
*/
|
|
5
|
+
import { LogEntry, LogLevel } from '@jetstart/shared';
|
|
6
|
+
export declare function filterByLevel(logs: LogEntry[], levels: LogLevel[]): LogEntry[];
|
|
7
|
+
export declare function filterByMinLevel(logs: LogEntry[], minLevel: LogLevel): LogEntry[];
|
|
8
|
+
//# sourceMappingURL=level.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Level Filter
|
|
4
|
+
* Filter logs by severity level
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.filterByLevel = filterByLevel;
|
|
8
|
+
exports.filterByMinLevel = filterByMinLevel;
|
|
9
|
+
const shared_1 = require("@jetstart/shared");
|
|
10
|
+
const LEVEL_PRIORITY = {
|
|
11
|
+
[shared_1.LogLevel.VERBOSE]: 0,
|
|
12
|
+
[shared_1.LogLevel.DEBUG]: 1,
|
|
13
|
+
[shared_1.LogLevel.INFO]: 2,
|
|
14
|
+
[shared_1.LogLevel.WARN]: 3,
|
|
15
|
+
[shared_1.LogLevel.ERROR]: 4,
|
|
16
|
+
[shared_1.LogLevel.FATAL]: 5,
|
|
17
|
+
};
|
|
18
|
+
function filterByLevel(logs, levels) {
|
|
19
|
+
return logs.filter(log => levels.includes(log.level));
|
|
20
|
+
}
|
|
21
|
+
function filterByMinLevel(logs, minLevel) {
|
|
22
|
+
const minPriority = LEVEL_PRIORITY[minLevel];
|
|
23
|
+
return logs.filter(log => {
|
|
24
|
+
const logPriority = LEVEL_PRIORITY[log.level];
|
|
25
|
+
return logPriority >= minPriority;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=level.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Search Filter
|
|
4
|
+
* Filter logs by text search
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.filterBySearch = filterBySearch;
|
|
8
|
+
function filterBySearch(logs, query) {
|
|
9
|
+
const lowerQuery = query.toLowerCase();
|
|
10
|
+
return logs.filter(log => {
|
|
11
|
+
// Search in message
|
|
12
|
+
if (log.message.toLowerCase().includes(lowerQuery)) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
// Search in tag
|
|
16
|
+
if (log.tag.toLowerCase().includes(lowerQuery)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
// Search in metadata
|
|
20
|
+
if (log.metadata) {
|
|
21
|
+
const metadataStr = JSON.stringify(log.metadata).toLowerCase();
|
|
22
|
+
if (metadataStr.includes(lowerQuery)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source Filter
|
|
3
|
+
* Filter logs by source (CLI, Core, Client, etc.)
|
|
4
|
+
*/
|
|
5
|
+
import { LogEntry, LogSource } from '@jetstart/shared';
|
|
6
|
+
export declare function filterBySource(logs: LogEntry[], sources: LogSource[]): LogEntry[];
|
|
7
|
+
//# sourceMappingURL=source.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Source Filter
|
|
4
|
+
* Filter logs by source (CLI, Core, Client, etc.)
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.filterBySource = filterBySource;
|
|
8
|
+
function filterBySource(logs, sources) {
|
|
9
|
+
return logs.filter(log => sources.includes(log.source));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=source.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logs Package Entry Point
|
|
3
|
+
* Logging infrastructure for JetStart
|
|
4
|
+
*/
|
|
5
|
+
export * from './server';
|
|
6
|
+
export * from './cli';
|
|
7
|
+
export * from './filters';
|
|
8
|
+
export * from './types';
|
|
9
|
+
export * from './utils';
|
|
10
|
+
export type { LogEntry, LogLevel, LogSource, LogFilter, LogStats, } from '@jetstart/shared';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Logs Package Entry Point
|
|
4
|
+
* Logging infrastructure for JetStart
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
__exportStar(require("./server"), exports);
|
|
22
|
+
__exportStar(require("./cli"), exports);
|
|
23
|
+
__exportStar(require("./filters"), exports);
|
|
24
|
+
__exportStar(require("./types"), exports);
|
|
25
|
+
__exportStar(require("./utils"), exports);
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logs Server
|
|
3
|
+
* WebSocket server for streaming logs
|
|
4
|
+
*/
|
|
5
|
+
import { LogEntry, LogFilter } from '@jetstart/shared';
|
|
6
|
+
export interface LogsServerConfig {
|
|
7
|
+
port?: number;
|
|
8
|
+
maxLogEntries?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class LogsServer {
|
|
11
|
+
private wss?;
|
|
12
|
+
private storage;
|
|
13
|
+
private clients;
|
|
14
|
+
private config;
|
|
15
|
+
constructor(config?: LogsServerConfig);
|
|
16
|
+
start(): Promise<void>;
|
|
17
|
+
stop(): Promise<void>;
|
|
18
|
+
addLog(entry: LogEntry): void;
|
|
19
|
+
getLogs(filter?: LogFilter): LogEntry[];
|
|
20
|
+
getStats(): any;
|
|
21
|
+
private handleMessage;
|
|
22
|
+
private handleSubscribe;
|
|
23
|
+
private broadcast;
|
|
24
|
+
private sendStats;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Logs Server
|
|
4
|
+
* WebSocket server for streaming logs
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.LogsServer = void 0;
|
|
11
|
+
const ws_1 = require("ws");
|
|
12
|
+
const storage_1 = require("./storage");
|
|
13
|
+
const shared_1 = require("@jetstart/shared");
|
|
14
|
+
const filters_1 = require("../filters");
|
|
15
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
16
|
+
class LogsServer {
|
|
17
|
+
wss;
|
|
18
|
+
storage;
|
|
19
|
+
clients = new Set();
|
|
20
|
+
config;
|
|
21
|
+
constructor(config = {}) {
|
|
22
|
+
this.config = {
|
|
23
|
+
port: config.port || shared_1.DEFAULT_LOGS_PORT,
|
|
24
|
+
maxLogEntries: config.maxLogEntries || 10000,
|
|
25
|
+
};
|
|
26
|
+
this.storage = new storage_1.LogStorage(this.config.maxLogEntries);
|
|
27
|
+
}
|
|
28
|
+
async start() {
|
|
29
|
+
this.wss = new ws_1.WebSocketServer({ port: this.config.port });
|
|
30
|
+
this.wss.on('connection', (ws) => {
|
|
31
|
+
console.log(chalk_1.default.green('✔'), 'Client connected to logs service');
|
|
32
|
+
this.clients.add(ws);
|
|
33
|
+
ws.on('message', (data) => {
|
|
34
|
+
this.handleMessage(ws, data);
|
|
35
|
+
});
|
|
36
|
+
ws.on('close', () => {
|
|
37
|
+
console.log(chalk_1.default.yellow('⚠'), 'Client disconnected from logs service');
|
|
38
|
+
this.clients.delete(ws);
|
|
39
|
+
});
|
|
40
|
+
ws.on('error', (err) => {
|
|
41
|
+
console.error(chalk_1.default.red('✖'), 'WebSocket error:', err.message);
|
|
42
|
+
this.clients.delete(ws);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
console.log(chalk_1.default.cyan('[Logs]'), `Server listening on port ${this.config.port}`);
|
|
46
|
+
}
|
|
47
|
+
async stop() {
|
|
48
|
+
if (this.wss) {
|
|
49
|
+
this.wss.close();
|
|
50
|
+
console.log(chalk_1.default.cyan('[Logs]'), 'Server stopped');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
addLog(entry) {
|
|
54
|
+
this.storage.add(entry);
|
|
55
|
+
this.broadcast(entry);
|
|
56
|
+
}
|
|
57
|
+
getLogs(filter) {
|
|
58
|
+
const logs = this.storage.getAll();
|
|
59
|
+
return filter ? (0, filters_1.applyFilters)(logs, filter) : logs;
|
|
60
|
+
}
|
|
61
|
+
getStats() {
|
|
62
|
+
return this.storage.getStats();
|
|
63
|
+
}
|
|
64
|
+
handleMessage(ws, data) {
|
|
65
|
+
try {
|
|
66
|
+
const message = JSON.parse(data.toString());
|
|
67
|
+
switch (message.type) {
|
|
68
|
+
case 'subscribe':
|
|
69
|
+
this.handleSubscribe(ws, message.filter, message.maxLines);
|
|
70
|
+
break;
|
|
71
|
+
case 'log':
|
|
72
|
+
this.addLog(message.log);
|
|
73
|
+
break;
|
|
74
|
+
case 'clear':
|
|
75
|
+
this.storage.clear();
|
|
76
|
+
break;
|
|
77
|
+
case 'stats':
|
|
78
|
+
this.sendStats(ws);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
console.error(chalk_1.default.red('✖'), 'Failed to parse message:', err.message);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
handleSubscribe(ws, filter, maxLines) {
|
|
87
|
+
const logs = this.getLogs(filter);
|
|
88
|
+
const recentLogs = maxLines ? logs.slice(-maxLines) : logs;
|
|
89
|
+
// Send existing logs
|
|
90
|
+
recentLogs.forEach(log => {
|
|
91
|
+
if (ws.readyState === ws_1.WebSocket.OPEN) {
|
|
92
|
+
ws.send(JSON.stringify(log));
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
broadcast(entry) {
|
|
97
|
+
const data = JSON.stringify(entry);
|
|
98
|
+
this.clients.forEach(ws => {
|
|
99
|
+
if (ws.readyState === ws_1.WebSocket.OPEN) {
|
|
100
|
+
try {
|
|
101
|
+
ws.send(data);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.error(chalk_1.default.red('✖'), 'Failed to broadcast log');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
sendStats(ws) {
|
|
110
|
+
if (ws.readyState === ws_1.WebSocket.OPEN) {
|
|
111
|
+
ws.send(JSON.stringify({
|
|
112
|
+
type: 'stats',
|
|
113
|
+
stats: this.storage.getStats(),
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.LogsServer = LogsServer;
|
|
119
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log Storage
|
|
3
|
+
* In-memory log storage with size limits
|
|
4
|
+
*/
|
|
5
|
+
import { LogEntry, LogStats } from '@jetstart/shared';
|
|
6
|
+
export declare class LogStorage {
|
|
7
|
+
private logs;
|
|
8
|
+
private maxEntries;
|
|
9
|
+
constructor(maxEntries?: number);
|
|
10
|
+
add(entry: LogEntry): void;
|
|
11
|
+
getAll(): LogEntry[];
|
|
12
|
+
clear(): void;
|
|
13
|
+
getStats(): LogStats;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=storage.d.ts.map
|