프로젝트 소개
vitals는 macOS 14 이상에서 실행되는 Apple Silicon Mac용 시스템 모니터입니다. 단일 Rust 바이너리가 프로세스 내에서 CPU, GPU, 메모리, 전력 및 열 상태를 샘플링합니다. powermetrics를 호출하지 않고, sudo 권한이 필요 없으며, 어떤 종류의 하위 프로세스도 시작하지 않습니다. 출력은 스크립트, 에이전트 또는 사람이 직접 읽을 수 있는 구조화된 JSON 형식입니다. 인자 없이 실행하면 동일한 바이너리가 선택 사항인 로컬 대시보드를 포함한 메뉴 바 트레이 항목으로 작동합니다.
명령줄 동사(Verbs)
snapshot은 하나의 전체 SoC 샘플을 출력합니다: 호스트 칩 및 코어 수, 시스템 전체 CPU 사용률, 코어 종류(효율 또는 성능), 주파수 및 사용률이 포함된 코어별 항목, GPU 사용률 및 주파수, 메모리 및 스왑 총량과 사용량, 커널 메모리 압력, CPU, GPU, ANE, RAM 및 시스템 전력 수치, CPU 및 GPU 온도, 최대치가 포함된 팬 속도, 부하 평균, 가동 시간 및 열 상태를 제공합니다. interval 옵션을 통해 CPU, GPU 및 전력 상주 시간이 통합되는 샘플링 창을 변경할 수 있습니다.
top은 CPU 및 메모리별로 프로세스 순위를 독립적으로 매기며, 행 수를 설정할 수 있어 동일한 프로세스가 두 목록에 모두 나타날 수 있습니다. CPU 백분율은 ps와 마찬가지로 시스템 전체가 아닌 프로세스당 기준이며, 멀티코어 작업 시 100%를 초과할 수 있습니다.
pressure는 원시 숫자 대신 판정 결과를 반환합니다: 상태, 사용 가능한 이력이 있는지에 대한 플래그, 코드와 심각도가 포함된 이유 목록, 각 플래그가 지정된 이유와 함께 의심되는 프로세스 목록, 그리고 한 줄 요약을 제공합니다. 설계상 상태가 좋지 않다고 보고할 때도 보고 자체가 실패한 것은 아니므로 종료 코드 0으로 종료됩니다. exit-code 플래그를 사용하면 판정 심각도가 상태 코드에 반영됩니다(0 정상, 3 경고, 4 심각). 런타임 오류는 1, 잘못된 호출은 2로 종료됩니다.
watch는 스스로 종료되지 않는 유일한 동사입니다. 한 줄에 하나의 컴팩트한 JSON 객체를 출력하고 매 줄마다 플러시하며, 중단되거나 요청된 샘플 수가 출력될 때까지 실행됩니다. interval은 케이던스와 샘플링 창을 모두 설정합니다. 출력이 줄 단위로 플러시되므로, 한 줄을 읽고 파이프를 닫는 소비자는 깔끔하게 종료됩니다. 항상 줄 바꿈으로 구분된 JSON이며 JSON 플래그는 거부됩니다.
JSON은 snapshot, top, pressure의 기본값입니다. 각각 터미널용으로 읽기 쉬운 텍스트 형식을 지원하며, JSON 플래그는 no-op으로 처리됩니다. 모든 응답에는 스키마 버전이 포함됩니다. 단위는 별도의 필드가 아닌 키 이름에 포함되며(메모리는 MB, 전력은 와트, 온도는 섭씨), 선택적 필드가 없는 경우 null로 출력하지 않고 생략합니다.
메뉴 바 앱 및 대시보드
인자 없이 실행하면 vitals는 실시간 텍스트와 커스텀 드롭다운이 있는 메뉴 바 트레이가 됩니다. 드롭다운에는 CPU(스파크라인 및 코어당 바 하나, 효율 코어와 성능 코어가 다르게 색칠됨), GPU, 커널 압력 신호로 판단한 메모리, 그리고 전력이 표시됩니다. 주요 수치는 임계값에서 색상이 변경되며, 드롭다운이 닫혀 있는 동안에는 아무것도 다시 그리지 않고, 디스플레이가 절전 모드일 때는 샘플링 케이던스가 낮아집니다.
이 앱은 액세서리로 선언되어 있어, 창이 요청되기 전까지는 Dock 아이콘이나 앱 전환기에 나타나지 않습니다. 드롭다운이나 실행 중인 앱을 다시 열어 대시보드를 열 수 있으며, 이는 자체 프로세스로서 웹 뷰 기반의 네이티브 창에서 열립니다. 대시보드가 열려 있는 동안에는 Dock 타일과 앱 메뉴가 나타나며, 닫히면 해당 프로세스가 종료되어 리소스 소모가 없습니다. 트레이가 종료되거나 충돌하면 창이 파일 디스크립터 감시를 통해 이를 감지하고 즉시 종료됩니다. HTTP 서버는 트레이 프로세스 내부에서 실행되며 요청 시 시작되므로, 대시보드를 요청한 적 없는 트레이는 리스너와 두 번째 샘플러를 가지지 않습니다.
대시보드 페이지는 위에서 아래로 읽도록 설계되었습니다: pressure 동사가 생성하는 것과 동일한 판정 결과, 주요 수치/상태 점/컨텍스트 라인/트렌드가 포함된 CPU, GPU, 메모리, 전력의 4개 타일, 하단 모든 항목의 범위를 지정하는 2, 5, 15분 범위 컨트롤, 십자선과 툴팁이 있는 시간 경과별 CPU 및 GPU 차트, 호버 시 클럭 속도가 표시되는 위치별 코어 바, 커널 압력 신호를 따르는 메모리 및 스왑 미터, 인라인 바가 포함된 상위 프로세스가 표시됩니다. 모든 차트는 동일한 데이터에 대해 차트-표 전환 토글을 제공하며, 페이지가 숨겨지면 폴링이 중단됩니다. 서버가 중단되어도 마지막으로 렌더링된 화면이 어둡게 유지되며, 라이트/다크 테마는 시스템 설정을 따릅니다.
설치 및 패키징
두 가지 독립적인 설치 경로를 통해 vitals를 PATH에 추가할 수 있습니다. 빌드 후 install을 수행하면 릴리스 바이너리가 prefix bin 디렉토리에 심볼릭 링크됩니다(sudo를 피하려면 prefix를 재정의하며, uninstall 타겟으로 링크를 제거할 수 있습니다). 앱 설치 경로는 빌드, 번들링, 응용 프로그램 폴더로의 복사, 로그인 시마다 트레이가 시작되도록 사용자별 런칭 에이전트 설치, 그리고 동일한 심볼릭 링크를 번들 복사본으로 재지정하는 과정을 거칩니다. 대응하는 uninstall 타겟이 이 모든 과정을 되돌립니다. 번들은 공증(notarized) 대신 임시 서명(ad-hoc signed)되어 있으며, 이는 런칭 에이전트 실행에 충분합니다. Finder를 통해 앱을 열 때는 일회성 우클릭 '열기' 또는 시스템 설정에서의 승인이 필요할 수 있습니다.
개발
빌드, 테스트, 경고를 오류로 처리하는 clippy 및 포맷팅을 위한 make 타겟이 제공됩니다. 대시보드는 Vite 및 React 앱이며, 프로덕션 빌드 결과물이 컴파일 타임에 바이너리에 내장되므로 페이지 수정 후에는 바이너리를 다시 빌드해야 합니다. 핫 리로드를 지원하는 개발 서버는 API 요청을 로컬 포트로 프록시하므로, 트레이 내부의 인스턴스를 포함하여 실행 중인 모든 인스턴스에 대해 작동합니다.
기여는 버그 보고, 측정 및 풀 리퀘스트를 통해 이루어지며, 취약점 보고를 위한 별도 채널이 있습니다. 이 프로젝트는 MIT 라이선스를 따릅니다.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.