Skip to content

component daily report generator

minsoo edited this page Jun 9, 2026 · 3 revisions

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가 만든다.

Time Window

prepare_report_window()는 입력 날짜를 KST 운영일로 해석한다.

  • report_date가 있으면 해당 날짜를 사용한다.
  • 없으면 Asia/Seoul 기준 전일을 사용한다.
  • KST 24개 hour item과 각각의 UTC 범위를 생성한다.
  • Factory target들과 cloud-infra target을 함께 반환한다.
  • 출력 root는 기본 reports/daily다.

시간 필터는 종료 시각을 1초 늘린 exclusive end로 변환해 start <= timestamp < end_exclusive를 적용한다. S3 prefix가 UTC 기준이므로 KST 한 시간이 걸치는 UTC hour partition을 모두 읽은 뒤 timestamp로 재필터링한다.

S3 Reader와 Writer

Factory Reader

S3ProcessedReader는 dataset별 UTC hour prefix를 ListObjectsV2로 나열하고 각 key를 GetObject하여 JSON으로 읽는다.

기본 입력:

  • factory_state
  • risk_score
  • infra_state

보조 입력:

  • state_snapshot

현재 코드는 순차 GetObject 방식이다. Terraform에 S3_GET_CONCURRENCY=16이 설정되어 있지만 reader가 이 값을 사용하지 않으므로 병렬화된 것으로 해석하면 안 된다.

Cloud Infra Reader

CloudInfraReader는 아래 prefix를 읽고 추적용 _s3_key를 추가한다.

  • processed/cloud_infra/fast/...
  • processed/cloud_infra/slow/...

Writer

S3ReportWriter는 JSON을 application/json, 보고서를 text/markdown; charset=utf-8PutObject한다.

Factory Reducers

시간별 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 Reducers

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

두 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를 분리한다.

Bedrock Client

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로 확인해야 한다.

Renderer와 Validation

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 문장의 운영적 타당성을 자동 확정하는 검증은 아니므로 사람의 검토가 계속 필요하다.

Metadata

성공 시 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만으로 정밀 산정할 수 없다.

Backfill

Inventory

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-31

Local module backfill

backfill_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 환경변수를 바꿀 수 있다.

Deployed Lambda backfill

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 계약을 다룬다.

관련 문서

Aegis-Pi Wiki

· 대표 문서 목록은 홈의 문서 탐색 표 참조

시작하기

요구사항

핵심 개념

아키텍처

컴포넌트 (Edge → Cloud → Dashboard)

Dashboard & 운영

시나리오 · 사례 · 참조

Clone this wiki locally