@jishankai/solid-cli 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.
@@ -0,0 +1,352 @@
1
+ import winston from 'winston';
2
+ import DailyRotateFile from 'winston-daily-rotate-file';
3
+ import { join } from 'path';
4
+ import { promises as fs } from 'fs';
5
+
6
+ /**
7
+ * Structured Logging System
8
+ */
9
+ export class Logger {
10
+ constructor(options = {}) {
11
+ this.options = {
12
+ logDir: './logs',
13
+ level: 'info',
14
+ consoleLevel: 'warn',
15
+ maxSize: '20m',
16
+ maxFiles: '14d',
17
+ enableConsole: true,
18
+ enableFiles: true,
19
+ ...options
20
+ };
21
+
22
+ this.logger = this.createLogger();
23
+ }
24
+
25
+ /**
26
+ * Create Winston logger with proper configuration
27
+ */
28
+ createLogger() {
29
+ const transports = [];
30
+
31
+ // Console transport for development
32
+ if (this.options.enableConsole) {
33
+ transports.push(
34
+ new winston.transports.Console({
35
+ level: this.options.consoleLevel,
36
+ format: winston.format.combine(
37
+ winston.format.colorize(),
38
+ winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
39
+ winston.format.printf(({ level, message, timestamp, ...meta }) => {
40
+ const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';
41
+ return `${timestamp} [${level}]: ${message}${metaStr}`;
42
+ })
43
+ )
44
+ })
45
+ );
46
+ }
47
+
48
+ // File transport for production logs
49
+ if (this.options.enableFiles) {
50
+ // Ensure log directory exists
51
+ this.ensureLogDirectory();
52
+
53
+ // Application logs
54
+ transports.push(
55
+ new DailyRotateFile({
56
+ filename: join(this.options.logDir, 'app-%DATE%.log'),
57
+ datePattern: 'YYYY-MM-DD',
58
+ maxSize: this.options.maxSize,
59
+ maxFiles: this.options.maxFiles,
60
+ format: winston.format.combine(
61
+ winston.format.timestamp(),
62
+ winston.format.json()
63
+ )
64
+ })
65
+ );
66
+
67
+ // Error logs
68
+ transports.push(
69
+ new DailyRotateFile({
70
+ filename: join(this.options.logDir, 'error-%DATE%.log'),
71
+ datePattern: 'YYYY-MM-DD',
72
+ level: 'error',
73
+ maxSize: this.options.maxSize,
74
+ maxFiles: this.options.maxFiles,
75
+ format: winston.format.combine(
76
+ winston.format.timestamp(),
77
+ winston.format.json()
78
+ )
79
+ })
80
+ );
81
+
82
+ // Security event logs
83
+ transports.push(
84
+ new DailyRotateFile({
85
+ filename: join(this.options.logDir, 'security-%DATE%.log'),
86
+ datePattern: 'YYYY-MM-DD',
87
+ level: 'warn',
88
+ maxSize: this.options.maxSize,
89
+ maxFiles: '30d', // Keep security logs longer
90
+ format: winston.format.combine(
91
+ winston.format.timestamp(),
92
+ winston.format.json()
93
+ )
94
+ })
95
+ );
96
+ }
97
+
98
+ return winston.createLogger({
99
+ level: this.options.level,
100
+ defaultMeta: {
101
+ service: 'security-solid-cli',
102
+ version: '2.0.0'
103
+ },
104
+ transports,
105
+ exitOnError: false
106
+ });
107
+ }
108
+
109
+ /**
110
+ * Ensure log directory exists
111
+ */
112
+ async ensureLogDirectory() {
113
+ try {
114
+ await fs.mkdir(this.options.logDir, { recursive: true });
115
+ } catch (error) {
116
+ console.error(`Failed to create log directory: ${error.message}`);
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Log analysis start
122
+ */
123
+ logAnalysisStart(options = {}) {
124
+ this.logger.info('Analysis started', {
125
+ event: 'analysis_start',
126
+ mode: options.mode,
127
+ depth: options.depth,
128
+ geoLookup: options.geoLookup,
129
+ hostname: options.hostname
130
+ });
131
+ }
132
+
133
+ /**
134
+ * Log analysis completion
135
+ */
136
+ logAnalysisComplete(results, duration) {
137
+ this.logger.info('Analysis completed', {
138
+ event: 'analysis_complete',
139
+ duration,
140
+ findings: results.summary.totalFindings,
141
+ highRisk: results.summary.highRiskFindings,
142
+ mediumRisk: results.summary.mediumRiskFindings,
143
+ lowRisk: results.summary.lowRiskFindings,
144
+ overallRisk: results.overallRisk,
145
+ agentsRan: Object.keys(results.agents).length
146
+ });
147
+ }
148
+
149
+ /**
150
+ * Log agent execution
151
+ */
152
+ logAgentStart(agentName, options = {}) {
153
+ this.logger.debug(`Agent started: ${agentName}`, {
154
+ event: 'agent_start',
155
+ agent: agentName,
156
+ ...options
157
+ });
158
+ }
159
+
160
+ /**
161
+ * Log agent completion
162
+ */
163
+ logAgentComplete(agentName, results, duration) {
164
+ this.logger.debug(`Agent completed: ${agentName}`, {
165
+ event: 'agent_complete',
166
+ agent: agentName,
167
+ duration,
168
+ findings: results.findings?.length || 0,
169
+ risk: results.overallRisk,
170
+ error: results.error ? true : false
171
+ });
172
+ }
173
+
174
+ /**
175
+ * Log agent error
176
+ */
177
+ logAgentError(agentName, error, duration) {
178
+ this.logger.error(`Agent failed: ${agentName}`, {
179
+ event: 'agent_error',
180
+ agent: agentName,
181
+ duration,
182
+ error: error.message,
183
+ stack: error.stack
184
+ });
185
+ }
186
+
187
+ /**
188
+ * Log security event
189
+ */
190
+ logSecurityEvent(event, details = {}) {
191
+ this.logger.warn('Security event detected', {
192
+ event: 'security_event',
193
+ securityEvent: event,
194
+ severity: details.severity || 'medium',
195
+ ...details
196
+ });
197
+ }
198
+
199
+ /**
200
+ * Log report generation
201
+ */
202
+ logReportGeneration(formats, outputPaths, duration) {
203
+ this.logger.info('Reports generated', {
204
+ event: 'report_generation',
205
+ formats,
206
+ outputPaths,
207
+ duration
208
+ });
209
+ }
210
+
211
+ /**
212
+ * Log LLM analysis
213
+ */
214
+ logLLMAnalysis(provider, model, tokens, duration) {
215
+ this.logger.info('LLM analysis completed', {
216
+ event: 'llm_analysis',
217
+ provider,
218
+ model,
219
+ tokens,
220
+ duration
221
+ });
222
+ }
223
+
224
+ /**
225
+ * Log blockchain detection
226
+ */
227
+ logBlockchainDetection(indicators) {
228
+ this.logger.info('Blockchain activity detected', {
229
+ event: 'blockchain_detection',
230
+ indicators,
231
+ action: 'blockchain_agents_activated'
232
+ });
233
+ }
234
+
235
+ /**
236
+ * Log performance metrics
237
+ */
238
+ logPerformance(operation, duration, metadata = {}) {
239
+ this.logger.debug(`Performance: ${operation}`, {
240
+ event: 'performance',
241
+ operation,
242
+ duration,
243
+ ...metadata
244
+ });
245
+ }
246
+
247
+ /**
248
+ * Log user interaction
249
+ */
250
+ logUserInteraction(action, details = {}) {
251
+ this.logger.debug('User interaction', {
252
+ event: 'user_interaction',
253
+ action,
254
+ ...details
255
+ });
256
+ }
257
+
258
+ /**
259
+ * Log configuration changes
260
+ */
261
+ logConfigurationChange(setting, oldValue, newValue) {
262
+ this.logger.info('Configuration changed', {
263
+ event: 'config_change',
264
+ setting,
265
+ oldValue,
266
+ newValue
267
+ });
268
+ }
269
+
270
+ /**
271
+ * Get logger instance
272
+ */
273
+ getLogger() {
274
+ return this.logger;
275
+ }
276
+
277
+ /**
278
+ * Set log level
279
+ */
280
+ setLevel(level) {
281
+ this.logger.level = level;
282
+ this.options.level = level;
283
+ }
284
+
285
+ /**
286
+ * Add custom transport
287
+ */
288
+ addTransport(transport) {
289
+ this.logger.add(transport);
290
+ }
291
+
292
+ /**
293
+ * Remove transport
294
+ */
295
+ removeTransport(transport) {
296
+ this.logger.remove(transport);
297
+ }
298
+
299
+ /**
300
+ * Close logger
301
+ */
302
+ async close() {
303
+ const transports = this.logger.transports;
304
+ await Promise.all(
305
+ transports.map(transport => {
306
+ if (typeof transport.close === 'function') {
307
+ return transport.close();
308
+ }
309
+ return Promise.resolve();
310
+ })
311
+ );
312
+ }
313
+ }
314
+
315
+ /**
316
+ * Global logger instance
317
+ */
318
+ let globalLogger = null;
319
+
320
+ /**
321
+ * Get or create global logger instance
322
+ */
323
+ export function getLogger(options = {}) {
324
+ if (!globalLogger) {
325
+ globalLogger = new Logger(options);
326
+ }
327
+ return globalLogger;
328
+ }
329
+
330
+ /**
331
+ * Log convenience functions
332
+ */
333
+ export const log = {
334
+ debug: (message, meta = {}) => getLogger().getLogger().debug(message, meta),
335
+ info: (message, meta = {}) => getLogger().getLogger().info(message, meta),
336
+ warn: (message, meta = {}) => getLogger().getLogger().warn(message, meta),
337
+ error: (message, meta = {}) => getLogger().getLogger().error(message, meta),
338
+
339
+ // Structured logging functions
340
+ analysisStart: (options) => getLogger().logAnalysisStart(options),
341
+ analysisComplete: (results, duration) => getLogger().logAnalysisComplete(results, duration),
342
+ agentStart: (agent, options) => getLogger().logAgentStart(agent, options),
343
+ agentComplete: (agent, results, duration) => getLogger().logAgentComplete(agent, results, duration),
344
+ agentError: (agent, error, duration) => getLogger().logAgentError(agent, error, duration),
345
+ securityEvent: (event, details) => getLogger().logSecurityEvent(event, details),
346
+ reportGeneration: (formats, paths, duration) => getLogger().logReportGeneration(formats, paths, duration),
347
+ llmAnalysis: (provider, model, tokens, duration) => getLogger().logLLMAnalysis(provider, model, tokens, duration),
348
+ blockchainDetection: (indicators) => getLogger().logBlockchainDetection(indicators),
349
+ performance: (operation, duration, meta) => getLogger().logPerformance(operation, duration, meta),
350
+ userInteraction: (action, details) => getLogger().logUserInteraction(action, details),
351
+ configChange: (setting, oldVal, newVal) => getLogger().logConfigurationChange(setting, oldVal, newVal)
352
+ };