두 유형은 타입 정의(edge/events.py)·서버 검증(EventValidator)·콘솔 필터· 통보 라벨까지 전 구간에 있었으나 생성하는 코드가 어디에도 없었다. 실제로 값을 넣는 것은 seed_demo.php 뿐이었고, 소개서가 내세운 "17종"은 15종이었다. 앞서 고친 EventValidator 누락과 정확히 반대 방향의 같은 병이다. 그때는 감지기가 있는데 서버가 막았고, 이번엔 서버·UI가 열려 있는데 감지기가 없다. 어느 쪽이든 화면은 멀쩡해 보인다. 엣지가 낼 수 없는 유형이라 서버에 둔다 — 전원·회선이 끊긴 노드는 자기가 죽었다고 신고할 수 없다. 하트비트의 부재로만 관측된다. App\Alert\DeviceHealthWatch: - dispatch_alerts.php 1분 크론의 1단계. 에스컬레이션·통보보다 앞에 두어 같은 실행 안에서 발행된 장치 이벤트가 곧바로 통보 대상이 되게 했다. - 멱등은 EscalationWatch와 같은 방식(event_uuid UNIQUE 충돌)이되, 장치 건전성은 연속 상태라 uuid 앵커를 '장애 구간의 시작'으로 잡았다. device_fault는 last_heartbeat_at(장애 내내 불변) → 장애당 정확히 1건. monitoring_degraded는 창 안의 마지막 정상 하트비트 ts. 창 전체가 저하면 시작을 볼 수 없으므로 창 버킷으로 폴백해 시간당 1회 재고지한다 — 의도된 리마인더이고, 매 틱 재발행하는 앵커 드리프트가 아니다. - 성능 저하는 지속을 요구(기본 5분). 한 번 튄 값에 울리면 운영자가 이 유형을 무시하게 되고, 그러면 감시가 멈춘 날에도 아무도 보지 않는다. 엣지 감지기들이 쓰는 규율과 같다. - 하트비트를 한 번도 보낸 적 없는 장치는 장애가 아니다(미설치 노드). 새 현장 첫날이 빨간 벽이 되면 그 사이트는 이 유형을 영영 신뢰하지 않는다. - 죽은 노드에 degraded를 겹쳐 내지 않는다 — 한 고장에 두 알람은 소음이다. - fps NULL을 0으로 강압하지 않는다(측정 실패 ≠ 정지). PdoDeviceMetric Repository가 NULL을 지키는 이유와 같다. - 억제(정비 모드)는 여기서 보지 않는다. 기록은 남기고 통보 여부는 AlertDispatcher가 정한다 — 정비 창은 전화를 끄는 것이지 노드가 죽었던 기록을 지우는 것이 아니다. camera_id는 NOT NULL인데 장치 단위 이벤트에는 카메라가 없다. '__device__' 센티넬을 쓰고, 콘솔은 "장치 전체"로 표시, 구역 편집기 카메라 목록에서는 제외한다(카메라 목록은 보고된 이벤트에서 파생되므로, 두면 존재하지 않는 카메라에 구역을 그리려는 일이 생긴다). 설정 4종 추가(device_stale_seconds 180 · degraded_sustain_seconds 300 · degraded_fps_ratio 0.6 · target_fps 12) — 두 config 템플릿에 한국어 설명과 함께. 낮은 프레임으로 운용하는 현장이 target_fps를 안 맞추면 전 노드가 영구 저하로 보고되므로 그 경고를 템플릿에 적었다. 검증: pytest 308 passed(3 skip: 모델 미동봉·shellcheck 미설치·AF_UNIX, 기존과 동일) · phpunit 240 passed(신규 16). dist 재생성으로 패리티 회복.
66 lines
5.1 KiB
PHP
66 lines
5.1 KiB
PHP
<?php
|
|
// ============================================================================
|
|
// move-detect — 설정 파일 (이 파일만 고치면 됩니다)
|
|
// 위치: 카페24 FTP 최상위 /config.php (www/ 안이 아닙니다!)
|
|
// 권한: 업로드 후 FTP 클라이언트에서 600 으로 지정하세요. zip/FTP 는 유닉스 권한을
|
|
// 옮기지 못하므로 여기서 미리 줄 수 없습니다. _preflight.php 가 확인해줍니다.
|
|
// ============================================================================
|
|
//
|
|
// 고칠 곳은 아래 "1. 데이터베이스" 세 줄뿐입니다. 값은 카페24 관리자 페이지의
|
|
// MySQL 정보에서 그대로 복사하세요. 나머지는 손대지 않아도 동작합니다.
|
|
//
|
|
return [
|
|
// ---- 1. 데이터베이스 (반드시 채우세요) ------------------------------
|
|
// CHANGEME_DB_NAME → 카페24에서 만든 DB 이름
|
|
'db_dsn' => 'mysql:host=localhost;dbname=CHANGEME_DB_NAME;charset=utf8mb4',
|
|
'db_user' => 'CHANGEME_DB_USER', // 카페24 MySQL 아이디
|
|
'db_pass' => 'CHANGEME_DB_PASSWORD', // 카페24 MySQL 비밀번호 — 비밀. 어디에도 붙여넣지 마세요.
|
|
|
|
// ---- 2. 저장 경로 (그대로 두세요) -----------------------------------
|
|
// 여기서 __DIR__ 은 이 config.php 가 있는 폴더(= FTP 최상위)입니다.
|
|
// src/Config.php 의 기본값은 '/../storage/snapshots' 이지만 그것은 src/ 기준이라
|
|
// '..' 이 하나 더 붙습니다. 둘 다 결국 같은 <최상위>/storage/snapshots 를 가리킵니다.
|
|
'snapshot_dir' => __DIR__ . '/storage/snapshots',
|
|
|
|
// ---- 3. 조절값 (기본값. 필요할 때만 바꾸세요) ------------------------
|
|
'nonce_ttl' => 86400, // 재전송 방지 nonce 보관 시간(초)
|
|
'timestamp_window' => 300, // HMAC 허용 시간 오차(초)
|
|
'rate_limit_per_min' => 60, // 장비 1대당 분당 이벤트 상한
|
|
'ingest_ip_rate_limit_per_min' => 300, // IP 1개당 분당 이벤트 상한 (DoS 방어)
|
|
'snapshot_retention_days' => 7, // 작업자 스냅샷 보존일 (PIPA; 지나면 삭제, 0=비활성)
|
|
// 이벤트 '기록'(이미지 아님) 보존일. 0 = 영구 보존이 기본값입니다 — 산업안전 조사나
|
|
// 노사 분쟁에서 수년 뒤에도 필요할 수 있는 사고 기록이라, 시스템이 임의로 지우지 않습니다.
|
|
// DB 용량 제한이 있는 현장만 값을 넣으세요(예: 1095 = 3년). 스냅샷 보존일보다 훨씬 커야 합니다.
|
|
'event_retention_days' => 0,
|
|
|
|
// ---- 4. 통보 (알림을 쓰려면 채우세요) -------------------------------
|
|
// 대시보드 주소입니다. 알림 메일/웹훅에 들어가는 사건 링크가 이 주소로 만들어집니다.
|
|
// 비워두면 통보 디스패처(tools/dispatch_alerts.php)가 실행을 거부합니다 —
|
|
// 열리지 않는 링크가 담긴 알림을 보내는 것보다 안 보내는 편이 낫기 때문입니다.
|
|
'public_base_url' => '', // 예: 'https://example.com/move_detect'
|
|
// 위급/높음 이벤트를 이 시간(초) 동안 아무도 확인하지 않으면 '미확인 경보' 이벤트를
|
|
// 새로 만들어 상위 담당자에게 통보합니다. 300 = 5분.
|
|
'escalate_after_seconds' => 300,
|
|
// 노드가 이 시간(초) 동안 아무 소식이 없으면 '장치 이상' 이벤트를 만듭니다. 하트비트는
|
|
// 30초 간격이라 180 이면 몇 번 걸러 먹어도 견딥니다. 짧게 줄이면 잠깐의 네트워크
|
|
// 끊김마다 알람이 울려, 정작 노드가 정말 죽었을 때 아무도 쳐다보지 않게 됩니다.
|
|
'device_stale_seconds' => 180,
|
|
// 노드 성능 저하(프레임 저하·카메라 오류·발열 감속)가 이 시간(초) 이상 계속되면
|
|
// '감시 성능 저하' 이벤트를 만듭니다. 한 번 튄 값으로는 만들지 않습니다.
|
|
'degraded_sustain_seconds' => 300,
|
|
// 성능 저하 판정 기준: 실제 프레임률이 target_fps 의 이 비율 아래로 떨어지면 저하로 봅니다.
|
|
// 노드를 일부러 낮은 프레임으로 돌리는 현장은 target_fps 를 실제 값으로 맞추세요.
|
|
// 그러지 않으면 모든 노드가 계속 '감시 성능 저하' 로 보고됩니다.
|
|
'degraded_fps_ratio' => 0.6,
|
|
'target_fps' => 12.0,
|
|
// 알림 메일·웹훅에 찍히는 시각의 기준 시간대입니다. 대시보드 화면은 보는 사람의 PC
|
|
// 시각을 쓰지만 알림은 서버가 만들기 때문에, 이 값이 틀리면 화면과 메일의 시각이
|
|
// 서로 다르게 나옵니다. 한국 현장은 그대로 두세요.
|
|
'timezone' => 'Asia/Seoul',
|
|
|
|
// ---- 5. 용량 관리 (그대로 두세요) -----------------------------------
|
|
// 장비 성능 추이 기록 보존일. 장비 1대당 하루 약 2,880행이 쌓입니다.
|
|
'metric_retention_days' => 30,
|
|
// 스냅샷 저장 공간 여유 하한(MB). 밑돌면 대시보드에 경고가 뜹니다. 0 = 검사 안 함.
|
|
'storage_min_free_mb' => 200,
|
|
];
|