-
Notifications
You must be signed in to change notification settings - Fork 0
component daily report generator
기준일: 2026-06-09
구현 위치: apps/daily-report-generator/
Daily Report Generator는 S3 processed 데이터를 결정론적으로 집계하고, compact context를 Bedrock에 전달해 한국어 운영 보고서 초안을 만든다. LLM은 통계 계산을 담당하지 않으며, 보고서는 운영 정본이 아닌 운영자 검토용 초안이다.
지원 target:
-
factory-a,factory-b,factory-c: 개별 Factory Daily Report -
cloud-infra: Cloud Infra Daily Report
apps/daily-report-generator/
├── lambda_prepare_report_window.py
├── lambda_aggregate_factory_hour.py
├── lambda_merge_factory_daily.py
├── lambda_generate_factory_report.py
├── lambda_aggregate_cloud_infra_hour.py
├── lambda_merge_cloud_infra_daily.py
├── lambda_generate_cloud_infra_report.py
├── report_generator/
│ ├── time_window.py
│ ├── s3_keys.py
│ ├── s3_reader.py
│ ├── s3_writer.py
│ ├── reducers.py
│ ├── event_detection.py
│ ├── severity.py
│ ├── aggregate_hour.py
│ ├── merge_daily.py
│ ├── prompt_builder.py
│ ├── report_renderer.py
│ ├── validation.py
│ ├── aggregate_cloud_infra_hour.py
│ ├── merge_cloud_infra_daily.py
│ ├── cloud_infra_prompt_builder.py
│ ├── cloud_infra_report_renderer.py
│ ├── cloud_infra_validation.py
│ ├── generate_report.py
│ ├── generate_cloud_infra_report.py
│ └── bedrock_client.py
├── scripts/
│ ├── run_local_daily_report.py
│ ├── inventory_daily_report_backfill.py
│ ├── backfill_daily_reports.py
│ └── invoke_reporting_lambdas_backfill.py
└── tests/
context_builder.py는 현재 NotImplementedError만 가진 미사용 placeholder다. 실제 Factory
context는 merge_daily.build_report_context, Cloud Infra context는
merge_cloud_infra_daily.build_cloud_infra_report_context가 만든다.
prepare_report_window()는 입력 날짜를 KST 운영일로 해석한다.
-
report_date가 있으면 해당 날짜를 사용한다. - 없으면
Asia/Seoul기준 전일을 사용한다. - KST 24개 hour item과 각각의 UTC 범위를 생성한다.
- Factory target들과
cloud-infratarget을 함께 반환한다. - 출력 root는 기본
reports/daily다.
시간 필터는 종료 시각을 1초 늘린 exclusive end로 변환해
start <= timestamp < end_exclusive를 적용한다. S3 prefix가 UTC 기준이므로 KST 한
시간이 걸치는 UTC hour partition을 모두 읽은 뒤 timestamp로 재필터링한다.
S3ProcessedReader는 dataset별 UTC hour prefix를 ListObjectsV2로 나열하고 각 key를
GetObject하여 JSON으로 읽는다.
기본 입력:
factory_staterisk_scoreinfra_state
보조 입력:
state_snapshot
현재 코드는 순차 GetObject 방식이다. Terraform에 S3_GET_CONCURRENCY=16이 설정되어
있지만 reader가 이 값을 사용하지 않으므로 병렬화된 것으로 해석하면 안 된다.
CloudInfraReader는 아래 prefix를 읽고 추적용 _s3_key를 추가한다.
processed/cloud_infra/fast/...processed/cloud_infra/slow/...
S3ReportWriter는 JSON을 application/json, 보고서를
text/markdown; charset=utf-8로 PutObject한다.
시간별 reducer는 factory ID, timestamp, message ID를 검증하고 중복을 제거한다.
| 영역 | 계산 내용 |
|---|---|
| Data quality | expected/actual, 수집률, 시작/내부/종료 결측, invalid/duplicate |
| Risk | 평균/최소/최대, warning/danger 시간, 주요 원인, 최악 구간 |
| Sensor | 온도/습도/압력 평균·극값·p05·p95, 임계 초과 시간 |
| AI | fire/fall/bend score 극값, spike window, abnormal sound count |
| Infra | not-ready node, unhealthy workload, restart delta |
| Pipeline | 결측과 상태를 이용한 warning/critical 요약 |
| Snapshot | 시간대 마지막 상태 참고값 |
NumericReducer의 percentile은 nearest-rank 방식이다. 이벤트는 연속 sample을 window로
묶고 severity 기본 점수 info=10, warning=50, danger=80에 지속 시간과 magnitude를
더해 우선순위를 계산한다.
Daily merge는 시간별 가중 평균과 극값을 합치고, 동일 이벤트의 hour 경계를 최대 120초 gap으로 병합한다. Context에는 상위 이벤트 기본 10개와 rule 기반 확인 항목을 넣는다.
Cloud Infra reducer는 schema_version=cloud-infra-status-v1인 snapshot만 받는다.
| 영역 | 계산 내용 |
|---|---|
| Data quality | fast 60/hour, slow 12/hour 기대량, gap, invalid/duplicate |
| Backend Runtime | ECS desired/running/pending, CPU/memory, ALB health/5xx |
| Data Pipeline | Lambda error/throttle/duration, DynamoDB 오류, disabled scheduler |
| EKS | cluster 상태, node ready, pod 상태/재시작, 상위 CPU/memory pod |
| ArgoCD | total/synced/out-of-sync/degraded/healthy |
| Freshness | Factory warning/critical 시간, stale factory/storage |
Cloud Infra daily merge는 일중 최소/최대/합계와 상위 이벤트를 합치며, Factory와 별도의 context schema와 renderer를 사용한다.
두 prompt builder의 공통 원칙:
-
report-context.json만 근거로 사용 - S3 raw나 context에 없는 사실 추가 금지
- 원인을 확정하지 않고 관측과 확인 필요 항목으로 표현
- 핵심 수치와 날짜를 유지
- 코드가 표를 삽입하므로 LLM은 표를 만들지 않음
- 마지막에 processed 기반, raw 미사용, LLM 초안 검토 필요를 명시
Factory prompt는 Factory B/C를 dummy/testbed로 구분하고 Risk, 센서/AI, Factory 인프라와 pipeline 상태를 설명한다. Cloud Infra prompt는 ECS/ALB, Lambda/DynamoDB, EKS, ArgoCD, freshness를 분리한다.
BedrockReportClient는 boto3 bedrock-runtime.invoke_model을 사용한다.
| 설정 | 코드 기본값 |
|---|---|
BEDROCK_MODEL_ID |
anthropic.claude-3-sonnet-20240229-v1:0 |
BEDROCK_MAX_TOKENS |
3000 |
BEDROCK_TEMPERATURE |
0.2 |
| API payload | Anthropic Messages, bedrock-2023-05-31
|
Terraform도 같은 Sonnet model ID를 기본값으로 Lambda 환경변수와 IAM foundation-model
ARN에 넣는다. 초기 ADR/계획의 Haiku는 과거 기준이다. 2026-05-28 AWS 실검증
generation-metadata.json도 Sonnet을 기록했다.
저장소에는 별도 model override가 있는 terraform.tfvars가 없다. 실제 배포에서
override했는지는 Lambda 환경변수와 생성 metadata로 확인해야 한다.
LLM 응답은 그대로 저장되지 않는다.
Factory renderer:
- heading trailing space를 허용해 섹션을 찾음
- 핵심 지표, 수집, Risk, 센서/AI, 인프라, 이벤트, 확인 항목 표 삽입
- 운영자 친화적 한국어로 일부 용어 치환
- context 원문 수치 검증 섹션 추가
Cloud Infra renderer:
- 핵심 지표와 각 운영 영역 표 삽입
- 이벤트/check ID를 한국어 label로 변환
- context 원문 수치 검증 섹션 추가
Validation은 Factory/target ID, 날짜, 수집량/수집률, Risk 또는 ECS/EKS/ArgoCD 핵심
값이 최종 Markdown에 존재하는지 확인한다. 실패하면 status=validation_failed를
반환하고 report.md와 metadata는 저장하지 않는다.
이 검증은 값의 누락이나 변조를 막는 최소 invariant 검사다. LLM 문장의 운영적 타당성을 자동 확정하는 검증은 아니므로 사람의 검토가 계속 필요하다.
성공 시 generation-metadata.json에 다음 값이 저장된다.
{
"generated_at": "UTC ISO-8601",
"model_id": "실제 client model id",
"context_key": ".../report-context.json",
"report_key": ".../report.md"
}현재 포함되지 않는 값:
- Bedrock input/output token usage
- context/output byte 수
- S3 input object count
- stop reason
따라서 모델 비용은 metadata만으로 정밀 산정할 수 없다.
inventory_daily_report_backfill.py는 S3를 읽기만 하며 Factory 3개와 cloud-infra의
날짜별 object 수, 24시간 완전성, 기존 report.md/metadata 존재 여부를 조사한다.
python apps/daily-report-generator/scripts/inventory_daily_report_backfill.py \
--bucket aegis-bucket-data \
--date-from 2026-05-01 \
--date-to 2026-05-31backfill_daily_reports.py는 현재 Python process에서 reader/reducer/Bedrock/writer를
직접 실행한다. Factory와 Cloud Infra를 모두 지원한다.
python apps/daily-report-generator/scripts/backfill_daily_reports.py \
--target-dates factory-a:2026-05-27,cloud-infra:2026-05-27 \
--only-missing \
--max-bedrock-calls 2 \
--dry-run--force는 기존 보고서를 재생성하며, --max-bedrock-calls는 비용 상한 역할을 한다.
실행 기본 model은 Sonnet이고 --model-id로 process 환경변수를 바꿀 수 있다.
invoke_reporting_lambdas_backfill.py는 배포된 Factory Lambda 4개를 직접 호출한다.
현재 factory-a/b/c만 지원하며 Cloud Infra backfill은 지원하지 않는다. Cloud Infra가
필요하면 전체 Step Functions 실행 또는 local module backfill을 사용한다.
python -m compileall -q apps/daily-report-generator
python -m pytest -q apps/daily-report-generator통합 기록 기준 15개 테스트가 통과했다. 테스트는 time window, Factory/Cloud Infra hourly aggregate, daily merge, prompt, 생성/검증, S3 key 계약을 다룬다.
- 시스템 아키텍처
- 제어 & 데이터 플레인
- Dashboard VPC 설계
- 하드웨어 배치
- Hub EKS 네임스페이스
- Tailscale Mesh VPN
- 데이터 생명주기
- 데이터 조회 모델
- 실시간 갱신 구조
- IoT 데이터 계약
- Reporting Pipeline
- 로컬 스토리지
- 클라우드 스토리지
- Edge Agent
- Edge AI 탐지
- Factory-A Log Adapter
- Dummy Sensor
- Edge IoT Publisher
- Lambda Data Processor
- Risk Normalizer
- Risk Score Engine
- Pipeline Status Aggregator
- Graph Aggregator 5m
- Cloud Infra Collector
- Daily Report Generator
- Risk Alert Dispatcher
- Image Snapshot Pipeline
- Dashboard Backend
- Dashboard Web
- AI 채팅 어시스턴트