xray-manager 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/LICENSE +21 -0
- package/README.md +798 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +113 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/config.d.ts +49 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +295 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/interactive.d.ts +83 -0
- package/dist/commands/interactive.d.ts.map +1 -0
- package/dist/commands/interactive.js +362 -0
- package/dist/commands/interactive.js.map +1 -0
- package/dist/commands/logs.d.ts +43 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +257 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/service.d.ts +43 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +177 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/user.d.ts +43 -0
- package/dist/commands/user.d.ts.map +1 -0
- package/dist/commands/user.js +212 -0
- package/dist/commands/user.js.map +1 -0
- package/dist/constants/exit-codes.d.ts +49 -0
- package/dist/constants/exit-codes.d.ts.map +1 -0
- package/dist/constants/exit-codes.js +100 -0
- package/dist/constants/exit-codes.js.map +1 -0
- package/dist/constants/paths.d.ts +57 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +72 -0
- package/dist/constants/paths.js.map +1 -0
- package/dist/constants/timeouts.d.ts +84 -0
- package/dist/constants/timeouts.d.ts.map +1 -0
- package/dist/constants/timeouts.js +111 -0
- package/dist/constants/timeouts.js.map +1 -0
- package/dist/services/config-manager.d.ts +66 -0
- package/dist/services/config-manager.d.ts.map +1 -0
- package/dist/services/config-manager.js +206 -0
- package/dist/services/config-manager.js.map +1 -0
- package/dist/services/log-manager.d.ts +113 -0
- package/dist/services/log-manager.d.ts.map +1 -0
- package/dist/services/log-manager.js +288 -0
- package/dist/services/log-manager.js.map +1 -0
- package/dist/services/systemd-manager.d.ts +197 -0
- package/dist/services/systemd-manager.d.ts.map +1 -0
- package/dist/services/systemd-manager.js +458 -0
- package/dist/services/systemd-manager.js.map +1 -0
- package/dist/services/user-manager.d.ts +63 -0
- package/dist/services/user-manager.d.ts.map +1 -0
- package/dist/services/user-manager.js +219 -0
- package/dist/services/user-manager.js.map +1 -0
- package/dist/types/config.d.ts +256 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +7 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/service.d.ts +96 -0
- package/dist/types/service.d.ts.map +1 -0
- package/dist/types/service.js +7 -0
- package/dist/types/service.js.map +1 -0
- package/dist/types/user.d.ts +114 -0
- package/dist/types/user.d.ts.map +1 -0
- package/dist/types/user.js +7 -0
- package/dist/types/user.js.map +1 -0
- package/dist/utils/clipboard.d.ts +21 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +45 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/format.d.ts +93 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +242 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/logger.d.ts +113 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +260 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/preflight.d.ts +57 -0
- package/dist/utils/preflight.d.ts.map +1 -0
- package/dist/utils/preflight.js +215 -0
- package/dist/utils/preflight.js.map +1 -0
- package/dist/utils/validator.d.ts +102 -0
- package/dist/utils/validator.d.ts.map +1 -0
- package/dist/utils/validator.js +238 -0
- package/dist/utils/validator.js.map +1 -0
- package/dist/utils/which.d.ts +13 -0
- package/dist/utils/which.d.ts.map +1 -0
- package/dist/utils/which.js +28 -0
- package/dist/utils/which.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ConfigManager - Xray Configuration File Management
|
|
4
|
+
*
|
|
5
|
+
* Provides safe interface to read, write, validate, and backup Xray config
|
|
6
|
+
*
|
|
7
|
+
* @module services/config-manager
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ConfigManager = void 0;
|
|
11
|
+
const promises_1 = require("fs/promises");
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const paths_1 = require("../constants/paths");
|
|
15
|
+
/**
|
|
16
|
+
* ConfigManager - Safe configuration file operations
|
|
17
|
+
*/
|
|
18
|
+
class ConfigManager {
|
|
19
|
+
/**
|
|
20
|
+
* Create a new ConfigManager
|
|
21
|
+
*
|
|
22
|
+
* @param configPath - Path to config file (default: /usr/local/etc/xray/config.json)
|
|
23
|
+
*/
|
|
24
|
+
constructor(configPath) {
|
|
25
|
+
this.configPath = configPath || paths_1.DEFAULT_PATHS.CONFIG_FILE;
|
|
26
|
+
this.backupDir = paths_1.DEFAULT_PATHS.BACKUP_DIR || '/var/backups/xray';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read and parse config file
|
|
30
|
+
*
|
|
31
|
+
* @returns Parsed configuration object
|
|
32
|
+
*/
|
|
33
|
+
async readConfig() {
|
|
34
|
+
try {
|
|
35
|
+
const content = await (0, promises_1.readFile)(this.configPath, 'utf-8');
|
|
36
|
+
const config = JSON.parse(content);
|
|
37
|
+
return config;
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error.code === 'ENOENT') {
|
|
41
|
+
throw new Error(`配置文件不存在: ${this.configPath}`);
|
|
42
|
+
}
|
|
43
|
+
else if (error.code === 'EACCES') {
|
|
44
|
+
throw new Error(`配置文件无读取权限: ${this.configPath}。请使用 sudo 或以 root 用户运行。`);
|
|
45
|
+
}
|
|
46
|
+
else if (error instanceof SyntaxError) {
|
|
47
|
+
throw new Error(`配置文件 JSON 格式错误: ${error.message}`);
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Write config to file with secure permissions
|
|
54
|
+
*
|
|
55
|
+
* @param config - Configuration object to write
|
|
56
|
+
*/
|
|
57
|
+
async writeConfig(config) {
|
|
58
|
+
try {
|
|
59
|
+
// Validate config before writing
|
|
60
|
+
this.validateConfig(config);
|
|
61
|
+
// Ensure directory exists
|
|
62
|
+
const dir = (0, path_1.dirname)(this.configPath);
|
|
63
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
64
|
+
await (0, promises_1.mkdir)(dir, { recursive: true });
|
|
65
|
+
}
|
|
66
|
+
// Write with pretty formatting
|
|
67
|
+
const content = JSON.stringify(config, null, 2);
|
|
68
|
+
await (0, promises_1.writeFile)(this.configPath, content, 'utf-8');
|
|
69
|
+
// Set secure permissions (600 = rw-------)
|
|
70
|
+
await (0, promises_1.chmod)(this.configPath, 0o600);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (error.code === 'EACCES') {
|
|
74
|
+
throw new Error(`配置文件无写入权限: ${this.configPath}。请使用 sudo 或以 root 用户运行。`);
|
|
75
|
+
}
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Validate configuration structure
|
|
81
|
+
*
|
|
82
|
+
* @param config - Configuration to validate
|
|
83
|
+
* @throws Error if validation fails
|
|
84
|
+
*/
|
|
85
|
+
validateConfig(config) {
|
|
86
|
+
if (!config || typeof config !== 'object') {
|
|
87
|
+
throw new Error('配置必须是一个对象');
|
|
88
|
+
}
|
|
89
|
+
// Check for required top-level fields
|
|
90
|
+
if (!config.inbounds || !Array.isArray(config.inbounds)) {
|
|
91
|
+
throw new Error('配置必须包含 inbounds 数组');
|
|
92
|
+
}
|
|
93
|
+
if (!config.outbounds || !Array.isArray(config.outbounds)) {
|
|
94
|
+
throw new Error('配置必须包含 outbounds 数组');
|
|
95
|
+
}
|
|
96
|
+
// Validate inbounds
|
|
97
|
+
for (const inbound of config.inbounds) {
|
|
98
|
+
if (!inbound.protocol) {
|
|
99
|
+
throw new Error('每个 inbound 必须指定 protocol');
|
|
100
|
+
}
|
|
101
|
+
if (typeof inbound.port !== 'number') {
|
|
102
|
+
throw new Error('每个 inbound 必须指定有效的 port');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Validate outbounds
|
|
106
|
+
for (const outbound of config.outbounds) {
|
|
107
|
+
if (!outbound.protocol) {
|
|
108
|
+
throw new Error('每个 outbound 必须指定 protocol');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Backup configuration file
|
|
114
|
+
*
|
|
115
|
+
* @returns Path to backup file
|
|
116
|
+
*/
|
|
117
|
+
async backupConfig() {
|
|
118
|
+
try {
|
|
119
|
+
// Ensure backup directory exists
|
|
120
|
+
if (!(0, fs_1.existsSync)(this.backupDir)) {
|
|
121
|
+
await (0, promises_1.mkdir)(this.backupDir, { recursive: true, mode: 0o700 });
|
|
122
|
+
}
|
|
123
|
+
// Generate timestamp-based backup filename
|
|
124
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
125
|
+
const backupPath = (0, path_1.join)(this.backupDir, `config.${timestamp}.json`);
|
|
126
|
+
// Read current config
|
|
127
|
+
const config = await this.readConfig();
|
|
128
|
+
// Write backup
|
|
129
|
+
const content = JSON.stringify(config, null, 2);
|
|
130
|
+
await (0, promises_1.writeFile)(backupPath, content, 'utf-8');
|
|
131
|
+
await (0, promises_1.chmod)(backupPath, 0o600);
|
|
132
|
+
return backupPath;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
throw new Error(`备份配置失败: ${error.message}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* List available backups
|
|
140
|
+
*
|
|
141
|
+
* @returns Array of backup file paths
|
|
142
|
+
*/
|
|
143
|
+
async listBackups() {
|
|
144
|
+
try {
|
|
145
|
+
if (!(0, fs_1.existsSync)(this.backupDir)) {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
const files = await (0, promises_1.readdir)(this.backupDir);
|
|
149
|
+
const backups = files
|
|
150
|
+
.filter((file) => file.startsWith('config.') && file.endsWith('.json'))
|
|
151
|
+
.map((file) => (0, path_1.join)(this.backupDir, file))
|
|
152
|
+
.sort()
|
|
153
|
+
.reverse(); // Most recent first
|
|
154
|
+
return backups;
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
throw new Error(`列出备份失败: ${error.message}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Restore configuration from backup
|
|
162
|
+
*
|
|
163
|
+
* @param backupPath - Path to backup file
|
|
164
|
+
*/
|
|
165
|
+
async restoreConfig(backupPath) {
|
|
166
|
+
try {
|
|
167
|
+
// Verify backup file exists
|
|
168
|
+
await (0, promises_1.access)(backupPath);
|
|
169
|
+
// Backup current config first (pre-restore backup)
|
|
170
|
+
await this.backupConfig();
|
|
171
|
+
// Read backup content
|
|
172
|
+
const content = await (0, promises_1.readFile)(backupPath, 'utf-8');
|
|
173
|
+
const config = JSON.parse(content);
|
|
174
|
+
// Validate and write
|
|
175
|
+
await this.writeConfig(config);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
throw new Error(`恢复配置失败: ${error.message}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Modify a configuration item
|
|
183
|
+
*
|
|
184
|
+
* @param path - Dot-separated path to config item (e.g., "log.loglevel")
|
|
185
|
+
* @param value - New value
|
|
186
|
+
*/
|
|
187
|
+
async modifyConfigItem(path, value) {
|
|
188
|
+
const config = await this.readConfig();
|
|
189
|
+
// Split path and navigate to parent object
|
|
190
|
+
const parts = path.split('.');
|
|
191
|
+
let current = config;
|
|
192
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
193
|
+
if (!current[parts[i]]) {
|
|
194
|
+
current[parts[i]] = {};
|
|
195
|
+
}
|
|
196
|
+
current = current[parts[i]];
|
|
197
|
+
}
|
|
198
|
+
// Set value
|
|
199
|
+
const lastPart = parts[parts.length - 1];
|
|
200
|
+
current[lastPart] = value;
|
|
201
|
+
// Validate and write
|
|
202
|
+
await this.writeConfig(config);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
exports.ConfigManager = ConfigManager;
|
|
206
|
+
//# sourceMappingURL=config-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/services/config-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LogManager - System Log Management via journalctl
|
|
3
|
+
*
|
|
4
|
+
* Provides safe interface to query and follow systemd journal logs
|
|
5
|
+
*
|
|
6
|
+
* @module services/log-manager
|
|
7
|
+
*/
|
|
8
|
+
import { ChildProcess } from 'child_process';
|
|
9
|
+
/**
|
|
10
|
+
* Log entry structure
|
|
11
|
+
*/
|
|
12
|
+
export interface LogEntry {
|
|
13
|
+
/** Log timestamp */
|
|
14
|
+
timestamp: Date;
|
|
15
|
+
/** Log message */
|
|
16
|
+
message: string;
|
|
17
|
+
/** Log level */
|
|
18
|
+
level: string;
|
|
19
|
+
/** Process ID */
|
|
20
|
+
pid?: string;
|
|
21
|
+
/** Hostname */
|
|
22
|
+
hostname?: string;
|
|
23
|
+
/** Systemd unit */
|
|
24
|
+
unit?: string;
|
|
25
|
+
/** Raw log data */
|
|
26
|
+
raw?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Log query options
|
|
30
|
+
*/
|
|
31
|
+
export interface LogQueryOptions {
|
|
32
|
+
/** Filter by log level (error, warning, info, debug) */
|
|
33
|
+
level?: string;
|
|
34
|
+
/** Time range start (e.g., "1 hour ago", "today", "2024-01-01") */
|
|
35
|
+
since?: string;
|
|
36
|
+
/** Time range end */
|
|
37
|
+
until?: string;
|
|
38
|
+
/** Number of lines to retrieve */
|
|
39
|
+
lines?: number;
|
|
40
|
+
/** Follow mode (real-time) */
|
|
41
|
+
follow?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Log follow process
|
|
45
|
+
*/
|
|
46
|
+
export interface LogFollowProcess {
|
|
47
|
+
/** Kill the follow process */
|
|
48
|
+
kill: () => void;
|
|
49
|
+
/** Child process */
|
|
50
|
+
process: ChildProcess;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* LogManager - Query and follow systemd journal logs
|
|
54
|
+
*/
|
|
55
|
+
export declare class LogManager {
|
|
56
|
+
private serviceName;
|
|
57
|
+
/**
|
|
58
|
+
* Create a new LogManager
|
|
59
|
+
*
|
|
60
|
+
* @param serviceName - Service name to query logs for
|
|
61
|
+
*/
|
|
62
|
+
constructor(serviceName: string);
|
|
63
|
+
/**
|
|
64
|
+
* Validate service name to prevent command injection
|
|
65
|
+
*
|
|
66
|
+
* @param name - Service name to validate
|
|
67
|
+
* @throws Error if invalid
|
|
68
|
+
*/
|
|
69
|
+
private validateServiceName;
|
|
70
|
+
/**
|
|
71
|
+
* Check if journalctl is available
|
|
72
|
+
*
|
|
73
|
+
* @returns True if journalctl is available
|
|
74
|
+
*/
|
|
75
|
+
isJournalctlAvailable(): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Map log level to journalctl priority
|
|
78
|
+
*
|
|
79
|
+
* @param level - Log level (error, warning, info, debug)
|
|
80
|
+
* @returns journalctl priority string
|
|
81
|
+
*/
|
|
82
|
+
private mapLevelToPriority;
|
|
83
|
+
/**
|
|
84
|
+
* Map journalctl priority to readable level
|
|
85
|
+
*
|
|
86
|
+
* @param priority - Journalctl priority (0-7)
|
|
87
|
+
* @returns Readable log level
|
|
88
|
+
*/
|
|
89
|
+
private mapPriorityToLevel;
|
|
90
|
+
/**
|
|
91
|
+
* Parse a JSON log entry from journalctl
|
|
92
|
+
*
|
|
93
|
+
* @param jsonLine - JSON string from journalctl -o json
|
|
94
|
+
* @returns Parsed log entry
|
|
95
|
+
*/
|
|
96
|
+
parseLogEntry(jsonLine: string): LogEntry;
|
|
97
|
+
/**
|
|
98
|
+
* Query logs with filters
|
|
99
|
+
*
|
|
100
|
+
* @param options - Query options
|
|
101
|
+
* @returns Array of log entries
|
|
102
|
+
*/
|
|
103
|
+
queryLogs(options?: LogQueryOptions): Promise<LogEntry[]>;
|
|
104
|
+
/**
|
|
105
|
+
* Follow logs in real-time
|
|
106
|
+
*
|
|
107
|
+
* @param options - Query options
|
|
108
|
+
* @param onLog - Callback for each log entry
|
|
109
|
+
* @returns Follow process controller
|
|
110
|
+
*/
|
|
111
|
+
followLogs(options?: LogQueryOptions, onLog?: (entry: LogEntry) => void): Promise<LogFollowProcess>;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=log-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-manager.d.ts","sourceRoot":"","sources":["../../src/services/log-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAS,YAAY,EAAE,MAAM,eAAe,CAAC;AAIpD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,oBAAoB;IACpB,SAAS,EAAE,IAAI,CAAC;IAEhB,kBAAkB;IAClB,OAAO,EAAE,MAAM,CAAC;IAEhB,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IAEd,iBAAiB;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,mBAAmB;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,8BAA8B;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,IAAI,CAAC;IAEjB,oBAAoB;IACpB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,WAAW,CAAS;IAE5B;;;;OAIG;gBACS,WAAW,EAAE,MAAM;IAK/B;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAuB3B;;;;OAIG;IACH,qBAAqB,IAAI,OAAO;IAShC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;;;;OAKG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ;IAkCzC;;;;;OAKG;IACG,SAAS,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IA4FnE;;;;;;OAMG;IACG,UAAU,CACd,OAAO,GAAE,eAAoB,EAC7B,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC;CAuE7B"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LogManager - System Log Management via journalctl
|
|
4
|
+
*
|
|
5
|
+
* Provides safe interface to query and follow systemd journal logs
|
|
6
|
+
*
|
|
7
|
+
* @module services/log-manager
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.LogManager = void 0;
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const which_1 = require("../utils/which");
|
|
14
|
+
/**
|
|
15
|
+
* LogManager - Query and follow systemd journal logs
|
|
16
|
+
*/
|
|
17
|
+
class LogManager {
|
|
18
|
+
/**
|
|
19
|
+
* Create a new LogManager
|
|
20
|
+
*
|
|
21
|
+
* @param serviceName - Service name to query logs for
|
|
22
|
+
*/
|
|
23
|
+
constructor(serviceName) {
|
|
24
|
+
this.validateServiceName(serviceName);
|
|
25
|
+
this.serviceName = serviceName;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Validate service name to prevent command injection
|
|
29
|
+
*
|
|
30
|
+
* @param name - Service name to validate
|
|
31
|
+
* @throws Error if invalid
|
|
32
|
+
*/
|
|
33
|
+
validateServiceName(name) {
|
|
34
|
+
if (!name || name.trim().length === 0) {
|
|
35
|
+
throw new Error('Service name cannot be empty');
|
|
36
|
+
}
|
|
37
|
+
// Prevent path traversal
|
|
38
|
+
if (name.includes('/') || name.includes('\\') || name.includes('..')) {
|
|
39
|
+
throw new Error(`Invalid service name: ${name} (path traversal detected)`);
|
|
40
|
+
}
|
|
41
|
+
// Prevent command injection
|
|
42
|
+
const dangerousChars = /[;&|`$()]/;
|
|
43
|
+
if (dangerousChars.test(name)) {
|
|
44
|
+
throw new Error(`Invalid service name: ${name} (potentially dangerous characters detected)`);
|
|
45
|
+
}
|
|
46
|
+
// Only allow alphanumeric, dash, underscore, and dot
|
|
47
|
+
const validPattern = /^[a-zA-Z0-9_.-]+$/;
|
|
48
|
+
if (!validPattern.test(name)) {
|
|
49
|
+
throw new Error(`Invalid service name: ${name}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if journalctl is available
|
|
54
|
+
*
|
|
55
|
+
* @returns True if journalctl is available
|
|
56
|
+
*/
|
|
57
|
+
isJournalctlAvailable() {
|
|
58
|
+
try {
|
|
59
|
+
const journalctlPath = (0, which_1.which)('journalctl');
|
|
60
|
+
return journalctlPath !== null && (0, fs_1.existsSync)(journalctlPath);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Map log level to journalctl priority
|
|
68
|
+
*
|
|
69
|
+
* @param level - Log level (error, warning, info, debug)
|
|
70
|
+
* @returns journalctl priority string
|
|
71
|
+
*/
|
|
72
|
+
mapLevelToPriority(level) {
|
|
73
|
+
const mapping = {
|
|
74
|
+
emergency: 'emerg',
|
|
75
|
+
alert: 'alert',
|
|
76
|
+
critical: 'crit',
|
|
77
|
+
error: 'err',
|
|
78
|
+
warning: 'warning',
|
|
79
|
+
notice: 'notice',
|
|
80
|
+
info: 'info',
|
|
81
|
+
debug: 'debug',
|
|
82
|
+
};
|
|
83
|
+
return mapping[level.toLowerCase()] || level;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Map journalctl priority to readable level
|
|
87
|
+
*
|
|
88
|
+
* @param priority - Journalctl priority (0-7)
|
|
89
|
+
* @returns Readable log level
|
|
90
|
+
*/
|
|
91
|
+
mapPriorityToLevel(priority) {
|
|
92
|
+
const mapping = {
|
|
93
|
+
'0': 'emergency',
|
|
94
|
+
'1': 'alert',
|
|
95
|
+
'2': 'critical',
|
|
96
|
+
'3': 'error',
|
|
97
|
+
'4': 'warning',
|
|
98
|
+
'5': 'notice',
|
|
99
|
+
'6': 'info',
|
|
100
|
+
'7': 'debug',
|
|
101
|
+
};
|
|
102
|
+
return mapping[priority] || 'unknown';
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Parse a JSON log entry from journalctl
|
|
106
|
+
*
|
|
107
|
+
* @param jsonLine - JSON string from journalctl -o json
|
|
108
|
+
* @returns Parsed log entry
|
|
109
|
+
*/
|
|
110
|
+
parseLogEntry(jsonLine) {
|
|
111
|
+
try {
|
|
112
|
+
const data = JSON.parse(jsonLine);
|
|
113
|
+
// Extract timestamp (microseconds since epoch)
|
|
114
|
+
const timestampMicros = parseInt(data.__REALTIME_TIMESTAMP || '0', 10);
|
|
115
|
+
const timestamp = new Date(timestampMicros / 1000);
|
|
116
|
+
// Extract message
|
|
117
|
+
const message = data.MESSAGE || '';
|
|
118
|
+
// Extract and map priority
|
|
119
|
+
const priority = data.PRIORITY || '6';
|
|
120
|
+
const level = this.mapPriorityToLevel(priority);
|
|
121
|
+
// Extract metadata
|
|
122
|
+
const pid = data._PID;
|
|
123
|
+
const hostname = data._HOSTNAME;
|
|
124
|
+
const unit = data._SYSTEMD_UNIT;
|
|
125
|
+
return {
|
|
126
|
+
timestamp,
|
|
127
|
+
message,
|
|
128
|
+
level,
|
|
129
|
+
pid,
|
|
130
|
+
hostname,
|
|
131
|
+
unit,
|
|
132
|
+
raw: jsonLine,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
throw new Error(`Failed to parse log entry: ${error.message}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Query logs with filters
|
|
141
|
+
*
|
|
142
|
+
* @param options - Query options
|
|
143
|
+
* @returns Array of log entries
|
|
144
|
+
*/
|
|
145
|
+
async queryLogs(options = {}) {
|
|
146
|
+
if (!this.isJournalctlAvailable()) {
|
|
147
|
+
throw new Error('journalctl is not available on this system. Please ensure systemd is installed.');
|
|
148
|
+
}
|
|
149
|
+
// Build journalctl arguments
|
|
150
|
+
const args = [
|
|
151
|
+
'-u',
|
|
152
|
+
this.serviceName, // Unit filter
|
|
153
|
+
'-o',
|
|
154
|
+
'json', // JSON output
|
|
155
|
+
'--no-pager', // Disable pager
|
|
156
|
+
];
|
|
157
|
+
// Add level filter
|
|
158
|
+
if (options.level) {
|
|
159
|
+
const priority = this.mapLevelToPriority(options.level);
|
|
160
|
+
args.push('-p', priority);
|
|
161
|
+
}
|
|
162
|
+
// Add time range filters
|
|
163
|
+
if (options.since) {
|
|
164
|
+
args.push('--since', options.since);
|
|
165
|
+
}
|
|
166
|
+
if (options.until) {
|
|
167
|
+
args.push('--until', options.until);
|
|
168
|
+
}
|
|
169
|
+
// Add line limit
|
|
170
|
+
if (options.lines) {
|
|
171
|
+
args.push('-n', String(options.lines));
|
|
172
|
+
}
|
|
173
|
+
return new Promise((resolve, reject) => {
|
|
174
|
+
const child = (0, child_process_1.spawn)('journalctl', args, {
|
|
175
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
176
|
+
});
|
|
177
|
+
let stdout = '';
|
|
178
|
+
let stderr = '';
|
|
179
|
+
child.stdout.on('data', (data) => {
|
|
180
|
+
stdout += data.toString();
|
|
181
|
+
});
|
|
182
|
+
child.stderr.on('data', (data) => {
|
|
183
|
+
stderr += data.toString();
|
|
184
|
+
});
|
|
185
|
+
child.on('close', (code) => {
|
|
186
|
+
if (code !== 0) {
|
|
187
|
+
const errorMsg = stderr.trim() || `journalctl exited with code ${code}`;
|
|
188
|
+
// Provide helpful error messages
|
|
189
|
+
if (errorMsg.includes('permission') || errorMsg.includes('access')) {
|
|
190
|
+
reject(new Error(`无权访问日志。请使用 sudo 或以 root 用户运行。\n详细错误: ${errorMsg}`));
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
reject(new Error(`查询日志失败: ${errorMsg}`));
|
|
194
|
+
}
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
// Parse log entries
|
|
198
|
+
const logs = [];
|
|
199
|
+
const lines = stdout.trim().split('\n');
|
|
200
|
+
for (const line of lines) {
|
|
201
|
+
if (!line.trim())
|
|
202
|
+
continue;
|
|
203
|
+
try {
|
|
204
|
+
const entry = this.parseLogEntry(line);
|
|
205
|
+
logs.push(entry);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
// Skip malformed entries
|
|
209
|
+
console.warn(`Skipped malformed log entry: ${error.message}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
resolve(logs);
|
|
213
|
+
});
|
|
214
|
+
child.on('error', (error) => {
|
|
215
|
+
reject(new Error(`Failed to execute journalctl: ${error.message}`));
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Follow logs in real-time
|
|
221
|
+
*
|
|
222
|
+
* @param options - Query options
|
|
223
|
+
* @param onLog - Callback for each log entry
|
|
224
|
+
* @returns Follow process controller
|
|
225
|
+
*/
|
|
226
|
+
async followLogs(options = {}, onLog) {
|
|
227
|
+
if (!this.isJournalctlAvailable()) {
|
|
228
|
+
throw new Error('journalctl is not available on this system. Please ensure systemd is installed.');
|
|
229
|
+
}
|
|
230
|
+
// Build journalctl arguments
|
|
231
|
+
const args = [
|
|
232
|
+
'-u',
|
|
233
|
+
this.serviceName,
|
|
234
|
+
'-o',
|
|
235
|
+
'json',
|
|
236
|
+
'--no-pager',
|
|
237
|
+
'-f', // Follow mode
|
|
238
|
+
];
|
|
239
|
+
// Add level filter
|
|
240
|
+
if (options.level) {
|
|
241
|
+
const priority = this.mapLevelToPriority(options.level);
|
|
242
|
+
args.push('-p', priority);
|
|
243
|
+
}
|
|
244
|
+
// Add line limit for initial output
|
|
245
|
+
if (options.lines) {
|
|
246
|
+
args.push('-n', String(options.lines));
|
|
247
|
+
}
|
|
248
|
+
const child = (0, child_process_1.spawn)('journalctl', args, {
|
|
249
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
250
|
+
});
|
|
251
|
+
// Handle stdout
|
|
252
|
+
if (onLog) {
|
|
253
|
+
let buffer = '';
|
|
254
|
+
child.stdout.on('data', (data) => {
|
|
255
|
+
buffer += data.toString();
|
|
256
|
+
const lines = buffer.split('\n');
|
|
257
|
+
// Process complete lines
|
|
258
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
259
|
+
const line = lines[i].trim();
|
|
260
|
+
if (!line)
|
|
261
|
+
continue;
|
|
262
|
+
try {
|
|
263
|
+
const entry = this.parseLogEntry(line);
|
|
264
|
+
onLog(entry);
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
console.warn(`Skipped malformed log entry: ${error.message}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Keep incomplete line in buffer
|
|
271
|
+
buffer = lines[lines.length - 1];
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
// Handle stderr
|
|
275
|
+
child.stderr.on('data', (data) => {
|
|
276
|
+
const errorMsg = data.toString();
|
|
277
|
+
console.error(`journalctl error: ${errorMsg}`);
|
|
278
|
+
});
|
|
279
|
+
return {
|
|
280
|
+
process: child,
|
|
281
|
+
kill: () => {
|
|
282
|
+
child.kill('SIGINT');
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
exports.LogManager = LogManager;
|
|
288
|
+
//# sourceMappingURL=log-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-manager.js","sourceRoot":"","sources":["../../src/services/log-manager.ts"],"names":[],"mappings":"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"}
|