# os_log 사용법: 애플 앱 로깅을 print에서 옮기기

- 게시: 2026.07.13
- 원문(HTML): https://trendbrief.news/articles/os-log-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%95%A0%ED%94%8C-%EC%95%B1-%EB%A1%9C%EA%B9%85%EC%9D%84-print%EC%97%90%EC%84%9C-%EC%98%AE%EA%B8%B0%EA%B8%B0.html
- 발행: [트렌드브리프](https://trendbrief.news/)

> os_log는 애플 플랫폼의 통합 로깅 시스템으로 print와 NSLog를 대체한다. Logger 생성, 로그 레벨 선택, 개인정보 보호, 콘솔 확인까지 Swift 개발자를 위한 기본 사용법을 애플 공식 문서 기준으로 정리했다.

os_log는 애플 플랫폼에서 앱의 동작을 기록하는 통합 로깅 시스템이다. 문자열만 콘솔에 찍던 print나 NSLog와 달리, 기록을 레벨과 범주로 나눠 저장하고 성능 부담을 줄이도록 설계됐다고 애플 공식 문서는 안내한다. 2026년 7월 기준 애플은 iOS 14, macOS 11 이상에서 도입된 Logger 타입을 권장하는 것으로 알려져 있다. 이 글은 Swift로 iOS·macOS 앱을 만드는 개발자를 대상으로, 콘솔 출력을 os_log로 옮기는 기본 사용법을 다룬다. 서버 사이드 Swift나 서드파티 로깅 라이브러리는 범위 밖이다.

## os_log는 무엇을 하는 도구인가

os_log는 앱과 시스템의 동작 기록을 한곳에 모아 관리하는 통합 로깅(unified logging) 방식이다. 통합 로깅은 각 앱이 제각각 파일이나 콘솔에 남기던 기록을 운영체제가 표준화된 저장소에 모아 두는 구조를 말한다. 애플 공식 문서에 따르면 이 시스템은 iOS 10과 macOS Sierra 무렵 도입됐다고 안내된다.

핵심은 두 가지다. 하나는 기록을 레벨과 범주로 나눠 남긴다는 점이고, 다른 하나는 기록이 실제로 필요한 순간까지 문자열 조립을 미뤄 성능 부담을 줄이도록 설계됐다는 점이다. 그래서 디버깅용 임시 출력을 넘어, 배포된 앱에서 문제를 추적하는 상시 로깅 수단으로도 쓰인다.

## print, NSLog와 무엇이 다른가

가장 큰 차이는 성능과 구조다. print는 빌드 설정과 상관없이 문자열을 만들어 콘솔로 흘려보내지만, os_log는 기록이 실제로 소비되는 시점까지 포매팅을 미루도록 설계됐다고 애플 공식 문서는 설명한다. 로그가 걸러지는 상황에서는 문자열을 아예 만들지 않아 부담이 작다.

구조 측면의 차이는 다음과 같다.

- 서브시스템과 카테고리로 로그를 분류해, 나중에 원하는 영역만 골라 볼 수 있다.

- debug부터 fault까지 중요도 레벨이 나뉘어, 어떤 기록을 디스크에 남길지 시스템이 판단한다.

- 동적 값이 기본적으로 가려져, 개인정보가 로그에 그대로 남는 사고를 줄인다.

- 콘솔 앱이나 명령줄 도구에서 필터링과 검색이 된다.

정리하면 print는 개발 중 눈으로 확인하는 용도에 가깝고, os_log는 배포 뒤에도 남는 진단 기록에 가깝다.

## 기본 사용법: Logger 만들기

먼저 os 프레임워크를 가져온 뒤 Logger 인스턴스를 하나 만든다. 생성자에는 subsystem과 category 두 값을 넘긴다. subsystem에는 보통 앱의 번들 식별자처럼 앱 전체를 가리키는 문자열을 넣고, category에는 네트워크나 결제, 인증처럼 기능 영역 이름을 넣는다.

예를 들어 subsystem에 앱 번들 ID를, category에 network를 넣어 Logger를 만든 뒤, logger.notice로 요청 시작 같은 사건을 기록한다. 문자열 보간을 그대로 쓸 수 있어 변수 값을 끼워 넣기도 편하다. Logger는 가볍게 여러 개 만들어도 되지만, 같은 카테고리를 반복해 쓴다면 타입 프로퍼티(static let)로 한 번만 선언해 재사용하는 편이 관리에 낫다.

## 로그 레벨은 어떻게 골라 쓰나

레벨은 기록의 중요도이자, 그 기록이 메모리와 디스크에 얼마나 오래 남을지를 가르는 기준이다. 애플 공식 문서 기준 다섯 단계로 나뉘는 것으로 안내된다.

- debug: 개발 중에만 필요한 상세한 흐름. 평소에는 저장되지 않고 따로 수집할 때만 보인다고 안내된다.

- info: 문제 해결에 참고가 되는 정보. 명령으로 수집할 때 주로 확인한다.

- notice(기본값): 앱이 정상 동작하는 중에 남기고 싶은 핵심 사건.

- error: 실행에는 지장이 없지만 짚어 둘 오류.

- fault: 앱이나 시스템 수준의 심각한 결함.

실무 감각으로는 평소 흐름 파악은 notice, 잡아 두고 싶은 예외는 error, 복구가 어려운 문제는 fault로 나눠 두면 나중에 콘솔에서 심각도별로 걸러 보기 쉽다. 레벨을 뭉뚱그려 전부 notice로 남기면 정작 급한 로그가 묻힌다.

## 동적 값과 개인정보는 어떻게 다루나

문자열 보간으로 넣은 동적 값은 기본적으로 로그에서 가려진다. 애플 공식 문서에 따르면 이런 값은 콘솔에서 private 라는 표시로 대체돼 실제 내용이 드러나지 않는다고 안내된다. 사용자 이메일이나 인증 토큰이 무심코 로그에 남는 사고를 막기 위한 기본값이다.

디버깅을 위해 값을 그대로 봐야 한다면 보간 지점에 공개 여부를 지정할 수 있는 것으로 안내된다. 다만 공개로 바꾸는 값이 개인정보가 아닌지 한 번 더 확인하는 습관이 안전하다. 반대로 식별자는 남기되 원본은 가리고 싶다면 값을 해싱해 기록하는 방식도 문서에서 소개된다.

## 기록한 로그는 어디서 보나

보통 세 갈래로 확인한다. 개발 중에는 Xcode 콘솔에 실시간으로 출력된다. 배포된 기기나 다른 맥의 로그를 볼 때는 맥의 콘솔(Console) 앱에서 기기를 연결해 서브시스템과 카테고리로 필터링한다.

명령줄에서는 log 도구를 쓴다. 실시간 스트림은 log stream, 지난 기록 조회는 log show 형태로 쓰며, 서브시스템이나 레벨 조건을 붙여 원하는 항목만 추린다고 애플 공식 문서는 안내한다. CI나 원격 진단처럼 화면이 없는 환경에서는 이 명령줄 경로가 특히 쓸모 있다.

## 옮길 때 챙길 점

print에서 os_log로 넘어갈 때 자주 걸리는 부분을 정리한다.

- debug 레벨은 평소 저장되지 않으므로, 배포 뒤에도 남기고 싶은 기록은 notice 이상으로 남긴다.

- Logger를 호출할 때마다 새로 만들기보다 카테고리별로 하나씩 선언해 재사용한다.

- 보간 값의 공개 여부를 습관적으로 점검해 개인정보 노출을 막는다.

- 카테고리 이름 규칙을 팀에서 미리 합의해 두면 나중에 필터링이 수월하다.

로깅은 문제가 터진 뒤에야 가치를 드러낸다. 지금 print를 대충 흩뿌려 두기보다 레벨과 카테고리를 정해 os_log로 옮겨 두면, 배포 뒤 원인 추적에 드는 시간을 줄일 수 있다. 여러 스레드가 얽힌 문제를 로그로 추적하는 상황이라면 [세마포어와 뮤텍스의 함정 목록](https://trendbrief.news/articles/%EC%84%B8%EB%A7%88%ED%8F%AC%EC%96%B4%EC%99%80-%EB%AE%A4%ED%85%8D%EC%8A%A4-%EC%96%B8%EC%A0%9C-%EB%AC%B4%EC%97%87%EC%9D%84-%EC%93%B0%EB%82%98.html)이 좋은 체크리스트가 된다.

## 관련 글

- [코어 웹 바이탈 최적화, 세 지표 병목과 개선 방법](https://trendbrief.news/articles/%EC%BD%94%EC%96%B4-%EC%9B%B9-%EB%B0%94%EC%9D%B4%ED%83%88-%EC%B5%9C%EC%A0%81%ED%99%94-%EC%84%B8-%EC%A7%80%ED%91%9C-%EB%B3%91%EB%AA%A9%EA%B3%BC-%EA%B0%9C%EC%84%A0-%EB%B0%A9%EB%B2%95.md)
- [MCP 서버 만들기, 파이썬으로 첫 도구 연결하기](https://trendbrief.news/articles/mcp-%EC%84%9C%EB%B2%84-%EB%A7%8C%EB%93%A4%EA%B8%B0-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9C%BC%EB%A1%9C-%EC%B2%AB-%EB%8F%84%EA%B5%AC-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0.md)
- [스위프트 async await, 콜백에서 순차 코드로](https://trendbrief.news/articles/%EC%8A%A4%EC%9C%84%ED%94%84%ED%8A%B8-async-await-%EC%BD%9C%EB%B0%B1%EC%97%90%EC%84%9C-%EC%88%9C%EC%B0%A8-%EC%BD%94%EB%93%9C%EB%A1%9C.md)
- [도커 컴포즈 네트워크 설정: 기본 동작과 커스텀 구성](https://trendbrief.news/articles/%EB%8F%84%EC%BB%A4-%EC%BB%B4%ED%8F%AC%EC%A6%88-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%84%A4%EC%A0%95-%EA%B8%B0%EB%B3%B8-%EB%8F%99%EC%9E%91%EA%B3%BC-%EC%BB%A4%EC%8A%A4%ED%85%80-%EA%B5%AC%EC%84%B1.md)
- [세마포어와 뮤텍스, 언제 무엇을 쓰나](https://trendbrief.news/articles/%EC%84%B8%EB%A7%88%ED%8F%AC%EC%96%B4%EC%99%80-%EB%AE%A4%ED%85%8D%EC%8A%A4-%EC%96%B8%EC%A0%9C-%EB%AC%B4%EC%97%87%EC%9D%84-%EC%93%B0%EB%82%98.md)