Golang ile tail uygulaması geliştirme

GNU/Linux dağıtımlarında tail komutu’na aşina olabilirsiniz. Genellikle -f flag’i ile dosyayı follow edip yeni eklenen metin’leri görmek için kullanıyoruz. Anlık log görüntülemek için oldukça kullanıyoruz.

Golang öğrenirken böyle bir programı go ile basitçe yazmayı araştırmaya başladım. Araştırmalarım sonucunda bu ufak makaleyi hazırladım.

İlk olarak hiçbir işletim sistemi api’si kullanmadan bunu nasıl yaparız ona bakalım.Çok basitçe hepimizin bazen yaptığı kötü çözümü entegre edelim. Dosyayı okuyup son satırlarını yazdırırır.Sonrasında sleep komutunu çalıştırıp tekrar okuyabiliriz.

Bu program teknik olarak çalışıyor ancak izlediğimiz dosyada değişiklik olur olmaz yanıt vermiyor. Çünkü son satıra ulaşınca bir süre uyuyor ve tekrar aynı işlemi yapıyor.Ayrıyetten her seferinde dosyayı tekrar okuyup yazıyor.

Tail programramı tabiki bunu bu şekilde yapmıyor. Linux, dosya sistemi olaylarını izlemek için inotify adında bir API sağlar.Bu API’yi kullanarak dosyadaki değişimi event olarak yakalyıp işlememiz mümkün.

API’nin kendi dökümanındaki açıklamasına bakalım:

The inotify API provides a mechanism for monitoring filesystem events. Inotify can be used to monitor individual files, or to monitor directories. When a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.

Açıklamadan’da anlayacağımız gibi aslında tam olarak ihtiyacımız olan şey. Dosyada değişiklik olduğunda bunu bize event olarak bildirmesini istiyoruz.

Golang’te syslog paketini kullanarak inotify api’yi kullanabiliriz.

https://pkg.go.dev/syscall#InotifyInit1

Yukarıdaki örnekte ise linux’taki inotify event’ini dinleyerek sadece değişiklik olduğunda değişikliği ekrana yazdırıyoruz.

Bu arada dosyaya veya klasöre ait daha fazla event dinleyebilirsiniz. İhtiyacınıza göre golang kaynaklarınızı incelemenizi tavsiye ederim.

Kaynaklar:

https://golang.hotexamples.com/examples/syscall/-/InotifyInit/golang-inotifyinit-function-examples.html

https://pkg.go.dev/syscall#InotifyInit1