fsnotify, Go dilinde yazılmış bir dosya sistemleri bildirim kütüphanesidir. Kütüphane, dosya sistemindeki dosya ve dizin değişikliklerini izleyebilir ve değişiklik olduğunda uygulamayı bilgilendirebilir. Çeşitli işletim sistemlerinde (Linux, macOS ve Windows gibi) çalışabilen ve cross-platform işletim sistemlerinde destek sağlar. fsnotify, Linux'taki inotify, macOS'ta FSEvents ve Windows'ta ReadDirectoryChangesW gibi farklı işletim sistemi dosya sistemi bildirim mekanizmalarını kullanmaktadır.

Go 1.17 veya daha yeni sürümlerinin kullanılması gerekmektedir; tam belgelendirme şurada bulunabilir: https://pkg.go.dev/github.com/fsnotify/fsnotify

Farklı işletim sistemleri için destek:

Backend İşletim Sistemi Durum
inotify Linux Destekleniyor
kqueue BSD, macOS Destekleniyor
ReadDirectoryChangesW Windows Destekleniyor
FEN illumos Destekleniyor
fanotify Linux 5.9+ Henüz desteklenmiyor
AHAFS AIX AIX dalı; Bakım eksikliği ve test ortamı nedeniyle deneysel özellik
FSEvents macOS x/sys/unix desteği gerektirir
USN Journals Windows x/sys/windows desteği gerektirir
Polling Tümü Henüz desteklenmiyor

Henüz Android ve Solaris dahil olmak üzere Linux ve illumos'u içeren işletim sistemleri test edilmemiştir.

Kullanım Senaryoları

fsnotify'in kullanım senaryoları şunları içerir, ancak bunlarla sınırlı değildir:

  1. Gerçek zamanlı dosya senkronizasyonu: fsnotify, dosya sistemindeki değişiklikleri gerçek zamanlı olarak izleyebilir ve gerçek zamanlı dosya senkronizasyonu uygulamak için uygundur. Kaynak dosyada değişiklik olduğunda, değişiklikler hemen hedef dosyaya senkronize edilebilir, dosyaların tutarlılığını sağlar.
  2. Otomatik derleme: fsnotify, proje kaynak kodundaki ve bağımlılık dosyalarındaki değişiklikleri izleyebilir, değişiklik olduğunda derleme komutlarını tetikleyerek otomatik derleme gerçekleştirebilir. Bu, manuel derleme süresini ve çabasını kurtarabilir ve geliştirme verimliliğini artırabilir.
  3. Dosya yedekleme: fsnotify, yedeklenmesi gereken dosya veya dizinlerdeki değişiklikleri izleyebilir ve değişiklik olduğunda hemen yedekleme başlatabilir. Bu, verinin güvenliğini sağlar ve dosya kaybı veya hasarı nedeniyle veri kaybını önler.
  4. Gerçek zamanlı log izleme: fsnotify, log dosyalarındaki oluşturma, değiştirme ve silme gibi işlemleri izleyebilir ve log dosyalarında değişiklik olduğunda log izleme programlarını tetikleyerek log içeriğindeki değişiklikleri etkili bir şekilde gerçek zamanlı olarak izleyebilir.
  5. Dosya sistemi güvenlik izleme: fsnotify, dosya sisteminden dosya erişimi, değiştirme ve silme gibi güvenlik olaylarını izleyebilir. Bu, dosya sisteminin güvenlik izleme özelliğini sağlar, güvensiz olayları hızlı bir şekilde tespit edip kaydedebilir.

Kullanım Örneği

Basit bir örnek:

package main

import (
    "log"

    "github.com/fsnotify/fsnotify"
)

func main() {
    // Yeni bir izleyici oluştur.
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }
    defer watcher.Close()

    // Olayları dinlemeye başla.
    go func() {
        for {
            select {
            case event, ok := <-watcher.Events:
                if !ok {
                    return
                }
                log.Println("Olay:", event)
                if event.Has(fsnotify.Write) {
                    log.Println("Değiştirilmiş dosya:", event.Name)
                }
            case err, ok := <-watcher.Errors:
                if !ok {
                    return
                }
                log.Println("Hata:", err)
            }
        }
    }()

    // İzlenmesi gereken yol eklenir.
    err = watcher.Add("/tmp")
    if err != nil {
        log.Fatal(err)
    }

    // Ana iş parçacığını bloke et.
    <-make(chan struct{})
}

Daha fazla örnek cmd/fsnotify içinde bulunabilir ve aşağıdaki komut kullanılarak çalıştırılabilir:

% go run ./cmd/fsnotify

Daha detaylı belgelendirme için godoc'a buradan ulaşabilirsiniz: https://pkg.go.dev/github.com/fsnotify/fsnotify

Sıkça Sorulan Sorular

Dosya başka bir dizine taşındığında hala izlenecek mi?

