@oneuptime/common 11.5.3 → 11.5.5
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/Models/DatabaseModels/AIAgentTaskPullRequest.ts +56 -45
- package/Models/DatabaseModels/AIInsight.ts +748 -0
- package/Models/DatabaseModels/AIRun.ts +262 -0
- package/Models/DatabaseModels/CodeRepository.ts +42 -0
- package/Models/DatabaseModels/Dashboard.ts +3 -3
- package/Models/DatabaseModels/GlobalConfig.ts +105 -0
- package/Models/DatabaseModels/Index.ts +4 -8
- package/Models/DatabaseModels/InstanceHealthLog.ts +277 -0
- package/Models/DatabaseModels/LlmLog.ts +33 -0
- package/Models/DatabaseModels/Project.ts +123 -6
- package/Models/DatabaseModels/Runbook.ts +1 -1
- package/Server/API/AIAgentDataAPI.ts +802 -140
- package/Server/API/AIAgentTaskAPI.ts +132 -69
- package/Server/API/AIAgentTaskLogAPI.ts +65 -41
- package/Server/API/AIAgentTaskPullRequestAPI.ts +41 -0
- package/Server/API/AIInsightAPI.ts +220 -0
- package/Server/API/AIInvestigationAPI.ts +363 -1
- package/Server/API/CodeFixRunAPI.ts +251 -0
- package/Server/API/GitHubAPI.ts +246 -3
- package/Server/API/TelemetryExceptionAPI.ts +193 -48
- package/Server/EnvironmentConfig.ts +1 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.ts +26 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.ts +73 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.ts +51 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.ts +53 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.ts +37 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.ts +75 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.ts +37 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.ts +203 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.ts +163 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +30 -0
- package/Server/Infrastructure/Queue.ts +82 -4
- package/Server/Infrastructure/Semaphore.ts +62 -1
- package/Server/Services/AIAgentService.ts +32 -0
- package/Server/Services/AIAgentTaskPullRequestService.ts +117 -0
- package/Server/Services/AIInsightService.ts +174 -0
- package/Server/Services/AIRunEventService.ts +63 -0
- package/Server/Services/AIRunService.ts +259 -1
- package/Server/Services/AIService.ts +249 -7
- package/Server/Services/AlertService.ts +4 -4
- package/Server/Services/CodeRepositoryService.ts +209 -0
- package/Server/Services/DashboardService.ts +11 -2
- package/Server/Services/GlobalConfigService.ts +148 -0
- package/Server/Services/IncidentService.ts +183 -38
- package/Server/Services/IncidentStateTimelineService.ts +24 -4
- package/Server/Services/Index.ts +4 -4
- package/Server/Services/{AIAgentTaskLogService.ts → InstanceHealthLogService.ts} +1 -1
- package/Server/Services/LlmLogService.ts +27 -0
- package/Server/Services/LlmProviderService.ts +108 -0
- package/Server/Services/MetricBaselineService.ts +123 -0
- package/Server/Services/MonitorService.ts +15 -0
- package/Server/Services/TelemetryExceptionService.ts +323 -116
- package/Server/Services/TraceAggregationService.ts +176 -0
- package/Server/Types/Workflow/ComponentCode.ts +6 -0
- package/Server/Types/Workflow/Components/AI/GenerateText.ts +326 -0
- package/Server/Types/Workflow/Components/Index.ts +2 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +1 -1
- package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +71 -0
- package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +243 -0
- package/Server/Utils/AI/CodeFix/CodeFixRunQueue.ts +131 -0
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +148 -0
- package/Server/Utils/AI/CodeFix/OpenPullRequestCap.ts +117 -0
- package/Server/Utils/AI/Eval/EvalCorpus.ts +369 -0
- package/Server/Utils/AI/Eval/EvalScores.ts +172 -0
- package/Server/Utils/AI/Eval/ReplayInvestigation.ts +87 -0
- package/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.ts +676 -0
- package/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.ts → SRE/AIInvestigationEngine.ts} +58 -37
- package/Server/Utils/AI/{Sentinel/SentinelMemory.ts → SRE/AIMemory.ts} +3 -3
- package/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.ts +50 -20
- package/Server/Utils/AI/SRE/ConfidenceSignal.ts +293 -0
- package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +115 -0
- package/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.ts +223 -0
- package/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.ts +71 -21
- package/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.ts +8 -8
- package/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.ts +364 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +317 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/Index.ts +27 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.ts +221 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +238 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.ts +521 -0
- package/Server/Utils/AI/SRE/Insights/FixRouting.ts +242 -0
- package/Server/Utils/AI/SRE/Insights/InsightScanner.ts +290 -0
- package/Server/Utils/AI/SRE/Insights/InsightStore.ts +283 -0
- package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +242 -0
- package/Server/Utils/AI/SRE/Insights/Triage.ts +162 -0
- package/Server/Utils/AI/SRE/Insights/Types.ts +49 -0
- package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +212 -0
- package/Server/Utils/AI/SRE/InvestigationGrader.ts +282 -0
- package/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.ts +114 -19
- package/Server/Utils/AI/{Sentinel → SRE}/README.md +4 -4
- package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +172 -0
- package/Server/Utils/AI/Toolbox/{SentinelActionTools.ts → AIActionTools.ts} +22 -1
- package/Server/Utils/AI/Toolbox/Index.ts +2 -2
- package/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.ts +526 -0
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +319 -1
- package/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.ts +221 -0
- package/Server/Utils/CodeRepository/StackTraceRepoResolver.ts +571 -0
- package/Server/Utils/Execute.ts +34 -13
- package/Server/Utils/LLM/LLMService.ts +160 -30
- package/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.ts +152 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +29 -0
- package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +225 -0
- package/Tests/Server/Infrastructure/Queue.test.ts +227 -0
- package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +159 -0
- package/Tests/Server/Services/AIAgentTaskPullRequestOutcomeStats.test.ts +154 -0
- package/Tests/Server/Services/AIInsightService.test.ts +324 -0
- package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +401 -0
- package/Tests/Server/Services/AIRunHumanVerdict.test.ts +161 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +95 -5
- package/Tests/Server/Services/AIServiceProjectAccess.test.ts +259 -0
- package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +249 -0
- package/Tests/Server/Services/FixPerformanceTaskTrigger.test.ts +274 -0
- package/Tests/Server/Services/GlobalConfigService.test.ts +80 -0
- package/Tests/Server/Services/IncidentInternalNoteAnnouncement.test.ts +1 -1
- package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +313 -0
- package/Tests/Server/Services/LlmProviderProjectOwned.test.ts +132 -0
- package/Tests/Server/Services/TelemetryExceptionAIFixReadiness.test.ts +405 -0
- package/Tests/Server/Services/TelemetryExceptionCodeFixRun.test.ts +322 -0
- package/Tests/Server/Services/TraceServiceLatencyProfile.test.ts +278 -0
- package/Tests/Server/Types/Workflow/Components/AIGenerateText.test.ts +722 -0
- package/Tests/Server/Utils/AI/{SentinelAlertGating.test.ts → AIAlertGating.test.ts} +19 -19
- package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +362 -0
- package/Tests/Server/Utils/AI/{SentinelInvestigationQueue.test.ts → AIInvestigationQueue.test.ts} +19 -19
- package/Tests/Server/Utils/AI/CodeAgentWorkspaceGuard.test.ts +138 -0
- package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +335 -0
- package/Tests/Server/Utils/AI/CodeFixRunQueue.test.ts +134 -0
- package/Tests/Server/Utils/AI/EvalCorpus.test.ts +209 -0
- package/Tests/Server/Utils/AI/EvalScores.test.ts +343 -0
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +218 -0
- package/Tests/Server/Utils/AI/Insights/ErrorLogSpikeDetector.test.ts +437 -0
- package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +287 -0
- package/Tests/Server/Utils/AI/Insights/InsightDetectorsIndex.test.ts +34 -0
- package/Tests/Server/Utils/AI/Insights/InsightFixRouting.test.ts +572 -0
- package/Tests/Server/Utils/AI/Insights/InsightNeverThrowsHardening.test.ts +344 -0
- package/Tests/Server/Utils/AI/Insights/InsightScanner.test.ts +720 -0
- package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +467 -0
- package/Tests/Server/Utils/AI/Insights/InsightStoreHardening.test.ts +370 -0
- package/Tests/Server/Utils/AI/Insights/InsightTriage.test.ts +210 -0
- package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +221 -0
- package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +328 -0
- package/Tests/Server/Utils/AI/Insights/MetricBaselineDrift.test.ts +182 -0
- package/Tests/Server/Utils/AI/Insights/MetricDriftDetector.test.ts +280 -0
- package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +259 -0
- package/Tests/Server/Utils/AI/Insights/TraceLatencyRegressionDetector.test.ts +770 -0
- package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +343 -0
- package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +307 -0
- package/Tests/Server/Utils/AI/OpenPullRequestCap.test.ts +170 -0
- package/Tests/Server/Utils/AI/SpanTreeAnalyzer.test.ts +559 -0
- package/Tests/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.test.ts +158 -0
- package/Tests/Server/Utils/GitHubCheckRunsConclusion.test.ts +100 -0
- package/Tests/Server/Utils/GitHubPullRequestStateMapping.test.ts +50 -0
- package/Tests/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.test.ts +266 -0
- package/Tests/Server/Utils/ServiceRepoLinkSuggester.test.ts +167 -0
- package/Tests/Server/Utils/StackTraceRepoResolver.test.ts +527 -0
- package/Tests/Types/AI/AIChatPermissionMode.test.ts +112 -0
- package/Tests/Types/AI/CodeFixTaskType.test.ts +152 -0
- package/Tests/Types/AI/FixPullRequestCiStatus.test.ts +181 -0
- package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +110 -0
- package/Tests/Types/Monitor/SqlDatabaseType.test.ts +55 -0
- package/Tests/Types/Workflow/AIGenerateTextMetadata.test.ts +180 -0
- package/Tests/UI/Components/TableBulkCsvExport.test.tsx +168 -0
- package/Tests/UI/Utils/TableColumnsToCsv.test.ts +523 -0
- package/Types/AI/AIChatTypes.ts +8 -0
- package/Types/AI/AIInsightEvidence.ts +77 -0
- package/Types/AI/AIInsightHumanVerdict.ts +15 -0
- package/Types/AI/AIInsightSeverity.ts +13 -0
- package/Types/AI/AIInsightStatus.ts +38 -0
- package/Types/AI/AIInsightType.ts +41 -0
- package/Types/AI/AIRunAutoGrade.ts +18 -0
- package/Types/AI/AIRunEventType.ts +5 -0
- package/Types/AI/AIRunHumanVerdict.ts +17 -0
- package/Types/AI/AIRunType.ts +6 -0
- package/Types/AI/CodeFixTaskContext.ts +88 -0
- package/Types/AI/CodeFixTaskType.ts +132 -0
- package/Types/AI/FixPullRequestCiStatus.ts +132 -0
- package/Types/BaseDatabase/AggregationIntervalUtil.ts +67 -0
- package/Types/Incident/IncidentMetricType.ts +7 -0
- package/Types/Monitor/CriteriaFilter.ts +8 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
- package/Types/Monitor/MonitorStep.ts +38 -0
- package/Types/Monitor/MonitorStepSqlMonitor.ts +141 -0
- package/Types/Monitor/MonitorType.ts +17 -0
- package/Types/Monitor/SqlDatabaseType.ts +49 -0
- package/Types/Monitor/SqlMonitor/SqlMonitorResponse.ts +28 -0
- package/Types/Permission.ts +11 -95
- package/Types/Probe/ProbeMonitorResponse.ts +2 -0
- package/Types/Runbook/RunbookStep.ts +26 -2
- package/Types/Runbook/RunbookStepType.ts +1 -0
- package/Types/Workflow/Component.ts +13 -0
- package/Types/Workflow/ComponentID.ts +1 -0
- package/Types/Workflow/Components/AI.ts +148 -0
- package/Types/Workflow/Components.ts +8 -0
- package/UI/Components/AI/GenerateFromAIModal.tsx +1 -1
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +11 -0
- package/UI/Components/MoreMenu/MoreMenu.tsx +1 -1
- package/UI/Components/Table/Table.tsx +38 -2
- package/UI/Utils/TableColumnsToCsv.ts +385 -0
- package/Utils/Monitor/MonitorMetricType.ts +1 -0
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +59 -45
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIInsight.js +795 -0
- package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AIRun.js +274 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CodeRepository.js +43 -0
- package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Dashboard.js +3 -3
- package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +110 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +4 -8
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InstanceHealthLog.js +304 -0
- package/build/dist/Models/DatabaseModels/InstanceHealthLog.js.map +1 -0
- package/build/dist/Models/DatabaseModels/LlmLog.js +35 -0
- package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +127 -6
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Runbook.js +1 -1
- package/build/dist/Models/DatabaseModels/Runbook.js.map +1 -1
- package/build/dist/Server/API/AIAgentDataAPI.js +568 -85
- package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskAPI.js +100 -44
- package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskLogAPI.js +49 -25
- package/build/dist/Server/API/AIAgentTaskLogAPI.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js +27 -0
- package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js.map +1 -1
- package/build/dist/Server/API/AIInsightAPI.js +140 -0
- package/build/dist/Server/API/AIInsightAPI.js.map +1 -0
- package/build/dist/Server/API/AIInvestigationAPI.js +257 -1
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/CodeFixRunAPI.js +181 -0
- package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -0
- package/build/dist/Server/API/GitHubAPI.js +164 -2
- package/build/dist/Server/API/GitHubAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryExceptionAPI.js +148 -43
- package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +1 -1
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js +32 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js +32 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js +125 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js +62 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +73 -3
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +44 -1
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Services/AIAgentService.js +29 -0
- package/build/dist/Server/Services/AIAgentService.js.map +1 -1
- package/build/dist/Server/Services/AIAgentTaskPullRequestService.js +78 -0
- package/build/dist/Server/Services/AIAgentTaskPullRequestService.js.map +1 -1
- package/build/dist/Server/Services/AIInsightService.js +164 -0
- package/build/dist/Server/Services/AIInsightService.js.map +1 -0
- package/build/dist/Server/Services/AIRunEventService.js +49 -0
- package/build/dist/Server/Services/AIRunEventService.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +221 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +198 -11
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +4 -4
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/CodeRepositoryService.js +180 -0
- package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
- package/build/dist/Server/Services/DashboardService.js +8 -2
- package/build/dist/Server/Services/DashboardService.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +84 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +149 -37
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +24 -4
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +4 -4
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/{AIAgentTaskLogService.js → InstanceHealthLogService.js} +2 -2
- package/build/dist/Server/Services/InstanceHealthLogService.js.map +1 -0
- package/build/dist/Server/Services/LlmLogService.js +23 -0
- package/build/dist/Server/Services/LlmLogService.js.map +1 -1
- package/build/dist/Server/Services/LlmProviderService.js +96 -0
- package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
- package/build/dist/Server/Services/MetricBaselineService.js +65 -0
- package/build/dist/Server/Services/MetricBaselineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +9 -1
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryExceptionService.js +243 -82
- package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +124 -0
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Types/Workflow/ComponentCode.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js +240 -0
- package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/Index.js +2 -0
- package/build/dist/Server/Types/Workflow/Components/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +48 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +174 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js +126 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js.map +1 -0
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +131 -0
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -0
- package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js +99 -0
- package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js.map +1 -0
- package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js +245 -0
- package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js.map +1 -0
- package/build/dist/Server/Utils/AI/Eval/EvalScores.js +83 -0
- package/build/dist/Server/Utils/AI/Eval/EvalScores.js.map +1 -0
- package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js +12 -0
- package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js.map +1 -0
- package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js +439 -0
- package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js.map +1 -0
- package/build/dist/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.js → SRE/AIInvestigationEngine.js} +47 -31
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -0
- package/build/dist/Server/Utils/AI/{Sentinel/SentinelMemory.js → SRE/AIMemory.js} +5 -5
- package/build/dist/Server/Utils/AI/SRE/AIMemory.js.map +1 -0
- package/build/dist/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.js +42 -19
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +226 -0
- package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +100 -0
- package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js +174 -0
- package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js.map +1 -0
- package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.js +60 -22
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.js +9 -9
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js +268 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +226 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js +26 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js +159 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +177 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js +384 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js +180 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js +269 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +231 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +206 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js +121 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Types.js +2 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Types.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +148 -0
- package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +231 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -0
- package/build/dist/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.js +102 -23
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +167 -0
- package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/{SentinelActionTools.js → AIActionTools.js} +18 -2
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +2 -2
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js +301 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +240 -2
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js +127 -0
- package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js +336 -0
- package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js.map +1 -0
- package/build/dist/Server/Utils/Execute.js +21 -11
- package/build/dist/Server/Utils/Execute.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +125 -25
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js +120 -0
- package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Types/AI/AIInsightEvidence.js +2 -0
- package/build/dist/Types/AI/AIInsightEvidence.js.map +1 -0
- package/build/dist/Types/AI/AIInsightHumanVerdict.js +16 -0
- package/build/dist/Types/AI/AIInsightHumanVerdict.js.map +1 -0
- package/build/dist/Types/AI/AIInsightSeverity.js +14 -0
- package/build/dist/Types/AI/AIInsightSeverity.js.map +1 -0
- package/build/dist/Types/AI/AIInsightStatus.js +36 -0
- package/build/dist/Types/AI/AIInsightStatus.js.map +1 -0
- package/build/dist/Types/AI/AIInsightType.js +42 -0
- package/build/dist/Types/AI/AIInsightType.js.map +1 -0
- package/build/dist/Types/AI/AIRunAutoGrade.js +19 -0
- package/build/dist/Types/AI/AIRunAutoGrade.js.map +1 -0
- package/build/dist/Types/AI/AIRunEventType.js +5 -0
- package/build/dist/Types/AI/AIRunEventType.js.map +1 -1
- package/build/dist/Types/AI/AIRunHumanVerdict.js +18 -0
- package/build/dist/Types/AI/AIRunHumanVerdict.js.map +1 -0
- package/build/dist/Types/AI/AIRunType.js +6 -0
- package/build/dist/Types/AI/AIRunType.js.map +1 -1
- package/build/dist/Types/AI/CodeFixTaskContext.js +29 -0
- package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -0
- package/build/dist/Types/AI/CodeFixTaskType.js +122 -0
- package/build/dist/Types/AI/CodeFixTaskType.js.map +1 -0
- package/build/dist/Types/AI/FixPullRequestCiStatus.js +102 -0
- package/build/dist/Types/AI/FixPullRequestCiStatus.js.map +1 -0
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +55 -0
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
- package/build/dist/Types/Incident/IncidentMetricType.js +7 -0
- package/build/dist/Types/Incident/IncidentMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +7 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +28 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +93 -0
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorType.js +15 -0
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SqlDatabaseType.js +47 -0
- package/build/dist/Types/Monitor/SqlDatabaseType.js.map +1 -0
- package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js +2 -0
- package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js.map +1 -0
- package/build/dist/Types/Permission.js +10 -84
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Runbook/RunbookStepType.js +1 -0
- package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
- package/build/dist/Types/Workflow/ComponentID.js +1 -0
- package/build/dist/Types/Workflow/ComponentID.js.map +1 -1
- package/build/dist/Types/Workflow/Components/AI.js +135 -0
- package/build/dist/Types/Workflow/Components/AI.js.map +1 -0
- package/build/dist/Types/Workflow/Components.js +7 -0
- package/build/dist/Types/Workflow/Components.js.map +1 -1
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -1
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +9 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +1 -1
- package/build/dist/UI/Components/Table/Table.js +28 -2
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Utils/TableColumnsToCsv.js +291 -0
- package/build/dist/UI/Utils/TableColumnsToCsv.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js +1 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/package.json +1 -1
- package/Models/DatabaseModels/AIAgentTask.ts +0 -660
- package/Models/DatabaseModels/AIAgentTaskLog.ts +0 -426
- package/Models/DatabaseModels/AIAgentTaskTelemetryException.ts +0 -399
- package/Models/DatabaseModels/ServiceCodeRepository.ts +0 -647
- package/Server/Services/AIAgentTaskService.ts +0 -240
- package/Server/Services/AIAgentTaskTelemetryExceptionService.ts +0 -39
- package/Server/Services/ServiceCodeRepositoryService.ts +0 -55
- package/Tests/Server/Services/AIAgentTaskServiceClaim.test.ts +0 -146
- package/Types/AI/AIAgentTaskMetadata.ts +0 -25
- package/Types/AI/AIAgentTaskType.ts +0 -40
- package/build/dist/Models/DatabaseModels/AIAgentTask.js +0 -691
- package/build/dist/Models/DatabaseModels/AIAgentTask.js.map +0 -1
- package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js +0 -447
- package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js.map +0 -1
- package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js +0 -415
- package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js.map +0 -1
- package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js +0 -665
- package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js.map +0 -1
- package/build/dist/Server/Services/AIAgentTaskLogService.js.map +0 -1
- package/build/dist/Server/Services/AIAgentTaskService.js +0 -217
- package/build/dist/Server/Services/AIAgentTaskService.js.map +0 -1
- package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js +0 -36
- package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js.map +0 -1
- package/build/dist/Server/Services/ServiceCodeRepositoryService.js +0 -54
- package/build/dist/Server/Services/ServiceCodeRepositoryService.js.map +0 -1
- package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js.map +0 -1
- package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js.map +0 -1
- package/build/dist/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.js.map +0 -1
- package/build/dist/Server/Utils/AI/Sentinel/InvestigationQueue.js.map +0 -1
- package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js.map +0 -1
- package/build/dist/Server/Utils/AI/Sentinel/SentinelMemory.js.map +0 -1
- package/build/dist/Server/Utils/AI/Toolbox/SentinelActionTools.js.map +0 -1
- package/build/dist/Types/AI/AIAgentTaskMetadata.js +0 -6
- package/build/dist/Types/AI/AIAgentTaskMetadata.js.map +0 -1
- package/build/dist/Types/AI/AIAgentTaskType.js +0 -29
- package/build/dist/Types/AI/AIAgentTaskType.js.map +0 -1
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import OneUptimeDate from "../../../../../../Types/Date";
|
|
2
|
+
import SortOrder from "../../../../../../Types/BaseDatabase/SortOrder";
|
|
3
|
+
import InBetween from "../../../../../../Types/BaseDatabase/InBetween";
|
|
4
|
+
import { LIMIT_PER_PROJECT } from "../../../../../../Types/Database/LimitMax";
|
|
5
|
+
import AIInsightType from "../../../../../../Types/AI/AIInsightType";
|
|
6
|
+
import AIInsightSeverity from "../../../../../../Types/AI/AIInsightSeverity";
|
|
7
|
+
import TelemetryExceptionService from "../../../../../Services/TelemetryExceptionService";
|
|
8
|
+
import ExceptionInstanceService from "../../../../../Services/ExceptionInstanceService";
|
|
9
|
+
import ServiceService from "../../../../../Services/ServiceService";
|
|
10
|
+
import QueryHelper from "../../../../../Types/Database/QueryHelper";
|
|
11
|
+
/*
|
|
12
|
+
* ExceptionSpike — an ESTABLISHED exception (first seen more than a day
|
|
13
|
+
* ago) whose recent hourly occurrence rate blew past its own 24-hour
|
|
14
|
+
* baseline, including the dormant-awakening case (an old exception that was
|
|
15
|
+
* quiet all day suddenly firing). Candidates come cheap from Postgres
|
|
16
|
+
* (group table); the actual rates come from two ClickHouse counts per
|
|
17
|
+
* candidate (fingerprint bloom index + time range — the exception-monitor
|
|
18
|
+
* count idiom). Deterministic — no LLM anywhere in this detector.
|
|
19
|
+
*/
|
|
20
|
+
// The spike window: occurrences in the last hour, compared to...
|
|
21
|
+
export const EXCEPTION_SPIKE_RECENT_WINDOW_HOURS = 1;
|
|
22
|
+
/*
|
|
23
|
+
* ...the exception's own average hourly rate over the 24 hours BEFORE the
|
|
24
|
+
* spike window. Self-baselining means a chronically noisy exception does
|
|
25
|
+
* not alert on its normal noise.
|
|
26
|
+
*/
|
|
27
|
+
export const EXCEPTION_SPIKE_BASELINE_WINDOW_HOURS = 24;
|
|
28
|
+
/*
|
|
29
|
+
* Absolute floor: below 10 occurrences/hour a "5x spike" can be 2→10 raw
|
|
30
|
+
* events — statistically meaningless and guaranteed inbox noise.
|
|
31
|
+
*/
|
|
32
|
+
export const EXCEPTION_SPIKE_MIN_RECENT_COUNT = 10;
|
|
33
|
+
/*
|
|
34
|
+
* Rate multiplier that counts as a spike. The baseline hourly average is
|
|
35
|
+
* floored at 1 (see evaluateSpike) so near-zero baselines don't produce
|
|
36
|
+
* infinite multipliers; the dormant case (prior24 == 0, recent >= 10) then
|
|
37
|
+
* falls out of the same rule automatically.
|
|
38
|
+
*/
|
|
39
|
+
export const EXCEPTION_SPIKE_MIN_MULTIPLIER = 5;
|
|
40
|
+
// A >= 10x spike is a step change, not a fluctuation — escalate to High.
|
|
41
|
+
export const EXCEPTION_SPIKE_HIGH_SEVERITY_MULTIPLIER = 10;
|
|
42
|
+
/*
|
|
43
|
+
* Candidate cap per scan tick: two ClickHouse counts per candidate, so 25
|
|
44
|
+
* candidates = 50 bounded point queries. Sorted by lifetime occurrence
|
|
45
|
+
* count so the perennial heavy hitters are always inspected first.
|
|
46
|
+
*/
|
|
47
|
+
export const EXCEPTION_SPIKE_CANDIDATE_LIMIT = 25;
|
|
48
|
+
// Titles must stay scannable in a list — truncate long exception messages.
|
|
49
|
+
export const EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH = 80;
|
|
50
|
+
export default class ExceptionSpikeDetector {
|
|
51
|
+
constructor() {
|
|
52
|
+
this.insightType = AIInsightType.ExceptionSpike;
|
|
53
|
+
}
|
|
54
|
+
/*
|
|
55
|
+
* Pure decision: recent-hour count vs the prior 24h window count.
|
|
56
|
+
* Spike ⇔ recent >= EXCEPTION_SPIKE_MIN_RECENT_COUNT AND
|
|
57
|
+
* recent >= EXCEPTION_SPIKE_MIN_MULTIPLIER * max(prior/24, 1).
|
|
58
|
+
*/
|
|
59
|
+
static evaluateSpike(recentCount, priorWindowCount) {
|
|
60
|
+
const baselineHourlyAverage = priorWindowCount / EXCEPTION_SPIKE_BASELINE_WINDOW_HOURS;
|
|
61
|
+
const effectiveBaseline = Math.max(baselineHourlyAverage, 1);
|
|
62
|
+
const multiplier = recentCount / effectiveBaseline;
|
|
63
|
+
const isSpike = recentCount >= EXCEPTION_SPIKE_MIN_RECENT_COUNT &&
|
|
64
|
+
multiplier >= EXCEPTION_SPIKE_MIN_MULTIPLIER;
|
|
65
|
+
return {
|
|
66
|
+
isSpike,
|
|
67
|
+
multiplier,
|
|
68
|
+
severity: multiplier >= EXCEPTION_SPIKE_HIGH_SEVERITY_MULTIPLIER
|
|
69
|
+
? AIInsightSeverity.High
|
|
70
|
+
: AIInsightSeverity.Medium,
|
|
71
|
+
baselineHourlyAverage,
|
|
72
|
+
isDormantAwakening: priorWindowCount === 0 &&
|
|
73
|
+
recentCount >= EXCEPTION_SPIKE_MIN_RECENT_COUNT,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/*
|
|
77
|
+
* Human label for the exception: the type when present, else the first
|
|
78
|
+
* EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH characters of the message.
|
|
79
|
+
*/
|
|
80
|
+
static buildExceptionLabel(exceptionType, message) {
|
|
81
|
+
if (exceptionType && exceptionType.trim().length > 0) {
|
|
82
|
+
return exceptionType.trim();
|
|
83
|
+
}
|
|
84
|
+
const trimmedMessage = (message || "").trim();
|
|
85
|
+
if (trimmedMessage.length === 0) {
|
|
86
|
+
return "Unknown exception";
|
|
87
|
+
}
|
|
88
|
+
if (trimmedMessage.length <= EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH) {
|
|
89
|
+
return trimmedMessage;
|
|
90
|
+
}
|
|
91
|
+
return `${trimmedMessage.slice(0, EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH)}…`;
|
|
92
|
+
}
|
|
93
|
+
// Stable dedupe key, keyed on the exception GROUP id (ingest dedupe unit).
|
|
94
|
+
static buildFingerprint(telemetryExceptionId) {
|
|
95
|
+
return `exception-spike:${telemetryExceptionId}`;
|
|
96
|
+
}
|
|
97
|
+
async detect(context) {
|
|
98
|
+
const recentWindowStart = OneUptimeDate.addRemoveHours(context.now, -1 * EXCEPTION_SPIKE_RECENT_WINDOW_HOURS);
|
|
99
|
+
const priorWindowStart = OneUptimeDate.addRemoveHours(recentWindowStart, -1 * EXCEPTION_SPIKE_BASELINE_WINDOW_HOURS);
|
|
100
|
+
const establishedBefore = OneUptimeDate.addRemoveHours(context.now, -1 * EXCEPTION_SPIKE_BASELINE_WINDOW_HOURS);
|
|
101
|
+
/*
|
|
102
|
+
* Candidates: established exception groups (born before the baseline
|
|
103
|
+
* window so they HAVE a baseline) that were active in the spike
|
|
104
|
+
* window. Anything younger is NewExceptionDetector's territory.
|
|
105
|
+
*/
|
|
106
|
+
const candidateQuery = {
|
|
107
|
+
projectId: context.projectId,
|
|
108
|
+
lastSeenAt: QueryHelper.greaterThanEqualTo(recentWindowStart),
|
|
109
|
+
firstSeenAt: QueryHelper.lessThan(establishedBefore),
|
|
110
|
+
isResolved: false,
|
|
111
|
+
isArchived: false,
|
|
112
|
+
};
|
|
113
|
+
const exceptions = await TelemetryExceptionService.findBy({
|
|
114
|
+
query: candidateQuery,
|
|
115
|
+
select: {
|
|
116
|
+
_id: true,
|
|
117
|
+
message: true,
|
|
118
|
+
exceptionType: true,
|
|
119
|
+
fingerprint: true,
|
|
120
|
+
occuranceCount: true,
|
|
121
|
+
firstSeenAt: true,
|
|
122
|
+
primaryEntityId: true,
|
|
123
|
+
},
|
|
124
|
+
sort: {
|
|
125
|
+
occuranceCount: SortOrder.Descending,
|
|
126
|
+
},
|
|
127
|
+
limit: EXCEPTION_SPIKE_CANDIDATE_LIMIT,
|
|
128
|
+
skip: 0,
|
|
129
|
+
props: { isRoot: true },
|
|
130
|
+
});
|
|
131
|
+
const candidates = [];
|
|
132
|
+
for (const exception of exceptions) {
|
|
133
|
+
if (!exception.id || !exception.fingerprint) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
/*
|
|
137
|
+
* Two bounded ClickHouse counts (fingerprint bloom + time range —
|
|
138
|
+
* the MonitorTelemetryMonitor.monitorException idiom). Occurrence
|
|
139
|
+
* `time` is client-reported, so both windows use the same clock and
|
|
140
|
+
* skew cancels out within the comparison.
|
|
141
|
+
*/
|
|
142
|
+
const recentCount = await ExceptionInstanceService.countBy({
|
|
143
|
+
query: {
|
|
144
|
+
projectId: context.projectId,
|
|
145
|
+
fingerprint: exception.fingerprint,
|
|
146
|
+
time: new InBetween(recentWindowStart, context.now),
|
|
147
|
+
},
|
|
148
|
+
skip: 0,
|
|
149
|
+
limit: LIMIT_PER_PROJECT,
|
|
150
|
+
props: { isRoot: true },
|
|
151
|
+
});
|
|
152
|
+
const priorCount = await ExceptionInstanceService.countBy({
|
|
153
|
+
query: {
|
|
154
|
+
projectId: context.projectId,
|
|
155
|
+
fingerprint: exception.fingerprint,
|
|
156
|
+
time: new InBetween(priorWindowStart, recentWindowStart),
|
|
157
|
+
},
|
|
158
|
+
skip: 0,
|
|
159
|
+
limit: LIMIT_PER_PROJECT,
|
|
160
|
+
props: { isRoot: true },
|
|
161
|
+
});
|
|
162
|
+
const decision = ExceptionSpikeDetector.evaluateSpike(recentCount.toNumber(), priorCount.toNumber());
|
|
163
|
+
if (!decision.isSpike) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const serviceName = await this.resolveServiceName(exception.primaryEntityId);
|
|
167
|
+
const label = ExceptionSpikeDetector.buildExceptionLabel(exception.exceptionType, exception.message);
|
|
168
|
+
const firstSeenAtIso = exception.firstSeenAt
|
|
169
|
+
? exception.firstSeenAt.toISOString()
|
|
170
|
+
: undefined;
|
|
171
|
+
const detailLines = [
|
|
172
|
+
decision.isDormantAwakening
|
|
173
|
+
? "**Dormant exception woke up**"
|
|
174
|
+
: "**Exception spike detected**",
|
|
175
|
+
"",
|
|
176
|
+
`- Exception: \`${label}\``,
|
|
177
|
+
];
|
|
178
|
+
if (exception.message) {
|
|
179
|
+
detailLines.push(`- Message: ${exception.message}`);
|
|
180
|
+
}
|
|
181
|
+
if (serviceName) {
|
|
182
|
+
detailLines.push(`- Service: ${serviceName}`);
|
|
183
|
+
}
|
|
184
|
+
detailLines.push(`- Occurrences in the last ${EXCEPTION_SPIKE_RECENT_WINDOW_HOURS}h: ${recentCount.toNumber()}`, `- Baseline: ${decision.baselineHourlyAverage.toFixed(2)}/hour over the prior ${EXCEPTION_SPIKE_BASELINE_WINDOW_HOURS}h (${priorCount.toNumber()} total)`, `- Spike multiplier: ${decision.multiplier.toFixed(1)}x`, `- Exception first seen: ${firstSeenAtIso || "unknown"} (lifetime occurrences: ${exception.occuranceCount || 0})`);
|
|
185
|
+
candidates.push({
|
|
186
|
+
insightType: AIInsightType.ExceptionSpike,
|
|
187
|
+
fingerprint: ExceptionSpikeDetector.buildFingerprint(exception.id.toString()),
|
|
188
|
+
title: `Exception spike: ${label} at ${decision.multiplier.toFixed(1)}x normal rate${serviceName ? ` in ${serviceName}` : ""}`,
|
|
189
|
+
detailMarkdown: detailLines.join("\n"),
|
|
190
|
+
severity: decision.severity,
|
|
191
|
+
serviceName: serviceName || undefined,
|
|
192
|
+
telemetryServiceId: serviceName ? exception.primaryEntityId : undefined,
|
|
193
|
+
telemetryExceptionId: exception.id,
|
|
194
|
+
evidence: {
|
|
195
|
+
exception: {
|
|
196
|
+
exceptionMessage: exception.message,
|
|
197
|
+
exceptionType: exception.exceptionType,
|
|
198
|
+
recentOccurrenceCount: recentCount.toNumber(),
|
|
199
|
+
baselineHourlyAverage: decision.baselineHourlyAverage,
|
|
200
|
+
spikeMultiplier: decision.multiplier,
|
|
201
|
+
totalOccurrenceCount: exception.occuranceCount,
|
|
202
|
+
firstSeenAt: firstSeenAtIso,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return candidates;
|
|
208
|
+
}
|
|
209
|
+
/*
|
|
210
|
+
* Best-effort service attribution: primaryEntityId is polymorphic and
|
|
211
|
+
* findOneById returns null for non-Service kinds — the insight then
|
|
212
|
+
* ships without a service name.
|
|
213
|
+
*/
|
|
214
|
+
async resolveServiceName(primaryEntityId) {
|
|
215
|
+
if (!primaryEntityId) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
const service = await ServiceService.findOneById({
|
|
219
|
+
id: primaryEntityId,
|
|
220
|
+
select: { name: true },
|
|
221
|
+
props: { isRoot: true },
|
|
222
|
+
});
|
|
223
|
+
return (service === null || service === void 0 ? void 0 : service.name) || null;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=ExceptionSpikeDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExceptionSpikeDetector.js","sourceRoot":"","sources":["../../../../../../../../Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import NewExceptionDetector from "./NewExceptionDetector";
|
|
2
|
+
import ExceptionSpikeDetector from "./ExceptionSpikeDetector";
|
|
3
|
+
import ErrorLogSpikeDetector from "./ErrorLogSpikeDetector";
|
|
4
|
+
import TraceLatencyRegressionDetector from "./TraceLatencyRegressionDetector";
|
|
5
|
+
import MetricDriftDetector from "./MetricDriftDetector";
|
|
6
|
+
/*
|
|
7
|
+
* The detector registry. All five deterministic sensors — no LLM in any of
|
|
8
|
+
* them. Order matters for the scanner's per-project new-insight cap: the
|
|
9
|
+
* signals most likely to be actionable code problems (exceptions, then
|
|
10
|
+
* latency) come before the softer volume/drift signals, so when the cap
|
|
11
|
+
* bites it drops the softest findings first. The scanner runs every
|
|
12
|
+
* detector with per-detector error isolation — a detector that throws
|
|
13
|
+
* must not silence its siblings.
|
|
14
|
+
*/
|
|
15
|
+
export default class InsightDetectors {
|
|
16
|
+
static getAllDetectors() {
|
|
17
|
+
return [
|
|
18
|
+
new NewExceptionDetector(),
|
|
19
|
+
new ExceptionSpikeDetector(),
|
|
20
|
+
new TraceLatencyRegressionDetector(),
|
|
21
|
+
new ErrorLogSpikeDetector(),
|
|
22
|
+
new MetricDriftDetector(),
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=Index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Index.js","sourceRoot":"","sources":["../../../../../../../../Server/Utils/AI/SRE/Insights/Detectors/Index.ts"],"names":[],"mappings":"AACA,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAC1D,OAAO,sBAAsB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,qBAAqB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,8BAA8B,MAAM,kCAAkC,CAAC;AAC9E,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,OAAO,gBAAgB;IAC5B,MAAM,CAAC,eAAe;QAC3B,OAAO;YACL,IAAI,oBAAoB,EAAE;YAC1B,IAAI,sBAAsB,EAAE;YAC5B,IAAI,8BAA8B,EAAE;YACpC,IAAI,qBAAqB,EAAE;YAC3B,IAAI,mBAAmB,EAAE;SAC1B,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import AIInsightType from "../../../../../../Types/AI/AIInsightType";
|
|
2
|
+
import AIInsightSeverity from "../../../../../../Types/AI/AIInsightSeverity";
|
|
3
|
+
import MetricBaselineService, { MetricBaselineService as MetricBaselineServiceClass, } from "../../../../../Services/MetricBaselineService";
|
|
4
|
+
/*
|
|
5
|
+
* MetricDrift — a metric's mean over the last 7 days drifted substantially
|
|
6
|
+
* from its mean over the prior 7 days, per (metric name, entity) cell. The
|
|
7
|
+
* data comes from two GROUP BY finalization queries over the
|
|
8
|
+
* MetricBaselineHourly materialized view (already maintained for anomaly
|
|
9
|
+
* monitors — this detector adds no write load); the recent/prior join and
|
|
10
|
+
* the drift decision are pure functions here so they are unit-testable
|
|
11
|
+
* without any ClickHouse.
|
|
12
|
+
*
|
|
13
|
+
* Drift severity is always Low and NEVER routes to an auto-fix: direction
|
|
14
|
+
* and goodness are unknowable without semantics (a 60% drop in latency is
|
|
15
|
+
* a win; a 60% drop in throughput is an outage). It is a "look here"
|
|
16
|
+
* signal, nothing more. Deterministic — no LLM anywhere in this detector.
|
|
17
|
+
*/
|
|
18
|
+
/*
|
|
19
|
+
* Both windows need this many raw samples per cell before their means are
|
|
20
|
+
* comparable — below it a single noisy hour can swing the mean by more
|
|
21
|
+
* than the drift threshold.
|
|
22
|
+
*/
|
|
23
|
+
export const METRIC_DRIFT_MIN_SAMPLES_PER_WINDOW = 100;
|
|
24
|
+
/*
|
|
25
|
+
* Relative mean change (|recent-prior| / |prior|) that counts as drift.
|
|
26
|
+
* 50% is far outside normal week-to-week variation for the sample-count-
|
|
27
|
+
* gated cells, so the inbox only sees step changes.
|
|
28
|
+
*/
|
|
29
|
+
export const METRIC_DRIFT_MIN_RELATIVE_CHANGE = 0.5;
|
|
30
|
+
/*
|
|
31
|
+
* At most this many drift insights per scan tick, ranked by |relative
|
|
32
|
+
* change|. A platform-wide shift moves hundreds of metrics at once — the
|
|
33
|
+
* top movers tell the story, the rest are echoes.
|
|
34
|
+
*/
|
|
35
|
+
export const METRIC_DRIFT_MAX_INSIGHTS = 5;
|
|
36
|
+
/*
|
|
37
|
+
* Rows fetched per drift window (recent/prior), ranked by sample count.
|
|
38
|
+
* Bounded because the detector joins the windows in JS. Mirrors
|
|
39
|
+
* MetricBaselineService.DRIFT_MAX_ROWS_PER_WINDOW — the service clamps to
|
|
40
|
+
* that cap regardless.
|
|
41
|
+
*/
|
|
42
|
+
export const METRIC_DRIFT_ROWS_PER_WINDOW = MetricBaselineServiceClass.DRIFT_MAX_ROWS_PER_WINDOW;
|
|
43
|
+
export default class MetricDriftDetector {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.insightType = AIInsightType.MetricDrift;
|
|
46
|
+
}
|
|
47
|
+
/*
|
|
48
|
+
* Pure join + decision: pair each (name, entity) cell's recent and
|
|
49
|
+
* prior rows, gate on sample counts, and keep cells whose relative mean
|
|
50
|
+
* change clears the threshold. Cells with a zero prior mean are skipped
|
|
51
|
+
* — relative change against a zero baseline is undefined, and
|
|
52
|
+
* "metric appeared" is NewException/ErrorLogSpike territory, not drift.
|
|
53
|
+
* Returns the top METRIC_DRIFT_MAX_INSIGHTS movers by |relative change|.
|
|
54
|
+
*/
|
|
55
|
+
static evaluateDrift(rows) {
|
|
56
|
+
const recentByCell = new Map();
|
|
57
|
+
const priorByCell = new Map();
|
|
58
|
+
for (const row of rows) {
|
|
59
|
+
// \u0000 cannot appear in either component — collision-free key.
|
|
60
|
+
const cellKey = `${row.name}\u0000${row.primaryEntityId}`;
|
|
61
|
+
if (row.window === "recent") {
|
|
62
|
+
recentByCell.set(cellKey, row);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
priorByCell.set(cellKey, row);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const findings = [];
|
|
69
|
+
for (const [cellKey, recent] of recentByCell) {
|
|
70
|
+
const prior = priorByCell.get(cellKey);
|
|
71
|
+
if (!prior) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (recent.sampleCount < METRIC_DRIFT_MIN_SAMPLES_PER_WINDOW ||
|
|
75
|
+
prior.sampleCount < METRIC_DRIFT_MIN_SAMPLES_PER_WINDOW) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (prior.mean === 0) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const relativeChange = (recent.mean - prior.mean) / Math.abs(prior.mean);
|
|
82
|
+
if (Math.abs(relativeChange) < METRIC_DRIFT_MIN_RELATIVE_CHANGE) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
findings.push({
|
|
86
|
+
metricName: recent.name,
|
|
87
|
+
primaryEntityId: recent.primaryEntityId,
|
|
88
|
+
recentMean: recent.mean,
|
|
89
|
+
priorMean: prior.mean,
|
|
90
|
+
relativeChange,
|
|
91
|
+
recentSampleCount: recent.sampleCount,
|
|
92
|
+
priorSampleCount: prior.sampleCount,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
findings.sort((a, b) => {
|
|
96
|
+
if (Math.abs(b.relativeChange) !== Math.abs(a.relativeChange)) {
|
|
97
|
+
return Math.abs(b.relativeChange) - Math.abs(a.relativeChange);
|
|
98
|
+
}
|
|
99
|
+
// Deterministic tie-break so scan ticks are reproducible.
|
|
100
|
+
const aKey = `${a.metricName}\u0000${a.primaryEntityId}`;
|
|
101
|
+
const bKey = `${b.metricName}\u0000${b.primaryEntityId}`;
|
|
102
|
+
return aKey.localeCompare(bKey);
|
|
103
|
+
});
|
|
104
|
+
return findings.slice(0, METRIC_DRIFT_MAX_INSIGHTS);
|
|
105
|
+
}
|
|
106
|
+
// Signed percent label, e.g. "+62%" / "-71%".
|
|
107
|
+
static formatChangePercent(relativeChange) {
|
|
108
|
+
const percent = Math.round(relativeChange * 100);
|
|
109
|
+
return `${percent >= 0 ? "+" : ""}${percent}%`;
|
|
110
|
+
}
|
|
111
|
+
// Stable dedupe key per (metric name, entity) cell.
|
|
112
|
+
static buildFingerprint(metricName, primaryEntityId) {
|
|
113
|
+
return `metric-drift:${metricName}:${primaryEntityId}`;
|
|
114
|
+
}
|
|
115
|
+
async detect(context) {
|
|
116
|
+
const rows = await MetricBaselineService.getWeekOverWeekDrift({
|
|
117
|
+
projectId: context.projectId,
|
|
118
|
+
limitPerWindow: METRIC_DRIFT_ROWS_PER_WINDOW,
|
|
119
|
+
});
|
|
120
|
+
const findings = MetricDriftDetector.evaluateDrift(rows);
|
|
121
|
+
return findings.map((finding) => {
|
|
122
|
+
const changeLabel = MetricDriftDetector.formatChangePercent(finding.relativeChange);
|
|
123
|
+
const detailLines = [
|
|
124
|
+
"**Metric drift detected (week-over-week)**",
|
|
125
|
+
"",
|
|
126
|
+
`- Metric: \`${finding.metricName}\``,
|
|
127
|
+
];
|
|
128
|
+
if (finding.primaryEntityId) {
|
|
129
|
+
detailLines.push(`- Entity: \`${finding.primaryEntityId}\``);
|
|
130
|
+
}
|
|
131
|
+
detailLines.push(`- Recent 7-day mean: ${finding.recentMean.toFixed(4)} (${finding.recentSampleCount} samples)`, `- Prior 7-day mean: ${finding.priorMean.toFixed(4)} (${finding.priorSampleCount} samples)`, `- Relative change: ${changeLabel}`, "", "Direction and goodness are metric-specific — this is a heads-up, not an alarm.");
|
|
132
|
+
return {
|
|
133
|
+
insightType: AIInsightType.MetricDrift,
|
|
134
|
+
fingerprint: MetricDriftDetector.buildFingerprint(finding.metricName, finding.primaryEntityId),
|
|
135
|
+
title: `Metric drift: ${finding.metricName} ${changeLabel} week-over-week`,
|
|
136
|
+
detailMarkdown: detailLines.join("\n"),
|
|
137
|
+
/*
|
|
138
|
+
* Always Low: without metric semantics the detector cannot know
|
|
139
|
+
* whether the drift is good or bad — it must never outrank a
|
|
140
|
+
* concrete exception or latency finding.
|
|
141
|
+
*/
|
|
142
|
+
severity: AIInsightSeverity.Low,
|
|
143
|
+
metricName: finding.metricName,
|
|
144
|
+
evidence: {
|
|
145
|
+
metricDrift: {
|
|
146
|
+
metricName: finding.metricName,
|
|
147
|
+
primaryEntityId: finding.primaryEntityId || undefined,
|
|
148
|
+
recentWeekMean: finding.recentMean,
|
|
149
|
+
priorWeekMean: finding.priorMean,
|
|
150
|
+
relativeChangePercent: finding.relativeChange * 100,
|
|
151
|
+
recentSampleCount: finding.recentSampleCount,
|
|
152
|
+
priorSampleCount: finding.priorSampleCount,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=MetricDriftDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetricDriftDetector.js","sourceRoot":"","sources":["../../../../../../../../Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import OneUptimeDate from "../../../../../../Types/Date";
|
|
2
|
+
import SortOrder from "../../../../../../Types/BaseDatabase/SortOrder";
|
|
3
|
+
import AIInsightType from "../../../../../../Types/AI/AIInsightType";
|
|
4
|
+
import AIInsightSeverity from "../../../../../../Types/AI/AIInsightSeverity";
|
|
5
|
+
import TelemetryExceptionService from "../../../../../Services/TelemetryExceptionService";
|
|
6
|
+
import ServiceService from "../../../../../Services/ServiceService";
|
|
7
|
+
import QueryHelper from "../../../../../Types/Database/QueryHelper";
|
|
8
|
+
/*
|
|
9
|
+
* NewException — a brand-new failure mode in the code: a telemetry
|
|
10
|
+
* exception group whose FIRST occurrence is inside the lookback window and
|
|
11
|
+
* that is already recurring (not a one-off blip). Postgres-only and cheap:
|
|
12
|
+
* the exception groups table carries firstSeenAt and the lifetime
|
|
13
|
+
* occurrence count, so no ClickHouse scan is needed at all. Deterministic —
|
|
14
|
+
* no LLM anywhere in this detector.
|
|
15
|
+
*/
|
|
16
|
+
/*
|
|
17
|
+
* Only exceptions born within this window count as "new". 24h matches the
|
|
18
|
+
* scanner's dedupe horizon: with a 15-minute scan tick every new exception
|
|
19
|
+
* is seen many times within the window, and the fingerprint upsert
|
|
20
|
+
* refreshes the same insight instead of duplicating it.
|
|
21
|
+
*/
|
|
22
|
+
export const NEW_EXCEPTION_LOOKBACK_HOURS = 24;
|
|
23
|
+
/*
|
|
24
|
+
* A single occurrence is noise (a deploy hiccup, a one-off bad request).
|
|
25
|
+
* Three occurrences means the failure path is being re-hit — worth a
|
|
26
|
+
* human's attention.
|
|
27
|
+
*/
|
|
28
|
+
export const NEW_EXCEPTION_MIN_OCCURRENCE_COUNT = 3;
|
|
29
|
+
/*
|
|
30
|
+
* At 50+ occurrences inside its first day the exception is hammering a hot
|
|
31
|
+
* path — escalate to High so it sorts above the long tail.
|
|
32
|
+
*/
|
|
33
|
+
export const NEW_EXCEPTION_HIGH_SEVERITY_OCCURRENCE_COUNT = 50;
|
|
34
|
+
/*
|
|
35
|
+
* Upper bound on candidates per scan tick. Mirrors the TopExceptionsTool
|
|
36
|
+
* cap — a project melting down does not need 500 insights, and the scanner
|
|
37
|
+
* additionally caps new insights per tick.
|
|
38
|
+
*/
|
|
39
|
+
export const NEW_EXCEPTION_CANDIDATE_LIMIT = 25;
|
|
40
|
+
// Titles must stay scannable in a list — truncate long exception messages.
|
|
41
|
+
export const NEW_EXCEPTION_TITLE_MESSAGE_MAX_LENGTH = 80;
|
|
42
|
+
export default class NewExceptionDetector {
|
|
43
|
+
constructor() {
|
|
44
|
+
this.insightType = AIInsightType.NewException;
|
|
45
|
+
}
|
|
46
|
+
/*
|
|
47
|
+
* Pure decision: does a lifetime occurrence count qualify, and how
|
|
48
|
+
* urgent is it. The query already filters on the minimum count — this
|
|
49
|
+
* re-check keeps the rule in one unit-testable place.
|
|
50
|
+
*/
|
|
51
|
+
static evaluateNewException(occurrenceCount) {
|
|
52
|
+
return {
|
|
53
|
+
qualifies: occurrenceCount >= NEW_EXCEPTION_MIN_OCCURRENCE_COUNT,
|
|
54
|
+
severity: occurrenceCount >= NEW_EXCEPTION_HIGH_SEVERITY_OCCURRENCE_COUNT
|
|
55
|
+
? AIInsightSeverity.High
|
|
56
|
+
: AIInsightSeverity.Medium,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/*
|
|
60
|
+
* Human label for the exception: the type when present, else the first
|
|
61
|
+
* NEW_EXCEPTION_TITLE_MESSAGE_MAX_LENGTH characters of the message.
|
|
62
|
+
*/
|
|
63
|
+
static buildExceptionLabel(exceptionType, message) {
|
|
64
|
+
if (exceptionType && exceptionType.trim().length > 0) {
|
|
65
|
+
return exceptionType.trim();
|
|
66
|
+
}
|
|
67
|
+
const trimmedMessage = (message || "").trim();
|
|
68
|
+
if (trimmedMessage.length === 0) {
|
|
69
|
+
return "Unknown exception";
|
|
70
|
+
}
|
|
71
|
+
if (trimmedMessage.length <= NEW_EXCEPTION_TITLE_MESSAGE_MAX_LENGTH) {
|
|
72
|
+
return trimmedMessage;
|
|
73
|
+
}
|
|
74
|
+
return `${trimmedMessage.slice(0, NEW_EXCEPTION_TITLE_MESSAGE_MAX_LENGTH)}…`;
|
|
75
|
+
}
|
|
76
|
+
/*
|
|
77
|
+
* Stable dedupe key. Keyed on the exception GROUP id (not the message):
|
|
78
|
+
* the group id is the ingest-side dedupe unit, so the insight refreshes
|
|
79
|
+
* instead of duplicating across scan ticks.
|
|
80
|
+
*/
|
|
81
|
+
static buildFingerprint(telemetryExceptionId) {
|
|
82
|
+
return `new-exception:${telemetryExceptionId}`;
|
|
83
|
+
}
|
|
84
|
+
async detect(context) {
|
|
85
|
+
const firstSeenSince = OneUptimeDate.addRemoveHours(context.now, -1 * NEW_EXCEPTION_LOOKBACK_HOURS);
|
|
86
|
+
const query = {
|
|
87
|
+
projectId: context.projectId,
|
|
88
|
+
firstSeenAt: QueryHelper.greaterThanEqualTo(firstSeenSince),
|
|
89
|
+
isResolved: false,
|
|
90
|
+
isArchived: false,
|
|
91
|
+
occuranceCount: QueryHelper.greaterThanEqualTo(NEW_EXCEPTION_MIN_OCCURRENCE_COUNT),
|
|
92
|
+
};
|
|
93
|
+
/*
|
|
94
|
+
* Root read with an explicit projectId in the query — the scanner is a
|
|
95
|
+
* server-side worker (monitor-worker precedent), never a user ACL.
|
|
96
|
+
*/
|
|
97
|
+
const exceptions = await TelemetryExceptionService.findBy({
|
|
98
|
+
query: query,
|
|
99
|
+
select: {
|
|
100
|
+
_id: true,
|
|
101
|
+
message: true,
|
|
102
|
+
exceptionType: true,
|
|
103
|
+
occuranceCount: true,
|
|
104
|
+
firstSeenAt: true,
|
|
105
|
+
primaryEntityId: true,
|
|
106
|
+
},
|
|
107
|
+
sort: {
|
|
108
|
+
occuranceCount: SortOrder.Descending,
|
|
109
|
+
},
|
|
110
|
+
limit: NEW_EXCEPTION_CANDIDATE_LIMIT,
|
|
111
|
+
skip: 0,
|
|
112
|
+
props: { isRoot: true },
|
|
113
|
+
});
|
|
114
|
+
const candidates = [];
|
|
115
|
+
for (const exception of exceptions) {
|
|
116
|
+
const occurrenceCount = exception.occuranceCount || 0;
|
|
117
|
+
const decision = NewExceptionDetector.evaluateNewException(occurrenceCount);
|
|
118
|
+
if (!decision.qualifies || !exception.id) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const serviceName = await this.resolveServiceName(exception.primaryEntityId);
|
|
122
|
+
const label = NewExceptionDetector.buildExceptionLabel(exception.exceptionType, exception.message);
|
|
123
|
+
const firstSeenAtIso = exception.firstSeenAt
|
|
124
|
+
? exception.firstSeenAt.toISOString()
|
|
125
|
+
: undefined;
|
|
126
|
+
const detailLines = [
|
|
127
|
+
"**New exception detected**",
|
|
128
|
+
"",
|
|
129
|
+
`- Exception: \`${label}\``,
|
|
130
|
+
];
|
|
131
|
+
if (exception.message) {
|
|
132
|
+
detailLines.push(`- Message: ${exception.message}`);
|
|
133
|
+
}
|
|
134
|
+
if (serviceName) {
|
|
135
|
+
detailLines.push(`- Service: ${serviceName}`);
|
|
136
|
+
}
|
|
137
|
+
detailLines.push(`- First seen: ${firstSeenAtIso || "unknown"} (within the last ${NEW_EXCEPTION_LOOKBACK_HOURS}h)`, `- Occurrences so far: ${occurrenceCount}`);
|
|
138
|
+
candidates.push({
|
|
139
|
+
insightType: AIInsightType.NewException,
|
|
140
|
+
fingerprint: NewExceptionDetector.buildFingerprint(exception.id.toString()),
|
|
141
|
+
title: `New exception: ${label}${serviceName ? ` in ${serviceName}` : ""}`,
|
|
142
|
+
detailMarkdown: detailLines.join("\n"),
|
|
143
|
+
severity: decision.severity,
|
|
144
|
+
serviceName: serviceName || undefined,
|
|
145
|
+
telemetryServiceId: serviceName ? exception.primaryEntityId : undefined,
|
|
146
|
+
telemetryExceptionId: exception.id,
|
|
147
|
+
evidence: {
|
|
148
|
+
exception: {
|
|
149
|
+
exceptionMessage: exception.message,
|
|
150
|
+
exceptionType: exception.exceptionType,
|
|
151
|
+
totalOccurrenceCount: occurrenceCount,
|
|
152
|
+
firstSeenAt: firstSeenAtIso,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return candidates;
|
|
158
|
+
}
|
|
159
|
+
/*
|
|
160
|
+
* Best-effort service attribution: primaryEntityId is polymorphic
|
|
161
|
+
* (Service/Host/DockerHost/...), and findOneById simply returns null for
|
|
162
|
+
* the non-Service kinds (AIInvestigationAPI precedent) — the insight then
|
|
163
|
+
* ships without a service name.
|
|
164
|
+
*/
|
|
165
|
+
async resolveServiceName(primaryEntityId) {
|
|
166
|
+
if (!primaryEntityId) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
const service = await ServiceService.findOneById({
|
|
170
|
+
id: primaryEntityId,
|
|
171
|
+
select: { name: true },
|
|
172
|
+
props: { isRoot: true },
|
|
173
|
+
});
|
|
174
|
+
return (service === null || service === void 0 ? void 0 : service.name) || null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=NewExceptionDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewExceptionDetector.js","sourceRoot":"","sources":["../../../../../../../../Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts"],"names":[],"mappings":"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"}
|