pemrograman

04 Mempelajari Field, Entry dan Hook Logrus Pada Golang

Pada kali ini kita akan mencoba mempelajari Logrus lebih mendalam yaitu mengenai Field, entry dan Hook. Fitur-fitur yang disediakan oleh Logrus untuk kebutuhan Logger ini sangat bermanfaat sekali bagi kita ketika kita membutuhkan beberapa fitur yang menunjang bisnis kita. Misalkan field ini digunakan untuk menyisipkan data atau informasi ke dalam log dan beberapa lain yang akan kita bahas secara rinci.

Field pada Logrus

Ketika kita membutuhkan beberapa Field untuk dimunculkan atau disematkan dalam log file kita, maka Field ini bisa kita gunakan untuk menyisipkan sesuatu data atau informasi yang dibutuhkan untuk menunjang kebutuhan bisnis ataupun tracing ketika terjadi permasalahan pada sistem kita.

Sebenarnya bisa kita buat menyisipkan secara manual informasi tersebut di message-nya tetapi Logrus telah menyediakan cara yang lebih baik yaitu dengan menggunakan fitur Field. Dengan fitur ini bisa menambahkan informasi kepada log yang kita kirim sesuai dengan kebutuhannya.

Fungsi yang akan kita gunakan pada Logrus yaitu fungsi

logger.WithField()
// atau
logger.WithFields()

Langsung kita akan mencoba dengan membuat fungsi seperti dibawah ini.

func TestField(t *testing.T) {
	logger := logrus.New()
	logger.SetFormatter(&logrus.JSONFormatter{})

	logger.WithField("user_id", 12345).Info("Hello World")

	fields := map[string]interface{}{
		"user_id": 12345,
		"shop_id": 123,
	}
	logger.WithFields(fields).Infof("this is information about shop")
}

Maka akan terlihat output pada file seperti dibawah ini.

{"level":"info","msg":"Hello World","time":"2024-04-30T16:57:07+07:00","user_id":12345}
{"level":"info","msg":"this is information about shop","shop_id":123,"time":"2024-04-30T16:57:07+07:00","user_id":12345}

Bisa kita lihat pada output memiliki fields user_id dan baris yang terakhir terdapat fields user_id dan shop_id yang mana sudah kita buat field sendiri.

Entry pada Logrus

Entry ini adalah sebuah struct yang merepresentasikan dari log agar bisa dikirim oleh Logrus. Setiap log yang kita kirim itu sebenarnya akan dibuat oleh object Entry. Misalkan ketika membuat Formatter sendiri, maka parameter yang digunakan untuk melakukan formatting bukan tipe string melainkan yaitu object dari Entry.

Lebih lengkapnya bisa dibaca di file ini. Ketika kita membuat entry kita bisa menggunakan fungsi

logrus.NewEntry()

Sebenarnya Entry ini jarang sekali kita pakai tetapi untuk lebih memahami pelajaran log ini kita akan coba membuatnya dengan terlebih dahulu membuat fungsi seperti dibawah ini.


func TestEntry(t *testing.T) {
	logger := logrus.New()
	logger.SetFormatter(&logrus.JSONFormatter{})

	logger.WithField("user_id", 12345).Info("Hello World")

	entry := logrus.NewEntry(logger)
	entry.WithField("user_id", 1235)
	entry.Info("log info using entry")
}

Maka, hasilnya sama seperti halnya kita menambahkan Field karena pada dasarnya saat kita menambahkan field itu sama halnya inisialisasi Entry.

Hook pada Logrus

Hook pada Logrus ini adalah sebuah struct yang bisa digunakan untuk menambahkan ke dalam Logger sebagai callback ketika melakukan eksekusi log atau terjadi sesuatu pada sistem kita pada level tertentu.

Misalnya, kita akan mengirimkan notifikasi via chat ke Slack Channel ketika ada Log dengan level Error atau yang lainnya. Kita juga bisa menambahkan Hook custom dengan menggunakan fungsi

logger.AddHook()

Agar bisa lebih memahami mekanisme Hook, kita akan coba menggunakannya dengan terlebih dahulu membuat kode seperti dibawah ini.

type SimpleHook struct{}

func (s *SimpleHook) Levels() []logrus.Level {
	return []logrus.Level{logrus.ErrorLevel, logrus.FatalLevel}
}

func (s *SimpleHook) Fire(entry *logrus.Entry) error {
	fmt.Println("Simple Hook", entry.Level, entry.Message)
	return nil
}

Ini adalah contoh simpel ketika kita membuat Hook, sebelum melakukan set ke dalam Hook dari Logrus. Method Levels() ini digunakan untuk memastikan pada Level tertentu akan menggunakan Hook yang sudah kita inisialisasi.

Dan method Fire() ini yang nanti akan dieksekusi oleh Logrus sebagai mekanisme Hook setelah dilakukan logger.

Selanjutnya kita buat fungsi unit test untuk memastikan Hook yang kita buat berjalan dengan baik.

func TestHook(t *testing.T) {
	logger := logrus.New()
	logger.AddHook(&SimpleHook{})

	logger.Info("Hello info")
	logger.Warn("Hello warn")
	logger.Error("Hello error")
	logger.Fatal("Hello fatal")
}

Setelah kita eksekusi atau jalankan fungsi unit test tersebut maka akan terlihat seperti dibawah ini.

time="2024-04-30T17:44:58+07:00" level=info msg="Hello info"
time="2024-04-30T17:44:58+07:00" level=warning msg="Hello warn"
Simple Hook error Hello error
time="2024-04-30T17:44:58+07:00" level=error msg="Hello error"
Simple Hook fatal Hello fatal
time="2024-04-30T17:44:58+07:00" level=fatal msg="Hello fatal"

Terlihat pada log file terdapat Simple Hook error Hello error dan Simple Hook fatal Hello fatal setelah dilakukan logging, ini menandakan bahwa setelah melakukan log maka akan mengeksekusi Hook selanjutnya berdasarkan level yang sudah kita tentukan. Sedangkan ketika kita log pada level Info dan Warn itu tidak tereksekusi Hook yang sudah kita tambahkan.

Baiklah, bisa kita simpulkan bahwa Hook ini sangat bermanfaat buat kita untuk alerting ASAP (as soon as possible) untuk sistem kita jika terjadi masalah agar kita lebih (aware) pada sistem kita dan (acknowledge) lebih cepat.

comments powered by Disqus