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

PostgreSQL’de sepeatör ile ayrılmış tek bir sütunu array’e çevirip arama yapma

Merhaba

Bazı legacy tablo tasarımlarında tek bir sütun içerisinde aralarına virgül(,), noktali virgül vb. gibi ayırıcılar koyup listeyi tek sütunda saklanabiliyor.

Örneğin:

idusernameroles
1metinADMIN,EDITOR
2fatihEDITOR,MANAGER

Yukarıdaki tabloda roles sütunu aslında bir text aralarına virgül koyularak liste buraya eklenmiş. Bazen bu listedeki veriler uzayıp gidebiliyor.

Böyle bir tabloda arama yapmak için PostgreSQL’deki string_to_array fonksiyonunun 2. parametresini kullanarak çözebiliriz.

Öncelikle fonksiyonun tanımına bakalım:

string_to_array ( stringtext, delimitertext [, null_stringtext ] ) → text[]

Bu fonksiyon ile ayırıcı olrak belirtilen karater ile sütunu verip array olarak tek bir column’da elde edebilirsiniz. Böylece bu sütun üzerinde PostgreSQL’in array fonksiyonlarını çalıştırabilirsiniz.

Örnek bir sorgu:

SELECT string_to_array(roles, ',') AS role_list,* FROM users

Sonuç:

role_listidusernameroles
{ADMIN,EDITOR}1metinADMIN,EDITOR
{EDITOR,MANAGER}2fatihEDITOR,MANAGER

Örneğin üzerinde arama yapmak için

WITH users_with_roles AS (
SELECT string_to_array(roles, ',') AS role_list,* FROM users) SELECT * FROM users_with_roles WHERE ADMIN = ANY(role_list)

Yukarıdaki gibi bir sorguda kullanabilirsiniz.Veyahut kendi senaryonuza göre burayı json encode edip farklı işlemler de gerçekleştirebilirsiniz.

İleri seviyede bu şekide bir view oluşturup her seferinde ana sorguyu yazmamak ta iyi bir fikir olabilir.

Kaynaklar:

https://www.postgresql.org/docs/13/functions-array.html