@archznn/xavva 3.1.2 → 3.2.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 +221 -12
- package/package.json +3 -2
- package/src/commands/AuditCommand.ts +12 -10
- package/src/commands/BuildCommand.ts +9 -7
- package/src/commands/ChangelogCommand.ts +5 -5
- package/src/commands/CleanCommand.ts +242 -0
- package/src/commands/CompletionCommand.ts +7 -7
- package/src/commands/DbCommand.ts +43 -14
- package/src/commands/DeployCommand.ts +252 -229
- package/src/commands/DepsCommand.ts +174 -174
- package/src/commands/DockerCommand.ts +35 -4
- package/src/commands/DoctorCommand.ts +252 -239
- package/src/commands/EncodingCommand.ts +26 -19
- package/src/commands/HealthCommand.ts +7 -7
- package/src/commands/HelpCommand.ts +34 -14
- package/src/commands/HistoryCommand.ts +5 -5
- package/src/commands/HttpCommand.ts +27 -1
- package/src/commands/IdeCommand.ts +313 -0
- package/src/commands/InitCommand.ts +26 -25
- package/src/commands/LogsCommand.ts +8 -6
- package/src/commands/ProfilesCommand.ts +6 -6
- package/src/commands/RedoCommand.ts +2 -2
- package/src/commands/RunCommand.ts +64 -24
- package/src/commands/StartCommand.ts +9 -7
- package/src/commands/TestCommand.ts +25 -1
- package/src/commands/TomcatCommand.ts +232 -88
- package/src/config/versions.ts +111 -9
- package/src/di/container.ts +239 -105
- package/src/errors/ErrorHandler.ts +23 -19
- package/src/errors/errorMessages.ts +235 -0
- package/src/index.ts +20 -6
- package/src/logging/FileLogger.ts +235 -0
- package/src/logging/Logger.ts +545 -0
- package/src/logging/OperationLogger.ts +296 -0
- package/src/logging/ProgressLogger.ts +187 -0
- package/src/logging/TableLogger.ts +246 -0
- package/src/logging/colors.ts +167 -0
- package/src/logging/constants.ts +176 -0
- package/src/logging/formatters.ts +337 -0
- package/src/logging/index.ts +93 -0
- package/src/logging/types.ts +64 -0
- package/src/plugins/PluginManager.ts +325 -0
- package/src/plugins/types.ts +82 -0
- package/src/services/AuditService.ts +5 -3
- package/src/services/BuildService.ts +15 -17
- package/src/services/DashboardService.ts +14 -3
- package/src/services/DbService.ts +35 -34
- package/src/services/DependencyAnalyzerService.ts +18 -18
- package/src/services/DependencyCacheService.ts +303 -0
- package/src/services/DeployWatcher.ts +127 -23
- package/src/services/DockerService.ts +3 -3
- package/src/services/EmbeddedTomcatService.ts +13 -12
- package/src/services/FileWatcher.ts +15 -7
- package/src/services/HttpService.ts +5 -5
- package/src/services/LogAnalyzer.ts +26 -22
- package/src/services/PerformanceProfiler.ts +267 -0
- package/src/services/ProjectService.ts +3 -0
- package/src/services/TestService.ts +3 -3
- package/src/services/TomcatService.ts +46 -25
- package/src/services/tomcat/TomcatBackupManager.ts +330 -0
- package/src/services/tomcat/TomcatChecksumVerifier.ts +211 -0
- package/src/services/tomcat/TomcatCompatibilityChecker.ts +298 -0
- package/src/services/tomcat/TomcatDownloadCache.ts +250 -0
- package/src/services/tomcat/TomcatDownloadService.ts +335 -0
- package/src/services/tomcat/TomcatInstallerService.ts +474 -0
- package/src/services/tomcat/TomcatMirrorManager.ts +181 -0
- package/src/services/tomcat/index.ts +36 -0
- package/src/services/tomcat/types.ts +120 -0
- package/src/types/args.ts +68 -1
- package/src/types/configSchema.ts +174 -0
- package/src/utils/ChangelogGenerator.ts +11 -11
- package/src/utils/LoggerLevel.ts +44 -20
- package/src/utils/ProgressBar.ts +87 -46
- package/src/utils/argsParser.ts +260 -0
- package/src/utils/config.ts +340 -189
- package/src/utils/constants.ts +87 -9
- package/src/utils/dryRun.ts +192 -0
- package/src/utils/processManager.ts +23 -7
- package/src/utils/security.ts +293 -0
- package/src/utils/ui.ts +299 -428
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profiler de Performance
|
|
3
|
+
*
|
|
4
|
+
* Mede tempo de execução de operações e gera relatórios
|
|
5
|
+
* Uso: xavva build --profile ou xavva deploy --profile
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Logger } from "../logging";
|
|
9
|
+
|
|
10
|
+
interface PhaseTiming {
|
|
11
|
+
phase: string;
|
|
12
|
+
startTime: number;
|
|
13
|
+
endTime?: number;
|
|
14
|
+
duration?: number;
|
|
15
|
+
parent?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ProfilerConfig {
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
verbose: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class PerformanceProfiler {
|
|
24
|
+
private timings: Map<string, PhaseTiming> = new Map();
|
|
25
|
+
private completedTimings: PhaseTiming[] = [];
|
|
26
|
+
private stack: string[] = [];
|
|
27
|
+
private config: ProfilerConfig;
|
|
28
|
+
private logger = Logger.getInstance();
|
|
29
|
+
private globalStart: number = 0;
|
|
30
|
+
|
|
31
|
+
constructor(config: Partial<ProfilerConfig> = {}) {
|
|
32
|
+
this.config = {
|
|
33
|
+
enabled: true,
|
|
34
|
+
verbose: false,
|
|
35
|
+
...config,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Inicia profiling global
|
|
41
|
+
*/
|
|
42
|
+
start(): void {
|
|
43
|
+
if (!this.config.enabled) return;
|
|
44
|
+
this.globalStart = performance.now();
|
|
45
|
+
this.timings.clear();
|
|
46
|
+
this.completedTimings = [];
|
|
47
|
+
this.stack = [];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Inicia uma fase
|
|
52
|
+
*/
|
|
53
|
+
startPhase(phase: string): void {
|
|
54
|
+
if (!this.config.enabled) return;
|
|
55
|
+
|
|
56
|
+
const parent = this.stack.length > 0 ? this.stack[this.stack.length - 1] : undefined;
|
|
57
|
+
|
|
58
|
+
const timing: PhaseTiming = {
|
|
59
|
+
phase,
|
|
60
|
+
startTime: performance.now(),
|
|
61
|
+
parent,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
this.timings.set(phase, timing);
|
|
65
|
+
this.stack.push(phase);
|
|
66
|
+
|
|
67
|
+
if (this.config.verbose) {
|
|
68
|
+
this.logger.debug(`[Profiler] Iniciando: ${phase}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Finaliza uma fase
|
|
74
|
+
*/
|
|
75
|
+
endPhase(phase?: string): void {
|
|
76
|
+
if (!this.config.enabled) return;
|
|
77
|
+
|
|
78
|
+
const phaseName = phase || this.stack.pop();
|
|
79
|
+
if (!phaseName) return;
|
|
80
|
+
|
|
81
|
+
const timing = this.timings.get(phaseName);
|
|
82
|
+
if (!timing) return;
|
|
83
|
+
|
|
84
|
+
timing.endTime = performance.now();
|
|
85
|
+
timing.duration = timing.endTime - timing.startTime;
|
|
86
|
+
|
|
87
|
+
this.completedTimings.push({ ...timing });
|
|
88
|
+
this.timings.delete(phaseName);
|
|
89
|
+
|
|
90
|
+
if (this.config.verbose) {
|
|
91
|
+
this.logger.debug(`[Profiler] Finalizado: ${phaseName} (${timing.duration.toFixed(2)}ms)`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Executa função dentro de uma fase
|
|
97
|
+
*/
|
|
98
|
+
async withPhase<T>(phase: string, fn: () => Promise<T>): Promise<T> {
|
|
99
|
+
this.startPhase(phase);
|
|
100
|
+
try {
|
|
101
|
+
return await fn();
|
|
102
|
+
} finally {
|
|
103
|
+
this.endPhase(phase);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Executa função síncrona dentro de uma fase
|
|
109
|
+
*/
|
|
110
|
+
withPhaseSync<T>(phase: string, fn: () => T): T {
|
|
111
|
+
this.startPhase(phase);
|
|
112
|
+
try {
|
|
113
|
+
return fn();
|
|
114
|
+
} finally {
|
|
115
|
+
this.endPhase(phase);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Gera relatório de performance
|
|
121
|
+
*/
|
|
122
|
+
generateReport(): void {
|
|
123
|
+
if (!this.config.enabled) return;
|
|
124
|
+
|
|
125
|
+
const totalTime = performance.now() - this.globalStart;
|
|
126
|
+
|
|
127
|
+
this.logger.newline();
|
|
128
|
+
this.logger.section("📊 Profile de Performance");
|
|
129
|
+
|
|
130
|
+
// Ordena por duração (decrescente)
|
|
131
|
+
const sorted = [...this.completedTimings].sort((a, b) =>
|
|
132
|
+
(b.duration || 0) - (a.duration || 0)
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// Agrupa por nível
|
|
136
|
+
const rootPhases = sorted.filter(t => !t.parent);
|
|
137
|
+
|
|
138
|
+
for (const phase of rootPhases) {
|
|
139
|
+
this.printPhase(phase, sorted, 0, totalTime);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Linha de total
|
|
143
|
+
this.logger.divider();
|
|
144
|
+
this.printTimingLine("TOTAL", totalTime, totalTime, 0, true);
|
|
145
|
+
|
|
146
|
+
// Estatísticas
|
|
147
|
+
this.printStats();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private printPhase(phase: PhaseTiming, all: PhaseTiming[], level: number, total: number): void {
|
|
151
|
+
this.printTimingLine(phase.phase, phase.duration || 0, total, level);
|
|
152
|
+
|
|
153
|
+
// Filhos
|
|
154
|
+
const children = all.filter(t => t.parent === phase.phase);
|
|
155
|
+
for (const child of children) {
|
|
156
|
+
this.printPhase(child, all, level + 1, total);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private printTimingLine(name: string, duration: number, total: number, level: number, isTotal = false): void {
|
|
161
|
+
const indent = " ".repeat(level);
|
|
162
|
+
const percent = total > 0 ? (duration / total) * 100 : 0;
|
|
163
|
+
const bar = this.renderBar(percent);
|
|
164
|
+
|
|
165
|
+
const timeStr = this.formatDuration(duration);
|
|
166
|
+
const percentStr = percent.toFixed(1).padStart(5);
|
|
167
|
+
|
|
168
|
+
const nameFormatted = isTotal
|
|
169
|
+
? `${name}`
|
|
170
|
+
: `${indent}${name}`;
|
|
171
|
+
|
|
172
|
+
this.logger.info(`${nameFormatted.padEnd(25)} ${timeStr.padStart(10)} ${bar} ${percentStr}%`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private renderBar(percent: number): string {
|
|
176
|
+
const width = 20;
|
|
177
|
+
const filled = Math.round((percent / 100) * width);
|
|
178
|
+
const empty = width - filled;
|
|
179
|
+
|
|
180
|
+
const bar = "█".repeat(filled) + "░".repeat(empty);
|
|
181
|
+
return `[${bar}]`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private formatDuration(ms: number): string {
|
|
185
|
+
if (ms < 1000) {
|
|
186
|
+
return `${ms.toFixed(0)}ms`;
|
|
187
|
+
} else if (ms < 60000) {
|
|
188
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
189
|
+
} else {
|
|
190
|
+
const mins = Math.floor(ms / 60000);
|
|
191
|
+
const secs = ((ms % 60000) / 1000).toFixed(1);
|
|
192
|
+
return `${mins}m ${secs}s`;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private printStats(): void {
|
|
197
|
+
const times = this.completedTimings.map(t => t.duration || 0);
|
|
198
|
+
|
|
199
|
+
if (times.length === 0) return;
|
|
200
|
+
|
|
201
|
+
const avg = times.reduce((a, b) => a + b, 0) / times.length;
|
|
202
|
+
const max = Math.max(...times);
|
|
203
|
+
const min = Math.min(...times);
|
|
204
|
+
|
|
205
|
+
this.logger.newline();
|
|
206
|
+
this.logger.info("📈 Estatísticas:");
|
|
207
|
+
this.logger.info(` Fases: ${times.length}`);
|
|
208
|
+
this.logger.info(` Média: ${this.formatDuration(avg)}`);
|
|
209
|
+
this.logger.info(` Mín: ${this.formatDuration(min)}`);
|
|
210
|
+
this.logger.info(` Máx: ${this.formatDuration(max)}`);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Exporta dados para JSON
|
|
215
|
+
*/
|
|
216
|
+
exportJSON(): object {
|
|
217
|
+
const totalTime = performance.now() - this.globalStart;
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
totalTime,
|
|
221
|
+
phases: this.completedTimings.map(t => ({
|
|
222
|
+
phase: t.phase,
|
|
223
|
+
duration: t.duration,
|
|
224
|
+
parent: t.parent,
|
|
225
|
+
})),
|
|
226
|
+
timestamp: new Date().toISOString(),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Limpa dados
|
|
232
|
+
*/
|
|
233
|
+
reset(): void {
|
|
234
|
+
this.timings.clear();
|
|
235
|
+
this.completedTimings = [];
|
|
236
|
+
this.stack = [];
|
|
237
|
+
this.globalStart = 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Verifica se profiling está ativo
|
|
242
|
+
*/
|
|
243
|
+
isEnabled(): boolean {
|
|
244
|
+
return this.config.enabled;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Ativa/desativa profiling
|
|
249
|
+
*/
|
|
250
|
+
setEnabled(enabled: boolean): void {
|
|
251
|
+
this.config.enabled = enabled;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Singleton global
|
|
256
|
+
let globalProfiler: PerformanceProfiler | null = null;
|
|
257
|
+
|
|
258
|
+
export function getProfiler(config?: Partial<ProfilerConfig>): PerformanceProfiler {
|
|
259
|
+
if (!globalProfiler) {
|
|
260
|
+
globalProfiler = new PerformanceProfiler(config);
|
|
261
|
+
}
|
|
262
|
+
return globalProfiler;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function resetProfiler(): void {
|
|
266
|
+
globalProfiler = null;
|
|
267
|
+
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { existsSync, readdirSync, statSync, readFileSync } from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import type { ProjectConfig } from "../types/config";
|
|
4
|
+
import { Logger } from "../logging";
|
|
4
5
|
|
|
5
6
|
export class ProjectService {
|
|
7
|
+
private logger = Logger.getInstance();
|
|
8
|
+
|
|
6
9
|
constructor(private config: ProjectConfig) {}
|
|
7
10
|
|
|
8
11
|
getBuildOutputDir(): string {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Suporta Maven e Gradle com modo watch
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { Logger } from "../utils/ui";
|
|
6
|
+
import { Logger, C } from "../utils/ui";
|
|
7
7
|
import { spawn } from "child_process";
|
|
8
8
|
import { watch, type FSWatcher } from "fs";
|
|
9
9
|
import path from "path";
|
|
@@ -287,8 +287,8 @@ export class TestService {
|
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
Logger.info("Total", result.totalTests);
|
|
290
|
-
Logger.info("Passed", `${
|
|
291
|
-
Logger.info("Failed", result.failed > 0 ? `${
|
|
290
|
+
Logger.info("Passed", `${C.success}${result.passed}${C.reset}`);
|
|
291
|
+
Logger.info("Failed", result.failed > 0 ? `${C.error}${result.failed}${C.reset}` : "0");
|
|
292
292
|
Logger.info("Skipped", result.skipped);
|
|
293
293
|
Logger.info("Duration", `${(result.duration / 1000).toFixed(2)}s`);
|
|
294
294
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { TomcatConfig, AppConfig } from "../types";
|
|
2
2
|
import { getHotswapAgentUrl, VERSIONS } from "../config/versions";
|
|
3
3
|
import { NetworkError } from "../errors/XavvaError";
|
|
4
|
-
import { Logger } from "../
|
|
4
|
+
import { Logger } from "../logging";
|
|
5
|
+
import { Logger as LoggerLegacy } from "../utils/ui";
|
|
6
|
+
import { NOISE_PATTERNS } from "../logging/constants";
|
|
5
7
|
import { ProgressBar, ThemedSpinner } from "../utils/ProgressBar";
|
|
6
8
|
import type { Subprocess } from "bun";
|
|
7
9
|
import { ProjectService } from "./ProjectService";
|
|
@@ -20,11 +22,12 @@ import {
|
|
|
20
22
|
export class TomcatService {
|
|
21
23
|
private activeConfig: TomcatConfig;
|
|
22
24
|
private currentProcess: Subprocess | null = null;
|
|
23
|
-
private
|
|
25
|
+
private startupSpinner?: { stop: (success?: boolean) => void; update: (msg: string) => void };
|
|
24
26
|
public onReady?: () => void;
|
|
25
27
|
private pid: number | null = null;
|
|
26
28
|
private projectService: ProjectService | null = null;
|
|
27
29
|
private hasReadyBeenCalled: boolean = false;
|
|
30
|
+
private logger = Logger.getInstance();
|
|
28
31
|
|
|
29
32
|
constructor(customConfig: TomcatConfig) {
|
|
30
33
|
this.activeConfig = customConfig;
|
|
@@ -82,7 +85,7 @@ export class TomcatService {
|
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
if (pid) {
|
|
85
|
-
|
|
88
|
+
this.logger.step(`Liberando porta ${this.activeConfig.port}`);
|
|
86
89
|
const killCmd = getKillCommand(pid);
|
|
87
90
|
Bun.spawnSync(killCmd);
|
|
88
91
|
}
|
|
@@ -126,13 +129,13 @@ export class TomcatService {
|
|
|
126
129
|
|
|
127
130
|
await Promise.all(tasks);
|
|
128
131
|
} catch (e) {
|
|
129
|
-
|
|
132
|
+
this.logger.warn("Não foi possível limpar totalmente a pasta webapps ou cache.");
|
|
130
133
|
}
|
|
131
134
|
}
|
|
132
135
|
|
|
133
136
|
stop() {
|
|
134
137
|
if (this.currentProcess) {
|
|
135
|
-
|
|
138
|
+
this.logger.warn("Parando servidor ativo...");
|
|
136
139
|
this.currentProcess.kill();
|
|
137
140
|
this.currentProcess = null;
|
|
138
141
|
}
|
|
@@ -210,7 +213,7 @@ export class TomcatService {
|
|
|
210
213
|
Logger.success(`HotswapAgent v${VERSIONS.HOTSWAP_AGENT.VERSION} instalado!`);
|
|
211
214
|
return agentPath;
|
|
212
215
|
} catch (e: any) {
|
|
213
|
-
|
|
216
|
+
this.logger.warn("Falha ao baixar HotswapAgent. Usando hot swap padrão da JVM.");
|
|
214
217
|
|
|
215
218
|
// Limpa arquivo parcial se existir
|
|
216
219
|
if (existsSync(agentPath)) {
|
|
@@ -314,13 +317,13 @@ export class TomcatService {
|
|
|
314
317
|
}
|
|
315
318
|
|
|
316
319
|
if (config.project.debug) {
|
|
317
|
-
|
|
320
|
+
this.logger.debug(`Porta do debugger ${config.project.debugPort}`);
|
|
318
321
|
env.JPDA_ADDRESS = String(config.project.debugPort);
|
|
319
322
|
env.JPDA_TRANSPORT = "dt_socket";
|
|
320
323
|
}
|
|
321
324
|
|
|
322
325
|
if ((config.project.cleanLogs || config.project.quiet) && !config.project.verbose) {
|
|
323
|
-
this.
|
|
326
|
+
this.startupSpinner = this.logger.spinner("Iniciando servidor Tomcat");
|
|
324
327
|
}
|
|
325
328
|
|
|
326
329
|
this.currentProcess = Bun.spawn([binPath, ...args], {
|
|
@@ -359,9 +362,9 @@ export class TomcatService {
|
|
|
359
362
|
// Detect startup completion
|
|
360
363
|
if (cleanLine.includes("Server startup in") || cleanLine.includes("SEVERE") || cleanLine.includes("Exception")) {
|
|
361
364
|
const isSuccess = cleanLine.includes("Server startup in");
|
|
362
|
-
if (this.
|
|
363
|
-
this.
|
|
364
|
-
this.
|
|
365
|
+
if (this.startupSpinner) {
|
|
366
|
+
this.startupSpinner.stop(isSuccess);
|
|
367
|
+
this.startupSpinner = undefined;
|
|
365
368
|
}
|
|
366
369
|
if (isSuccess && this.onReady && !this.hasReadyBeenCalled) {
|
|
367
370
|
this.hasReadyBeenCalled = true;
|
|
@@ -371,10 +374,12 @@ export class TomcatService {
|
|
|
371
374
|
|
|
372
375
|
// Verbose: formata logs do Tomcat
|
|
373
376
|
if (verbose) {
|
|
374
|
-
|
|
375
|
-
|
|
377
|
+
// No modo verbose, só filtra o noise básico (CATALINA_, JRE_HOME, etc)
|
|
378
|
+
// Logs do HOTSWAP e outros são mostrados
|
|
379
|
+
if (LoggerLegacy.isTomcatNoise(cleanLine) && !LoggerLegacy.isTomcatVerboseLog(cleanLine)) {
|
|
380
|
+
continue; // Silencia noise básico
|
|
376
381
|
}
|
|
377
|
-
const formatted =
|
|
382
|
+
const formatted = LoggerLegacy.formatTomcatLog(cleanLine);
|
|
378
383
|
if (formatted) {
|
|
379
384
|
console.log(formatted);
|
|
380
385
|
}
|
|
@@ -384,30 +389,46 @@ export class TomcatService {
|
|
|
384
389
|
// Clean mode: filtra noise
|
|
385
390
|
if (clean) {
|
|
386
391
|
// Sempre filtra noise do sistema
|
|
387
|
-
if (
|
|
392
|
+
if (NOISE_PATTERNS.system.some(n => cleanLine.includes(n))) continue;
|
|
388
393
|
|
|
389
394
|
// Quiet mode: só mostra essencial
|
|
390
|
-
if (quiet && !
|
|
395
|
+
if (quiet && !LoggerLegacy.isEssential(cleanLine)) {
|
|
391
396
|
if (cleanLine.includes("INFO") && !cleanLine.includes("ERROR")) continue;
|
|
392
397
|
}
|
|
393
398
|
|
|
394
399
|
// Grep filter
|
|
395
400
|
if (grep && !cleanLine.toLowerCase().includes(grep.toLowerCase())) {
|
|
396
|
-
if (!
|
|
401
|
+
if (!LoggerLegacy.isEssential(cleanLine)) continue;
|
|
397
402
|
}
|
|
398
403
|
|
|
399
|
-
const summarized =
|
|
400
|
-
if (summarized) {
|
|
401
|
-
//
|
|
402
|
-
if (
|
|
404
|
+
const summarized = LoggerLegacy.summarize(cleanLine);
|
|
405
|
+
if (summarized && summarized.trim()) {
|
|
406
|
+
// Para o spinner antes de mostrar log para não quebrar a interface
|
|
407
|
+
if (this.startupSpinner) {
|
|
408
|
+
this.startupSpinner.stop(true);
|
|
409
|
+
this.startupSpinner = undefined;
|
|
410
|
+
}
|
|
411
|
+
console.log(summarized);
|
|
403
412
|
}
|
|
404
413
|
} else {
|
|
405
|
-
//
|
|
406
|
-
|
|
407
|
-
|
|
414
|
+
// Modo normal (não verbose, não clean): filtra mais agressivamente
|
|
415
|
+
// Só mostra logs essenciais e resumos
|
|
416
|
+
if (NOISE_PATTERNS.system.some(n => cleanLine.includes(n))) {
|
|
408
417
|
continue;
|
|
409
418
|
}
|
|
410
|
-
|
|
419
|
+
|
|
420
|
+
// No modo normal, só mostra se for essencial ou tiver resumo
|
|
421
|
+
const summarized = LoggerLegacy.summarize(cleanLine);
|
|
422
|
+
if (summarized && summarized.trim()) {
|
|
423
|
+
// Para o spinner antes de mostrar log
|
|
424
|
+
if (this.startupSpinner) {
|
|
425
|
+
this.startupSpinner.stop(true);
|
|
426
|
+
this.startupSpinner = undefined;
|
|
427
|
+
}
|
|
428
|
+
console.log(summarized);
|
|
429
|
+
}
|
|
430
|
+
// Silencia logs não essenciais no modo normal
|
|
431
|
+
// (WARNING, ADVERTÊNCIA, INFO genérico, etc. só aparecem no verbose)
|
|
411
432
|
}
|
|
412
433
|
}
|
|
413
434
|
}
|