skillhub/scanner/docs/monitoring-guide.md
XiaoSeS 3bc97ff1b8 feat(security): add security scanning system with multi-scanner support and frontend UI (#144)
* feat(security): extend scanner config with full analyzer options

Integrate skill-scanner's 8 analysis engines and policy configuration
into SkillHub's config system. Operators can now control behavioral,
LLM, Meta, AI Defense, VirusTotal, and trigger analyzers via
application.yml or environment variables.

Changes:
- Add Analyzers and Policy nested classes to SkillScannerProperties
- Create ScanOptions record to encapsulate analyzer flags
- Update SkillScannerService to pass options in /scan body and /scan-upload query params
- Wire ScanOptions through SkillScannerConfig and SkillScannerAdapter
- Extend application.yml with full scanner config block and env var overrides
- Update all tests to verify new configuration flow

All tests pass.

* feat(security): add domain model and integrate scan into publish flow

Add SCANNING/SCAN_FAILED status to SkillVersionStatus. Introduce
SecurityScanService, SecurityScanner port, ScanTask, SecurityAudit
and related domain types. Wire scan trigger into SkillPublishService
so non-auto-publish versions enter scanning when scanner is enabled,
falling back to review task creation when disabled.

* feat(security): add infra layer for scanner HTTP client and adapters

Add WebClient-based HttpClient abstraction with WebClientHttpClient
implementation. Add SkillScannerApiResponse record, SecurityScanException,
and SecurityAuditJpaRepository. Add webflux and test dependencies to
infra module.

* feat(security): add Redis stream consumers, audit API, and DB migration

Add AbstractStreamConsumer base class, ScanTaskConsumer for processing
scan results from Redis stream, and RedisScanTaskProducer. Add
RedisStreamConfig for stream/group initialization. Add SecurityAudit
REST controller and DTO. Add V35 Flyway migration for security_audits
table.

* feat(security): add scanner config to application profiles

Add scanner enabled flag to application-local.yml and
application-test.yml. Enable behavioral analyzer by default
in application.yml.

* feat(deploy): add skill-scanner to docker-compose and k8s manifests

Add skill-scanner service to docker-compose.yml with health check.
Add scanner k8s deployment, service, and configmap entries. Wire
scanner env vars into Makefile dev-all flow. Add verify-scanner.sh
script for post-deploy validation.

* docs(security): add scanner documentation suite

Add scanner docs: configuration guide, failure impact analysis,
monitoring guide, improvement recommendations, custom rules guide,
and skill-vetter rules conversion example. Update deployment docs
with scanner section. Add security-scanning overview and PRD.

* feat(security): add skill-vetter custom rule examples

Add example Regex and YARA rules derived from skill-vetter RED FLAGS
in scanner/examples/vetter-rules/. Includes 7 Regex rules
(signatures-append.yaml) and 3 YARA rules (skillhub_vetter.yara)
covering agent memory theft, IP-based exfiltration, and browser
data theft detection.

* feat(security): add scanner Docker build context

Add Dockerfile for cisco-ai-skill-scanner container and
.env.example with LLM configuration placeholders.

* fix(security): align Finding mapping with scanner API response schema

SkillScannerApiResponse.Finding used incorrect field names (message,
location.file, location.line, code_snippet) that did not match the
scanner's actual JSON output (description, file_path, line_number,
snippet), causing all four fields to deserialize as null.

Flatten Finding to match scanner API: remove nested Location, rename
fields to description/file_path/line_number/snippet. Add skill_name
and timestamp to SkillScannerApiResponse. Extend SecurityFinding with
remediation, analyzer, and metadata fields to capture LLM analyzer
output. Retain 8-arg compact constructor for backward compatibility.

* chore(security): add debug logging to scanner response mapping

Log raw scanner API response and mapped SecurityFinding fields
side-by-side to help verify data consistency between scanner
output and database records.

* feat(security): add multi-scanner support and soft delete for security audits

- Add ScannerType enum for type-safe scanner identification
- Update V35 migration to support multiple scanners and soft delete
- Remove CASCADE delete, use code-level soft delete (deleted_at)
- Add repository methods for querying latest audit by scanner type
- Update SecurityScanService to handle scanner type parameter
- Integrate soft delete in SkillHardDeleteService
- Update all tests to use ScannerType enum

This enables multiple scanner integrations (skill-scanner, future LLM/compliance scanners)
and preserves complete audit history through soft deletion.

* feat(security): add security audit UI to review detail and skill detail pages

Display security scan results on the review detail page (full audit
section with collapsible findings) and the skill detail sidebar (compact
summary with dialog for details).  Handles empty/404 gracefully by
returning null, avoids loading shimmer flicker, and separates lifecycle
action buttons with a visual divider.

* docs(security): add security audit UI PRD

* fix(security): replace LocalDateTime with Instant in security audit and align controller test with list API

SecurityAudit and SecurityScanService used LocalDateTime.now() which
violated the project time guardrail. Replaced with Instant and
Clock.systemUTC() to match existing conventions.

