fsnotify/fsnotify
요약
fsnotify는 Windows, Linux, macOS 등 다양한 운영체제에서 크로스 플랫폼 파일 시스템 알림 기능을 제공하는 Go 라이브러리입니다. 이 라이브러리는 inotify와 같은 백엔드를 사용하여 디렉토리 변경 사항을 감지하며, 사용자는 특정 이벤트(예: CHMOD)를 무시하거나 상위 디렉토리를 감시하여 관심 없는 파일을 필터링할 수 있습니다. 다만, NFS/SMB 프로토콜이나 가상 파일 시스템은 네트워크 수준 지원이 제한적이며, Linux 환경에서는 `sysctl`을 통해 inotify의 최대 감시(watch) 및 인스턴스 수를 조정해야 할 필요가 있을 수 있습니다.
핵심 포인트
- fsnotify는 Windows, Linux, macOS 등 다양한 OS에서 크로스 플랫폼 파일 시스템 알림 기능을 제공하는 Go 라이브러리입니다.
- 파일 변경 사항을 정확히 감지하기 위해 디렉토리 전체에 대한 '감시(watch)'를 명시적으로 추가해야 합니다. 재귀적 감시는 로드맵에 포함되어 있습니다.
- NFS나 SMB 같은 네트워크 프로토콜은 파일 알림에 대한 네이티브 지원이 제한적이므로, 폴링 방식의 구현이 필요할 수 있습니다.
- Linux 환경에서 inotify 기반으로 작동하는 경우, `fs.inotify.max_user_watches`와 `fs.inotify.max_user_instances` 같은 시스템 설정을 조정하여 감지 가능한 파일 수를 늘려야 할 수 있습니다.
- 개별 파일을 직접 감시하는 것은 원자적 업데이트 방식 때문에 권장되지 않으며, 상위 디렉토리를 감시하고 이벤트 이름으로 필터링하는 것이 일반적입니다.
fsnotify는 Windows, Linux, macOS, BSD, 그리고 illumos에서 크로스 플랫폼 파일 시스템 알림 (filesystem notifications)을 제공하는 Go 라이브러리입니다.
Go 1.23 이상의 버전이 필요합니다. 전체 문서는 https://pkg.go.dev/github.com/fsnotify/fsnotify 에서 확인할 수 있습니다.
플랫폼 지원:
| 백엔드 (Backend) | OS | 상태 (Status) |
|---|---|---|
| inotify | Linux | 지원됨 (Supported) |
| ... | 아직 지원되지 않음 |
Linux와 illumos에는 Android와 Solaris가 포함되어야 하지만, 현재 테스트되지 않은 상태입니다.
기본 예제:
package main
import (
"log"
...
더 많은 예제는 cmd/fsnotify에서 찾을 수 있으며, 다음 명령어로 실행할 수 있습니다:
% go run ./cmd/fsnotify
더 자세한 문서는 godoc에서 확인할 수 있습니다: https://pkg.go.dev/github.com/fsnotify/fsnotify
아니요, 파일이 이동된 위치를 감시하고 있지 않는 한 그렇지 않습니다.
아니요, 감시하고자 하는 모든 디렉토리에 대해 감시 (watches)를 추가해야 합니다 (재귀적 감시자 (recursive watcher)는 로드맵에 포함되어 있습니다: #18).
fsnotify가 작동하려면 하위 OS (underlying OS)의 지원이 필요합니다. 현재 NFS 및 SMB 프로토콜은 파일 알림에 대한 네트워크 수준의 지원을 제공하지 않으며, /proc 및 /sys 가상 파일 시스템 (virtual filesystems) 또한 마찬가지입니다.
이는 폴링 감시자 (polling watcher, #9)를 통해 해결될 수 있지만, 아직 구현되지 않았습니다.
일부 프로그램은 많은 속성 변경 (attribute changes)을 생성할 수 있습니다. 예를 들어 macOS의 Spotlight, 안티바이러스 프로그램, 백업 애플리케이션 등이 이에 해당합니다. 일반적으로 Chmod 이벤트를 무시하는 것이 가장 좋습니다. 이러한 이벤트는 유용하지 않은 경우가 많고 문제를 일으키는 경향이 있습니다.
macOS의 Spotlight 인덱싱은 여러 이벤트를 발생시킬 수 있습니다 (see #15). 네이티브 FSEvents 구현이 완료될 때까지 (see #11) 임시 해결 방법은 해당 폴더를 Spotlight 개인정보 보호 설정 (Spotlight Privacy settings) 에 추가하는 것입니다.
개별 파일(디렉토리가 아닌)을 감시하는 것은 일반적으로 권장되지 않습니다. 많은 프로그램(특히 에디터)이 파일을 원자적 (atomically)으로 업데이트하기 때문입니다. 즉, 임시 파일에 내용을 작성한 다음 이를 목적지로 이동시켜 원본을 덮어쓰는 방식(또는 이와 유사한 방식)을 사용합니다. 이 경우 원본 파일은 더 이상 존재하지 않으므로, 원본 파일에 설정된 감시자는 유실됩니다.
이것의 결과(upshot)는 전원 장애나 충돌(crash)이 발생하더라도 파일이 절반만 작성된 상태로 남지 않는다는 것입니다.
상위 디렉터리를 감시하고 Event.Name을 사용하여 관심 없는 파일들을 걸러내십시오. 이에 대한 예제는 cmd/fsnotify/file.go에 있습니다.
파일이 삭제될 때, 모든 파일 디스크립터(file descriptor)가 닫히기 전까지는 REMOVE 이벤트가 발생하지 않으며, 대신 CHMOD 이벤트가 발생합니다:
fp := os.Open("file")
os.Remove("file") // CHMOD
fp.Close() // REMOVE
이것은 inotify가 전송하는 이벤트 방식이므로, 이 부분에 대해서는 변경할 수 있는 것이 많지 않습니다.
fs.inotify.max_user_watches sysctl 변수는 사용자당 감시(watch) 수의 상한선을 지정하며, fs.inotify.max_user_instances는 사용자당 최대 inotify 인스턴스(instance) 수를 지정합니다. 생성하는 모든 Watcher는 하나의 "인스턴스"이며, 추가하는 모든 경로는 하나의 "감시(watch)"입니다. 제한에 도달하면 "no space left on device" 또는 "too many open files" 에러가 발생합니다.
이 값들은 /proc에서도 /proc/sys/fs/inotify/max_user_watches 및 /proc/sys/fs/inotify/max_user_instances로 노출됩니다. 기본값은 배포판(distro)과 가용 메모리에 따라 다릅니다.
이 값들을 늘리려면 sysctl을 사용하거나 proc 파일에 값을 직접 쓸 수 있습니다:
sysctl fs.inotify.max_user_watches=200000
sysctl fs.inotify.max_user_instances=256
재부팅 시 변경 사항이 유지되도록 하려면 /etc/sysctl.conf 또는 /usr/lib/sysctl.d/50-default.conf를 편집하십시오 (상세 내용은 Linux 배포판마다 다르므로 해당 배포판의 문서를 확인하십시오):
fs.inotify.max_user_watches=200000
fs.inotify.max_user_instances=256
kqueue는 감시 중인 모든 파일에 대해 파일 디스크립터(file descriptor)를 열어야 합니다. 따라서 5개의 파일이 있는 디렉터리를 감시한다면 총 6개의 파일 디스크립터가 필요합니다. 이러한 플랫폼에서는 시스템의 "max open files" 제한에 더 빨리 도달하게 됩니다.
sysctl 변수인 kern.maxfiles와 kern.maxfilesperproc를 사용하여 최대 오픈 파일(open files) 수를 제어할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub Trending Go (weekly)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기