Files
knowledge-governance/internal/governance/monitor.go
T
姚章浩 63f3b2c503 feat(governance): policy-driven ingestion from catalog annotations
Annotation in 来源与目录 is now the only import decision surface:
- migration 000033: catalog_import_intents (durable, rescan-proof per-file
  intent with locator snapshot + fetch lifecycle), source_items.policy_state,
  planned publication state, ui_setting_revisions.ingestion_concurrency
- marking fans a folder decision out to per-file intents, materializes
  versioned items, reuses already-verified local bytes (compare, don't pull),
  and plans one publication per routed KB; blocked retires planned rows
  while live publications stay untouched (需下架 shows in the KB diff)
- artifact.fetch worker lane (scripts/artifact_fetch.py): DingTalk export
  tree/live box API, AList /api/fs/get direct download with SSO-redirect
  fail-closed, PP ledger via locator hash; content-level dedupe on sha256
- 开始处理 promotes planned->pending inside the claim-time concurrency budget
  from system settings; claims enforce it in SQL
- monitor overview rebuilt as knowledge-base diff: planned/needs_removal per
  KB + fetch pipeline summary; frontend lanes 待入库/需下架 replace the
  deprecated snapshot change-set confirmation
- spool: images (png/jpg/gif/bmp/webp) accepted, ppt/pptx rejected in favour
  of PDF twins; DingTalk PPT resolves its converted PDF pair
2026-09-30 10:54:07 +08:00

131 lines
5.0 KiB
Go

package governance
import "time"
type MonitorHost struct {
CPUPercent float64 `json:"cpu_percent"`
MemoryUsedBytes int64 `json:"memory_used_bytes"`
MemoryTotalBytes int64 `json:"memory_total_bytes"`
DiskUsedBytes int64 `json:"disk_used_bytes"`
DiskTotalBytes int64 `json:"disk_total_bytes"`
GPUState string `json:"gpu_state"`
GPUDetail string `json:"gpu_detail"`
Simulated bool `json:"simulated"`
}
type MonitorService struct {
Key string `json:"key"`
Name string `json:"name"`
State string `json:"state"`
Detail string `json:"detail"`
LatencyMS int `json:"latency_ms"`
ObservedAt time.Time `json:"observed_at"`
Simulated bool `json:"simulated"`
}
// ServiceHealth (P10) separates "process reachable" (Liveness) from "can
// accept work" (Readiness). not_configured and not_applicable are explicit and
// never collapse into unknown.
type ServiceHealth struct {
Key string `json:"key"`
Name string `json:"name"`
Liveness string `json:"liveness"`
Readiness string `json:"readiness"`
Reason string `json:"reason"`
LatencyMS int64 `json:"latency_ms"`
ObservedAt time.Time `json:"observed_at"`
LastSuccessAt *time.Time `json:"last_success_at"`
ConsecutiveFailures int `json:"consecutive_failures"`
Configured bool `json:"configured"`
Applicable bool `json:"applicable"`
}
type KnowledgeBaseProgress struct {
ID string `json:"id"`
Name string `json:"name"`
Visibility string `json:"visibility"`
Imported int `json:"imported"`
Completed int `json:"completed"`
Pending int `json:"pending"`
Processing int `json:"processing"`
Finalizing int `json:"finalizing"`
Failed int `json:"failed"`
Cancelled int `json:"cancelled"`
Planned int `json:"planned"`
NeedsRemoval int `json:"needs_removal"`
StalePlanned int `json:"stale_planned"`
InternalImported int `json:"internal_imported"`
InternalCompleted int `json:"internal_completed"`
ExternalImported int `json:"external_imported"`
ExternalCompleted int `json:"external_completed"`
}
// IngestionPipeline summarizes the artifact-fetch lane that sits in front of
// 待入库 so operators can see why planned items are not uploadable yet.
type IngestionPipeline struct {
FetchPending int `json:"fetch_pending"`
FetchFailed int `json:"fetch_failed"`
FetchMissing int `json:"fetch_missing"`
Concurrency int `json:"concurrency"`
}
// JobWindowMetrics reports a frozen statistical window; insufficient samples
// stay null and are never rendered as 0.
type JobWindowMetrics struct {
WindowSeconds int `json:"window_seconds"`
JobsStarted int `json:"jobs_started"`
JobsCompleted int `json:"jobs_completed"`
JobsFailed int `json:"jobs_failed"`
SuccessRate *float64 `json:"success_rate"`
FailureRate *float64 `json:"failure_rate"`
DurationAvgSeconds *float64 `json:"duration_avg_seconds"`
DurationP50Seconds *float64 `json:"duration_p50_seconds"`
DurationP95Seconds *float64 `json:"duration_p95_seconds"`
}
type QueueGauges struct {
Pending int `json:"pending"`
Running int `json:"running"`
Retry int `json:"retry"`
Failed int `json:"failed"`
OldestPendingAgeSeconds *float64 `json:"oldest_pending_age_seconds"`
}
type RunMetrics struct {
ObservedAt time.Time `json:"observed_at"`
ActiveWorkers int `json:"active_workers"`
WorkerSource string `json:"worker_source"`
Queue QueueGauges `json:"queue"`
ShortWindow JobWindowMetrics `json:"short_window"`
LongWindow JobWindowMetrics `json:"long_window"`
}
type MonitorOverview struct {
Mode string `json:"mode"`
Simulated bool `json:"simulated"`
ObservedAt time.Time `json:"observed_at"`
Host MonitorHost `json:"host"`
Services []MonitorService `json:"services"`
KnowledgeBases []KnowledgeBaseProgress `json:"knowledge_bases"`
Pipeline IngestionPipeline `json:"pipeline"`
Health []ServiceHealth `json:"health"`
}
type KnowledgeMonitorFile struct {
Name string `json:"name"`
Directory string `json:"directory"`
Visibility string `json:"visibility"`
Status string `json:"status"`
StageDetail string `json:"stage_detail"`
ElapsedSecond int `json:"elapsed_seconds"`
ErrorCode string `json:"error_code"`
}
type KnowledgeMonitorFilePage struct {
Items []KnowledgeMonitorFile `json:"items"`
Total int `json:"total"`
Limit int `json:"limit"`
Offset int `json:"offset"`
SampleOnly bool `json:"sample_only"`
}