Also fixed SecurityAuditControllerTest to mock the correct repository
method (findLatestActiveByVersionId) and assert against the list
response shape.

* test(security): add useQuery mock for security audit components in frontend tests

The SecurityAuditSummary and SecurityAuditSection components use
useQuery via useSecurityAudits hook, which was missing from the
@tanstack/react-query mocks in skill-detail and review-detail tests.
2026-03-23 09:56:03 +08:00

372 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Scanner 运维监控指南
## 概述
本文档提供 Scanner 服务的运维监控指南,包括关键指标、告警规则和故障排查方法。
## 关键监控指标
### 1. 版本状态监控
#### SCANNING 状态的版本数量
```sql
-- 查询当前处于 SCANNING 状态的版本数量
SELECT COUNT(*) as scanning_count
FROM skill_versions
WHERE status = 'SCANNING';
```
**告警阈值**
- ⚠️ 警告:> 10 个版本
- 🔴 严重:> 50 个版本
#### SCAN_FAILED 状态的版本数量
```sql
-- 查询最近 1 小时内扫描失败的版本数量
SELECT COUNT(*) as failed_count
FROM skill_versions
WHERE status = 'SCAN_FAILED'
AND updated_at > NOW() - INTERVAL 1 HOUR;
```
**告警阈值**
- ⚠️ 警告:> 5 个版本/小时
- 🔴 严重:> 20 个版本/小时
#### 卡死的扫描任务
```sql
-- 查找卡在 SCANNING 状态超过 10 分钟的版本
SELECT id, skill_id, version, status, created_at, updated_at
FROM skill_versions
WHERE status = 'SCANNING'
AND updated_at < NOW() - INTERVAL 10 MINUTE
ORDER BY updated_at ASC;
```
**告警阈值**
- 🔴 严重:任何超过 10 分钟的 SCANNING 状态
### 2. Redis Stream 监控
#### 消息堆积情况
```bash
# 查看 scan 队列的消息堆积情况
redis-cli XPENDING skillhub:scan:requests skillhub-scanners
# 查看队列长度
redis-cli XLEN skillhub:scan:requests
```
**告警阈值**
- ⚠️ 警告:队列长度 > 100
- 🔴 严重:队列长度 > 500
#### 消费者状态
```bash
# 查看消费者组信息
redis-cli XINFO GROUPS skillhub:scan:requests
# 查看消费者信息
redis-cli XINFO CONSUMERS skillhub:scan:requests skillhub-scanners
```
**检查项**
- 消费者是否在线
- 是否有长时间未确认的消息
### 3. 临时文件监控
#### 磁盘空间使用
```bash
# 检查临时文件目录大小
du -sh /tmp/skillhub-scans/
# 检查 /tmp 分区剩余空间
df -h /tmp
```
**告警阈值**
- ⚠️ 警告:/tmp 剩余空间 < 5GB
- 🔴 严重/tmp 剩余空间 < 1GB
#### 孤儿文件清理
```bash
# 查找超过 1 小时的临时文件(可能是孤儿文件)
find /tmp/skillhub-scans/ -type f -mmin +60
# 清理孤儿文件(谨慎操作)
find /tmp/skillhub-scans/ -type f -mmin +60 -delete
```
### 4. Scanner 服务健康检查
#### HTTP 健康检查
```bash
# 检查 Scanner 服务是否可用
curl -f http://localhost:8000/health || echo "Scanner service is down"
# 检查响应时间
time curl -s http://localhost:8000/health > /dev/null
```
**告警阈值**
- 警告响应时间 > 5 秒
- 🔴 严重:服务不可用
#### 扫描成功率
```sql
-- 计算最近 1 小时的扫描成功率
SELECT
COUNT(CASE WHEN status = 'PENDING_REVIEW' THEN 1 END) as success_count,
COUNT(CASE WHEN status = 'SCAN_FAILED' THEN 1 END) as failed_count,
ROUND(
COUNT(CASE WHEN status = 'PENDING_REVIEW' THEN 1 END) * 100.0 /
NULLIF(COUNT(*), 0),
2
) as success_rate
FROM skill_versions
WHERE updated_at > NOW() - INTERVAL 1 HOUR
AND status IN ('PENDING_REVIEW', 'SCAN_FAILED');
```
**告警阈值**
- ⚠️ 警告:成功率 < 80%
- 🔴 严重成功率 < 50%
## Prometheus 告警规则示例
```yaml
groups:
- name: scanner_alerts
interval: 30s
rules:
# Scanner 服务不可用
- alert: ScannerServiceDown
expr: up{job="skill-scanner"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Scanner service is down"
description: "Scanner service has been down for more than 2 minutes"
# 扫描失败率过高
- alert: ScannerHighFailureRate
expr: rate(scanner_failures_total[5m]) > 0.5
for: 5m
labels:
severity: warning
annotations:
summary: "Scanner failure rate > 50%"
description: "Scanner failure rate is {{ $value | humanizePercentage }} in the last 5 minutes"
# 版本卡在 SCANNING 状态
- alert: ScanStuckTooLong
expr: skillhub_scanning_versions{status="SCANNING"} > 0
for: 10m
labels:
severity: critical
annotations:
summary: "Versions stuck in SCANNING state"
description: "{{ $value }} versions have been in SCANNING state for more than 10 minutes"
# 临时文件磁盘空间不足
- alert: TempFilesDiskUsage
expr: node_filesystem_avail_bytes{mountpoint="/tmp"} < 1e9
for: 5m
labels:
severity: warning
annotations:
summary: "Temp files disk usage high"
description: "Only {{ $value | humanize1024 }}B available in /tmp"
# Redis Stream 消息堆积
- alert: ScanQueueBacklog
expr: redis_stream_length{stream="skillhub:scan:requests"} > 100
for: 5m
labels:
severity: warning
annotations:
summary: "Scan queue backlog"
description: "{{ $value }} messages pending in scan queue"
```
## 故障排查手册
### 问题 1版本卡在 SCANNING 状态
**症状**
- 用户反馈技能包一直在扫描中
- 数据库中版本状态为 SCANNING 超过 10 分钟
**排查步骤**
1. 检查 Redis Stream 消费者是否在线
```bash
redis-cli XINFO CONSUMERS skillhub:scan:requests skillhub-scanners
```
2. 检查是否有对应的消息
```bash
redis-cli XPENDING skillhub:scan:requests skillhub-scanners
```
3. 检查应用日志
```bash
kubectl logs -l app=skillhub-backend --tail=100 | grep "versionId=<VERSION_ID>"
```
**解决方案**
如果确认消息丢失或消费者异常手动修复版本状态
```sql
-- 将卡死的版本标记为 SCAN_FAILED
UPDATE skill_versions
SET status = 'SCAN_FAILED', updated_at = NOW()
WHERE id = <VERSION_ID> AND status = 'SCANNING';
-- 创建人工审核任务
INSERT INTO review_tasks (skill_version_id, namespace_id, requester_id, created_at)
SELECT id, (SELECT namespace_id FROM skills WHERE id = skill_id), created_by, NOW()
FROM skill_versions
WHERE id = <VERSION_ID>;
```
### 问题 2Scanner 服务不可用
**症状**
- 所有扫描任务失败
- HTTP 连接超时
**排查步骤**
1. 检查 Scanner 服务状态
```bash
# Docker 环境
docker ps | grep scanner
# Kubernetes 环境
kubectl get pods -l app=skill-scanner
```
2. 检查 Scanner 日志
```bash
# Docker 环境
docker logs skill-scanner --tail=100
# Kubernetes 环境
kubectl logs -l app=skill-scanner --tail=100
```
3. 检查网络连通性
```bash
curl -v http://localhost:8000/health
```
**解决方案**
- 重启 Scanner 服务
- 检查配置是否正确API keybase URL
- 检查资源限制CPU内存
### 问题 3临时文件占满磁盘
**症状**
- /tmp 分区空间不足
- 扫描任务失败日志显示 "No space left on device"
**排查步骤**
1. 检查磁盘使用情况
```bash
df -h /tmp
du -sh /tmp/skillhub-scans/
```
2. 查找大文件
```bash
find /tmp/skillhub-scans/ -type f -size +100M -exec ls -lh {} \;
```
3. 查找孤儿文件
```bash
find /tmp/skillhub-scans/ -type f -mmin +60
```
**解决方案**
```bash
# 清理超过 1 小时的临时文件
find /tmp/skillhub-scans/ -type f -mmin +60 -delete
# 清理空目录
find /tmp/skillhub-scans/ -type d -empty -delete
```
### 问题 4Redis Stream 消息堆积
**症状**
- 扫描任务延迟严重
- Redis Stream 队列长度持续增长
**排查步骤**
1. 检查队列长度
```bash
redis-cli XLEN skillhub:scan:requests
```
2. 检查消费者数量和状态
```bash
redis-cli XINFO CONSUMERS skillhub:scan:requests skillhub-scanners
```
3. 检查应用实例数量
```bash
kubectl get pods -l app=skillhub-backend
```
**解决方案**
- 增加应用实例数量水平扩展
- 检查 Scanner 服务性能
- 临时禁用扫描功能清空队列后再启用
## 日常巡检清单
### 每日检查
- [ ] 检查 SCANNING 状态的版本数量
- [ ] 检查 SCAN_FAILED 状态的版本数量
- [ ] 检查 Scanner 服务健康状态
- [ ] 检查 /tmp 磁盘空间使用情况
### 每周检查
- [ ] 检查扫描成功率趋势
- [ ] 检查 Redis Stream 消息堆积情况
- [ ] 清理孤儿临时文件
- [ ] 检查告警规则是否触发
### 每月检查
- [ ] 审查扫描失败的原因分布
- [ ] 评估 Scanner 服务性能
- [ ] 优化告警阈值
- [ ] 更新运维文档
## 相关文档
- [故障影响分析](./failure-impact-analysis.md)
- [改进建议](./improvement-recommendations.md)
- [配置说明](./configuration.md)