Hayır, eğer taşındığı konumu izlemiyorsanız.

Alt dizinleri izliyor mu?

Hayır, izlemek istediğiniz her dizin için izleme eklemeniz gerekir (özyinelemeli izleme planlanmıştır: #18).

Bir gorutinde hem hata hem de olay kanallarını eş zamanlı olarak izlemem gerekiyor mu?

Evet. Aynı gorutinde select kullanarak her iki kanaldan da okuyabilirsiniz (her kanal için ayrı bir gorutin başlatmanıza gerek yoktur; örneğe bakın).

Bildirimler neden NFS, SMB, FUSE, /proc veya /sys üzerinde çalışmıyor?

fsnotify işlev görmesi için altta yatan işletim sisteminden destek gerekmektedir. Mevcut NFS ve SMB protokolleri dosya bildirimleri için ağ düzeyinde destek sağlamamaktadır ve /proc ve /sys sanal dosya sistemleri de destek sağlamamaktadır.

Bu, bir anket izleyici kullanılarak düzeltilebilir (#9), ancak henüz uygulanmamıştır.

Neden çok sayıda Chmod olayı alıyorum?

Bazı programlar, özellikle macOS'taki Spotlight, antivirüs programları, yedekleme uygulamaları ve bazı diğer bilinen uygulamalar gibi çok sayıda özellik değişikliği oluşturabilir. Genelde Chmod olaylarını görmezden gelmek en iyi uygulamadır çünkü genellikle gereksizdir ve sorunlara neden olabilir.

Spotlight dizin indekslemesi macOS'ta çok sayıda olaya neden olabilir (bkz. #15). Geçici bir çözüm, yerel FSEvents uygulamasına sahip olana kadar klasörlerinizi Spotlight Gizlilik Ayarlarına eklemektir (bkz. #11).

Dosyaları izlemek iyi çalışmıyor

Genellikle (dizinler yerine) bireysel dosyaları izlemek önerilmez çünkü özellikle düzenleyiciler gibi birçok program dosyaları atomik olarak günceller: geçici bir dosyaya yazacak ve daha sonra onu hedef konuma taşıyacak, orijinal dosyayı üzerine yazacak (veya bir türevi). Orijinal dosyanın izleyicisi artık kaybolmuştur çünkü dosya artık mevcut değildir.

Sonuç olarak, bir güç kesintisi veya çökme yarım yazılmış bir dosyaya neden olmaz.

Ana dizini izleyin ve Event.Name'i kullanarak ilginizi çekmeyen dosyaları filtreleyin. cmd/fsnotify/file.go içinde bir örnek bulunmaktadır.

Belirli Platformlar için Notlar

Linux

Bir dosya silindiğinde, KALDIR olayı dosya tanımlayıcıları kapatılana kadar gönderilmez; bu zaman, bir CHMOD olayı gönderilir:

fp := os.Open("file")
os.Remove("file")        // CHMOD
fp.Close()               // REMOVE

Bu, inotify tarafından gönderilen olaydır, bu yüzden bununla ilgili çok fazla değişiklik yapılmamalıdır.

fs.inotify.max_user_watches sysctl değişkeni, kullanıcı başına maksimum izleme sayısını belirtirken, fs.inotify.max_user_instances maksimum inotify örnek sayısını belirtir. Oluşturduğunuz her Watcher bir "örnek"dir ve eklediğiniz her yol bir "izleme"dir.

Bunlar aynı zamanda /proc dizininde /proc/sys/fs/inotify/max_user_watches ve /proc/sys/fs/inotify/max_user_instances yolunda bulunabilir.

Bunları artırmak için sysctl kullanabilir veya değerleri proc dosyasına yazabilirsiniz:

sysctl fs.inotify.max_user_watches=124983
sysctl fs.inotify.max_user_instances=128

Değişikliklerin bir yeniden başlatmadan sonra etkili olması için /etc/sysctl.conf veya /usr/lib/sysctl.d/50-default.conf dosyasını düzenleyin (detaylar her Linux dağıtımı için farklılık gösterebilir, lütfen dağıtım belgelerine bakın):

fs.inotify.max_user_watches=124983
fs.inotify.max_user_instances=128

Sınırın aşılması "Cihazda boş yer yok" veya "Çok fazla açık dosya" hatalarına yol açacaktır.

kqueue (macOS, tüm BSD sistemleri)

kqueue, her gözlemlenen dosya için bir dosya tanımlayıcı açmayı gerektirir; bu nedenle, beş dosya içeren bir dizini gözlemliyorsanız, altı dosya tanımlayıcı olur. Bu platformlarda, sistemdeki "maksimum açık dosya" sınırına daha hızlı ulaşacaksınız.

Maksimum açık dosya sayısını kontrol etmek için kern.maxfiles ve kern.maxfilesperproc sysctl değişkenlerini kullanabilirsiniz.