chore(platform): replace runtime console diagnostics
What changed: - Replaced platform-service runtime console diagnostics with structured stderr logging helpers. - Preserved push notification, AI diagnostics, auto-trigger, and diagnostics repository error handling semantics. Warning impact: - Platform runtime no-console warnings: 12 -> 0. - Workspace lint: 12 -> 0 warnings. Verification: - pnpm --filter @lysnrai/platform-service build - pnpm --filter @lysnrai/platform-service test - pnpm --filter @lysnrai/platform-service exec eslint <runtime files> --ext .ts - pnpm lint
This commit is contained in:
parent
2c9dc1870d
commit
663dcdecab
@ -32,6 +32,22 @@ interface PushPayload {
|
||||
badge?: number;
|
||||
}
|
||||
|
||||
function logPushWarning(message: string, extra?: Record<string, unknown>): void {
|
||||
process.stderr.write(JSON.stringify({ level: 'warn', module: 'push', message, ...extra }) + '\n');
|
||||
}
|
||||
|
||||
function logPushError(message: string, error: unknown, extra?: Record<string, unknown>): void {
|
||||
process.stderr.write(
|
||||
JSON.stringify({
|
||||
level: 'error',
|
||||
module: 'push',
|
||||
message,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
...extra,
|
||||
}) + '\n'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store or update device token for push notifications
|
||||
*/
|
||||
@ -130,7 +146,7 @@ export async function sendFCM(
|
||||
// Get FCM server key from environment
|
||||
const fcmKey = process.env.FCM_SERVER_KEY;
|
||||
if (!fcmKey) {
|
||||
console.warn('[Push] FCM_SERVER_KEY not configured');
|
||||
logPushWarning('FCM_SERVER_KEY not configured');
|
||||
return results;
|
||||
}
|
||||
|
||||
@ -164,11 +180,11 @@ export async function sendFCM(
|
||||
results.success.push(token);
|
||||
} else {
|
||||
const error = await response.text();
|
||||
console.error(`[Push] FCM failed for token ${token.substring(0, 16)}...:`, error);
|
||||
logPushError('FCM send failed', error, { tokenPrefix: token.substring(0, 16) });
|
||||
results.failed.push(token);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`[Push] FCM error for token ${token.substring(0, 16)}...:`, err);
|
||||
logPushError('FCM send error', err, { tokenPrefix: token.substring(0, 16) });
|
||||
results.failed.push(token);
|
||||
}
|
||||
}
|
||||
@ -194,7 +210,7 @@ export async function sendAPNS(
|
||||
const apnsPrivateKey = process.env.APNS_PRIVATE_KEY;
|
||||
|
||||
if (!apnsKeyId || !apnsTeamId || !apnsBundleId || !apnsPrivateKey) {
|
||||
console.warn('[Push] APNS credentials not fully configured');
|
||||
logPushWarning('APNS credentials not fully configured');
|
||||
return results;
|
||||
}
|
||||
|
||||
@ -241,7 +257,10 @@ export async function sendAPNS(
|
||||
results.success.push(token);
|
||||
} else {
|
||||
const error = await response.text();
|
||||
console.error(`[Push] APNS failed for token ${token.substring(0, 16)}...:`, error);
|
||||
logPushError('APNS send failed', error, {
|
||||
status: response.status,
|
||||
tokenPrefix: token.substring(0, 16),
|
||||
});
|
||||
results.failed.push(token);
|
||||
|
||||
// Handle invalid token (410 Gone)
|
||||
@ -250,7 +269,7 @@ export async function sendAPNS(
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`[Push] APNS error for token ${token.substring(0, 16)}...:`, err);
|
||||
logPushError('APNS send error', err, { tokenPrefix: token.substring(0, 16) });
|
||||
results.failed.push(token);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import { config } from '../../lib/config.js';
|
||||
import type { FastifyBaseLogger } from 'fastify';
|
||||
|
||||
// ============================================================================
|
||||
// Azure OpenAI Embedding Client
|
||||
@ -11,6 +10,17 @@ const EMBEDDING_DIMENSIONS = 1536;
|
||||
const MAX_BATCH_SIZE = 100; // Azure OpenAI limit
|
||||
const MAX_TOKENS_PER_REQUEST = 8192;
|
||||
|
||||
function logEmbeddingError(message: string, error: unknown): void {
|
||||
process.stderr.write(
|
||||
JSON.stringify({
|
||||
level: 'error',
|
||||
module: 'ai-diagnostics.embeddings',
|
||||
message,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
}) + '\n'
|
||||
);
|
||||
}
|
||||
|
||||
interface EmbeddingResponse {
|
||||
object: 'list';
|
||||
data: Array<{
|
||||
@ -93,7 +103,7 @@ export async function generateEmbedding(
|
||||
model: data.model,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Failed to generate embedding:', error);
|
||||
logEmbeddingError('Failed to generate embedding', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@ -174,7 +184,7 @@ export async function generateEmbeddingsBatch(
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to generate batch embeddings:', error);
|
||||
logEmbeddingError('Failed to generate batch embeddings', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,17 @@ interface RootCauseAnalysisPrompt {
|
||||
analysisType: 'root_cause' | 'pattern' | 'comparison' | 'trend';
|
||||
}
|
||||
|
||||
function logAnalyzerError(message: string, error: unknown): void {
|
||||
process.stderr.write(
|
||||
JSON.stringify({
|
||||
level: 'error',
|
||||
module: 'ai-diagnostics.llm-analyzer',
|
||||
message,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
}) + '\n'
|
||||
);
|
||||
}
|
||||
|
||||
const ROOT_CAUSE_ANALYSIS_PROMPT_TEMPLATE = `You are an expert software engineer diagnosing production errors. Analyze this error cluster and provide root cause insights.
|
||||
|
||||
## Error Cluster
|
||||
@ -206,7 +217,7 @@ async function callLLM(
|
||||
completionTokens: data.usage?.completion_tokens || 0,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('LLM call failed:', error);
|
||||
logAnalyzerError('LLM call failed', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,17 @@ import type { DebugSessionDoc } from './types.js';
|
||||
import { createSession } from './repository.js';
|
||||
import { getRegisteredContainer } from '@bytelyst/cosmos';
|
||||
|
||||
function logTriggerError(message: string, error: unknown): void {
|
||||
process.stderr.write(
|
||||
JSON.stringify({
|
||||
level: 'error',
|
||||
module: 'diagnostics.auto-triggers',
|
||||
message,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
}) + '\n'
|
||||
);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Trigger Configuration Types
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@ -399,7 +410,7 @@ async function sendTriggerNotifications(
|
||||
});
|
||||
} catch (err) {
|
||||
// Log but don't fail
|
||||
console.error('Failed to send Slack notification:', err);
|
||||
logTriggerError('Failed to send Slack notification', err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,7 +438,7 @@ async function sendTriggerNotifications(
|
||||
}),
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to send Teams notification:', err);
|
||||
logTriggerError('Failed to send Teams notification', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -39,6 +39,12 @@ function screenshotsCollection() {
|
||||
return getCollection<DebugScreenshotDoc>('debug_screenshots', '/sessionId');
|
||||
}
|
||||
|
||||
function logDiagnosticsWarning(message: string, extra?: Record<string, unknown>): void {
|
||||
process.stderr.write(
|
||||
JSON.stringify({ level: 'warn', module: 'diagnostics.repository', message, ...extra }) + '\n'
|
||||
);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Helper: Build composite partition key
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@ -320,9 +326,10 @@ export async function updateSessionStats(
|
||||
retries++;
|
||||
if (retries >= MAX_RETRIES) {
|
||||
// Log warning but don't fail the ingest - data integrity > stats accuracy
|
||||
console.warn(
|
||||
`[diagnostics] Failed to update session stats after ${MAX_RETRIES} retries for session ${sessionId}`
|
||||
);
|
||||
logDiagnosticsWarning('Failed to update session stats after max retries', {
|
||||
retries: MAX_RETRIES,
|
||||
sessionId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Small delay before retry
|
||||
|
||||
Loading…
Reference in New Issue
Block a user