fluentd Notlarım

Cem Topkaya
12 min readNov 13, 2020

--

Her şey syslog ile başladı. 80'lerde, Eric Allman tarafından geliştirilen Sendmail posta göndericisinin arka plan programına bir günlük kaydı çözümü gerekiyordu. Syslog böyle doğdu. Unix benzeri ekosistemdeki diğer uygulamalar tarafından hızla benimsendi ve bir standart haline geldi.

Kim ne yapar:

Originator (istemci), “Syslog istemcisi” olarak da bilinen bir oluşturucu, Syslog formatlı mesajı ağ üzerinden veya doğru uygulamaya göndermekten sorumludur;

Relay (röle), mesajları ağ üzerinden iletmek için bir röle kullanılır. Bir röle, örneğin zenginleştirmek için mesajları dönüştürebilir (ünlü örnekler Logstash veya fluentd’dir);

Collector (toplayıcı), “Syslog sunucuları” olarak da bilinen toplayıcılar, birden çok uygulamadan günlükleri depolamak, görselleştirmek ve almak için kullanılır. Toplayıcı, günlükleri çok çeşitli farklı çıktılara yazabilir: yerel dosyalar, veritabanları veya önbellekler.

syslogd ve rsyslog

Tarihi olarak, Linux’taki uygulamalarınızdan günlükleri toplama işi bir arka plan programının sorumluluğundadı. Birçok eski dağıtımda, bu görev syslogd adlı bir arka plana atanmıştır, ancak son dağıtımlarda yerini rsyslog arka plan programı almıştır.

systemd-journal

Systemd, son dağıtımlarda mevcut init işleminin yerini aldığında, günlükleri alma ve depolama konusunda kendi yöntemiyle geldi: systemd-journal.

Şimdi, iki sistem bir arada var oluyor, ancak bir arada bulunmalarının, geçmişte kullanılan günlük mimarileriyle geriye doğru uyumlu olduğu düşünülüyordu. rsyslog ve systemd-journal arasındaki temel fark, rsyslog’un günlükleri /var/log’da bulunan günlük dosyalarında tutması, journald’nin bunu yapacak şekilde yapılandırılmadıkça verileri saklamamasıdır.

systemd-journal yardımcı programı sisteminizdeki loglama aktivitelerini de takip eder. Hizmet olarak yapılandırılan bazı uygulamalar (örneğin bir Apache HTTP Sunucusu) doğrudan sistem günlüğüyle konuşabilir. Systemd günlüğü, günlükleri merkezi bir şekilde depolayan /run/log/journal dizinidir. Günlük dosyaları systemd tarafından ikili dosyalar olarak saklanır, bu nedenle, normal cat veya less komutlarını kullanarak dosyaları inceleyemezsiniz. Bunun yerine, systemd-journal tarafından oluşturulan günlük dosyalarını incelemek için “journalctl” komutunu kullanmamız gerekir.

Syslog, artık syslog standardında tanımlanan önem düzeyleri fikriyle geldi. Syslog aşağıdaki önem dereceleriyle gelir:

  • Emergency
  • Alert
  • Critical
  • Error
  • Warning
  • Notice
  • Informational
  • Debug

80'lerden sonra programlama dilleri gelişti ve farklı günlük kaydı çerçeveleri tanıtıldı. Günümüzde her programlama dilinin, verileri JSON gibi çeşitli biçimlerde kaydetmenize izin veren kendi günlük kaydı çerçevesi vardır. Çoğu durumda verileri metin dosyası, sistem günlüğü veya Elasticsearch gibi farklı hedeflere gönderebilirsiniz. Ancak biçim ve olası hedefler dışında, çoğu için ortak olan bir şey vardır — günlük olayının düzeyi.

Çoğu günlük kaydı çerçevesinde, aşağıdaki günlük düzeylerinin tümü veya bir kısmı ile karşılaşırsınız:

  • TRACE
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL

Bazılarının isimleri size ne hakkında oldukları hakkında bir ipucu veriyor ancak, biraz daha açalım.

TRACE, en ayrıntılı bilgilerdir, yalnızca uygulamanızda ve kullandığınız üçüncü taraf kitaplıklarında neler olup bittiğine dair tam görünürlüğe ihtiyaç duyduğunuz nadir durumlarda kullanılır. TRACE günlük kaydı düzeyinin çok ayrıntılı olmasını bekleyebilirsiniz. Örneğin, algoritmadaki her adımı veya her bir sorguyu kodunuzdaki parametrelerle açıklama eklemek için kullanabilirsiniz.

Standart işlem sırasında göz ardı edilebilecek, ancak uzun hata ayıklama oturumları sırasında yararlı olabilecek, kodunuzun adım adım yürütülmesini gösteren olayları açıklayan bir günlük düzeyi.

DEBUG, TRACE düzeyine kıyasla daha az ayrıntılıdır, ancak günlük kullanımda ihtiyaç duyacağınızdan daha fazladır. DEBUG günlük seviyesi, sorunları teşhis etmek ve sorun gidermek için veya her şeyin doğru çalıştığından emin olmak amacıyla test ortamında uygulama çalıştırırken gerekli olabilecek bilgiler için kullanılmalıdır.

Daha ayrıntılı bilgilere ihtiyaç duyulduğunda yazılım hata ayıklaması sırasında yararlı olduğu düşünülen olaylar için kullanılan bir günlük düzeyi.

INFO, bir şeyin olduğunu, uygulamanın belirli bir duruma girdiğini vb. gösteren standart günlük düzeyidir. Örneğin, yetkilendirme API’nizin denetleyicisi, yetkilendirme başarılı olursa hangi kullanıcının yetkilendirme talep ettiğine ilişkin bilgileri içeren bir INFO günlük düzeyi içerebilir. INFO günlük düzeyi kullanılarak kaydedilen bilgiler tamamen bilgilendirici olmalıdır ve bunlara düzenli olarak bakılmaması önemli bilgilerin kaçırılmasına neden olmamalıdır.

Bir olay oldu, olay tamamen bilgilendirme amaçlıdır ve normal işlemler sırasında göz ardı edilebilir.

WARN, uygulamada beklenmeyen bir durum olduğunu, bir sorun olduğunu veya süreçlerden birini aksatabilecek bir durumu gösteren günlük seviyesidir. Ancak bu, uygulamanın başarısız olduğu anlamına gelmez. WARN seviyesi beklenmeyen durumlarda kullanılmalıdır, ancak kod çalışmaya devam edebilir. Örneğin, belirli bir belgenin işlenmemesine neden olan bir ayrıştırma hatası oluştu.

Uygulama içinde beklenmeyen bir davranış meydana geldi ancak uygulama çalışmaya devam ediyor ve temel iş özellikleri beklendiği gibi çalışıyor.

ERROR, uygulama bir veya daha fazla işlevinin düzgün çalışmasını engelleyen bir sorunla karşılaşıldığında kullanılması gereken günlük düzeyidir. ERROR günlük seviyesi, ödeme sistemlerinden biri müsait olmadığı halde e-ticaret uygulamasında sepeti kontrol etme seçeneği varken veya herhangi bir nedenle sosyal medya loglama seçeneğiniz çalışmadığında kullanılabilir.

Bir veya daha fazla işlevsellik çalışmıyor, bu da bazı işlevlerin düzgün çalışmasını engelliyor.

FATAL, uygulamanın bir olayla karşılaştığını veya çok önemli iş işlevlerinden birinin artık çalışmadığı bir duruma girdiğini bildiren günlük düzeyi. FATAL günlük seviyesi, uygulama bir veritabanı gibi çok önemli bir veri deposuna bağlanamadığında veya tüm ödeme sistemleri kullanılamadığında ve kullanıcılar e-ticaretinizdeki sepetlerini ödeyemediğinde kullanılabilir.

Bir veya daha fazla temel iş işlevi çalışmıyor ve tüm sistem iş işlevlerini yerine getirmiyor.

Kaynaklar:

Docker Günlüklerini fluentd Sürücüsüyle Yakalamak

fluentd Sunucusunu Konteyner Olarak Ayaklandırmak

$ docker run --rm -d --name gunluk-havuzu \
-p 24224:24224 \
-p 24224:24224/udp \
-v /home/cnrusr/data:/fluentd/log \
fluent/fluentd:v1.3-debian-1

Docker Hub adresi (*)

fluentd Sürücüsüyle Günlükleri Sunucuya Etiketli Göndermek

$ docker run -d --name ping \
--log-driver=fluentd \
--log-opt fluentd-address=127.0.0.1:24224 \
--log-opt tag="oradamasin" \
alpine ping 127.0.0.1

$ docker run -d --name merhaba \
--log-driver=fluentd \
--log-opt fluentd-address=127.0.0.1:24224 \
--log-opt tag="selam" \
alpine echo "selam, nasılsın"

Gönderilen kayıtları sunucuda görüntüleyelim:

$ docker exec -it gunluk-havuzu cat /fluentd/log/data.log

Loki’ye göndermek için eklenti kurmamız gerekiyor (*).

fluentd Hakkında

$ /opt/td-agent/embedded/bin/fluentd -c <ayar-dosyası-yolu.conf>

Temel Bilgiler

Bir Günlük Kaydının Yapısı

En basit haliyle logger uygulamasının shell komutu:

# logger -i -plocal0.info -ttest cem naber teststring

ve üreteceği günlük kaydı şöyledir:

Dec 10 09:55:14 CEM-TOPKAYA-PC test[505]: cem naber teststring
  • source” yönergeleri girdi kaynaklarını belirler. Tüm verilerin geldiği direktif source olacak.
    Fluentd giriş kaynakları, kaynak direktifleri kullanılarak istenen giriş eklentileri seçilerek ve yapılandırılarak etkinleştirilir. Fluentd standart giriş eklentileri http ve forward içerir.
    http, gelen HTTP paketlerini almak için bir HTTP uç noktası sağlar.
    forward, TCP paketlerini almak için bir TCP uç noktası sağlar. Elbette her ikisi de aynı anda olabilir yani birden çok kaynak konfigürasyonu ekleyebilirsiniz.
  • match” yönergeleri çıktı hedeflerini belirler. Fluentd’ye ne yapacağını söyler.
    match yönergesi, eşleşen etiketlere sahip etkinlikleri (events) arar ve bunları işler. match direktifinin en yaygın kullanımı, olayları diğer sistemlere göndermektir. Bu nedenle, match yönergesine karşılık gelen eklentilere çıktı eklentileri denir. Fluentd ile gelen standart çıktı eklentileri file ve forward eklentileridir. Genellikle match direktifiyle çıktıya yönlendiririz ancak @type rewrite_tag_filter parametresiyle tag değiştirilip tekrar işlenebilecek başka filter tarafından alınabilir.
  • filter” yönergeleri olay işleme ardışık düzenlerini belirler. filter yönergesi match ile aynı sözdizimine sahiptir, ancak filter ardı sıra işlemler için zincirlenebilir. parse bölümü <source>, <match> veya <filter> direktifi altında olabilir.
  • system” yönergeleri sistem genelinde yapılandırmayı ayarlar
  • label” yönergeleri çıktıyı gruplandırır ve dahili yönlendirme için filtre uygular. label, boru hatlarını ayırarak karmaşık tag işlemeyi azaltır. Bunu biraz açalım. source direktifiyle tail, forward, http gibi kaynaklardan günlük kayıtlarını çeker, tag ile işaretler ve etiketine uygun ardışık filter direktifleri ile günlük kaydını işler ve match direktifiyle stdout, elasticsearch, mongodb, mail, file gibi çıktılara yönlendiririz. İşte günlük kaydının işlendiği süreçleri gruplamak için label kullanır ve doğrudan ilgili label grubuna yönlendiririz.
  • @include” yönergeleri diğer dosyaları içerir

dummy İle Sürekli Log Satırı Üretmek

dummy bir dizi ve içerisinde olan json nesnelerini sırayla ve sürekli döndürerek sanki log kayıtları oluşuyormuş gibi akıtır. JSON objesinde günlük kaydını “hede” adında bir property ile bağladığımız için sonraki aşamalarda “hede” özelliğine bakmalıyız.

<source>
@type dummy
tag cem
dummy [
{ "hede": "2020/11/11 11:09:06 452597 ALARM_CRIT...[{}]}" },
{ "hede": "2020/09/30 00:03:24 407613 DEBUG [140....af\"" }
]
</source>
<match>
@type stdout
</match>

rule İle Farklı Süzgeçlere/Eşleşmelere Yönlendirmek

<source>
@type dummy
tag cem.raw
dummy [
{ "log": "1020/11/11 11:09:06 452597 ALARM_CRITICAL .." },
{ "log": "2020/09/30 00:03:24 407613 DEBUG [14000273.." },
{ "log": "4020/11/11 11:09:06 452597 ALARM_cRITICAL .." }
]
</source>
<match cem.raw>
@type rewrite_tag_filter
<rule>
key log
pattern /\sALARM_[A-Z]+\s/
tag cem.alarm
</rule>
<rule>
key log
pattern /\sDEBUG\s/
tag cem.debug
</rule>
</match>
<match>
@type stdout
</match>

Çıktı içinde bazı gereksizleri nokta ile kısalttım:

2020-...00 cem.alarm: {"log":"1020/11/1..6 452597    ALARM_CRITICAL .."}
2020-...00 cem.debug: {"log":"2020/09/3..4 407613 DEBUG [14000273.."}
2020-...00 cem.alarm: {"log":"1020/11/1..6 452597 ALARM_CRITICAL .."}
2020-...00 cem.debug: {"log":"2020/09/3..4 407613 DEBUG [14000273.."}
2020-...00 cem.alarm: {"log":"1020/11/1..6 452597 ALARM_CRITICAL .."}

fluentd İçinde Grok Deseni Kullanmak

Varsayılan olarak grok desenleri yüklü değil ve bunu şu ekran çıktısında gösteriyor:

gem search -rd <yüklenecek paket adı> ile eksik kütüphaneleri yükleyebilirsiniz:

Kurulumdan sonra grok deseniyle çalışan örnek:

<source>
@type dummy
tag dummy.log
dummy [
{ "message": "Oct 24 09:01:33 mymachine uim-toolbar[5831]: Theme parsing error: <data>:2:30: The style property GtkWidget:focus-line-width is deprecated and shouldn't be used anymore. It will be removed in a future version" },
{ "message": "Oct 24 09:01:33 mymachine uim-toolbar[5831]: Theme parsing error: <data>:3:27: The style property GtkWidget:focus-padding is deprecated and shouldn't be used anymore. It will be removed in a future version" },
{ "message": "Oct 24 09:01:33 mymachine uim-toolbar[5831]: Theme parsing error: <data>:2:30: The style property GtkWidget:focus-line-width is deprecated and shouldn't be used anymore. It will be removed in a future version" }
]
</source>
<filter **>
@type parser
key_name message
<parse>
@type grok
<grok>
pattern %{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:host} %{SYSLOGPROG}: %{GREEDYDATA:message}
</grok>
</parse>
</filter>
<match **>
@type stdout
</match>

Örnek ayarlar, girdiler ve çıktıları

Günlük kaydı metin ancak içinde metin kodlu JSON verisi

Girdi günlük kaydı:

2020/11/11 11:09:06 452597    ALARM_CRITICAL [140413148362496 xxx.cpp:45->setAlarm]    {"alarmId":"32bcb763-9c89-4370-af08-0089d20ce271","alarmNature":"ADAC","alarmRaisedTime":"2020-11-11T11:09:06Z","eventType":"DATABASE_ACCESS_FAILURE","info":"Not Found, dbType:MONGO, dbPort:30558, dbIp:10.10.21.12","nfInstanceId":"81fdab8a-8605-11ea-bc55-0242ac130003","perceivedSeverity":"CRITICAL","probableCause":"DB is unreachable","serviceInstanceId":"81fdab8a-8605-11ea-bc55-0242ac130003","snssai":[{}]}

Çıktı:

{"Log_Time":"2020/11/11 11:09:06","logId":"452597","Level":"ALARM_CRITICAL","ID":"140413148362496","File":"CnrAlarmManager.cpp:45->setAlarm","hostname":"CEM-TOPKAYA-PC","tag":"cem","Messages":{"alarmId":"32bcb763-9c89-4370-af08-0089d20ce271","alarmNature":"ADAC","alarmRaisedTime":"2020-11-11T11:09:06Z","eventType":"DATABASE_ACCESS_FAILURE","info":"Not Found, dbType:MONGO, dbPort:30558, dbIp:10.10.21.12","nfInstanceId":"81fdab8a-8605-11ea-bc55-0242ac130003","perceivedSeverity":"CRITICAL","probableCause":"DB is unreachable","serviceInstanceId":"81fdab8a-8605-11ea-bc55-0242ac130003","snssai":[{}]}}

Çıktıyı veren ayar:

Tail komutunu bir fonksiyon olarak düşünün. Fonksiyonların ilk parametreleri mecburi sonrakiler seçimli olabiliyor.

ikinci parametrenin ön tanımlı değeri olduğu için seçimlidir

Buna göre tail fonksiyonunun gerekli ve seçimli parametrelerini görelim:

https://docs.fluentd.org/v/0.12/input/tail

Demekki eğer tail işlevini kullanacaksak type, tag, path, format parametrelerini tanımlamamız şart!

<source>
@type tail
path c:/temp/f_tail.log
tag cem
refresh_interval 30
read_from_head true
format /(?<Log_Time>\d{4}\/\d{1,2}\/\d{1,2} +\d{1,2}:\d{1,2}:\d{1,2}) (?<logId>\d{6}) +(?<Level>\w+) \[(?<ID>\w+) (?<File>.*)] (?<Messages>.*)/
</source>
<filter>
@type record_transformer
reserve_data true
<record>
hostname "#{Socket.gethostname}"
tag ${tag}
</record>
</filter>
<filter cenk>
@type record_transformer
reserve_data true
<record>
makineAdi "#{Socket.gethostname}"
etiket ${tag}
</record>
</filter>
<filter cem>
@type parser
key_name Messages
reserve_data true
remove_key_name_field true
hash_value_field Messages
<parse>
@type json
</parse>
</filter>
<match>
@type stdout
</match>

@type tail

in_tail eklentisi Fluentd’in metin dosyalarının sonundan olayları okumasını sağlar. Fluentd içinde tail’in davranışı tail -f komutuna benzer.

*nix Sistemlerde tail komutunu bilmeniz sizin için ve buraki kullanımını anlamanız için yerinde olacaktır (Wikinin Türkçe anlatımı).

-f (follow) diye özel bir komut satırı seçeneğiyle tail komutu dosyayı takip etmemizi sağlar. tail sadece son birkaç satırı görüntüleyip çıkmak yerine, satırları gösterir ve sonra dosyayı izlemeye başlar. Dosyaya başka prosesler tarafından yeni satırlar eklendiğinde tail görüntüyü günceller. Bu özellikle log (sistem tarafından tutulan günlük dosyaları) dosyalarını izlemek için çok faydalıdır. Komut satırında tail -f ~/.bash_history çalıştırdığınızda .bash_history dosyasının son 10 satırı izlemeye alınıyor, eğer başka bir konsoldan herhangi bir giriş yapılıp bu da .bash_history’ye kaydedilirse bunu anında görürüz.

path

Günlüklerimizin kaynağı bir dosya vepath ile günlük dosyasının yerini belirtiyoruz.

tag

Okuyacağımız ve dönüştüreceğimiz bu günlük kayıtlarını tag ile etiketliyoruz. Böylece daha sonra çalışmasını istediğimiz süzgeçler bu etikete bakarak işlem yapmaya başlarlar. Örneğimizde; okuduğumuz günlük kaydını alıyor dönüştürüyor ve sonraki olayla tutucuları tarafından işlenmesini sağlıyoruz (etiketsiz süzgeçler <filter> ve etiketi cem olanlar <filter cem>..).

refresh_interval

İzleme dosyası listesinin yenilenme aralığı. Varsayılan 60 saniyedir. Biz ise 30 saniyede bir okuma yapmasını istedik.

read_from_head

true Değeri verildiğinde günlükleri sondan değil, dosyanın başından okumaya başlar. Varsayılan false değeri atanmış ve dosyanın sonundan okur. Örneğimizde dosyamızda tek bir kayıt olduğu için ve denemelerimiz canlı ortam olmadığı için true verdim. Hedef dosya büyükse, okuması uzun zaman alır ve dosyanın okunması bitene kadar diğer eklentiler başlatılmaz.

format

Günlük kaydını okur okumaz bir başka şekil verilir ve olay akışına devam eder.

Birden Fazla Kanala Çıktı Vermek

Çıktı vermek için match direktifini kullanırız.

Sadece elasticsearch’e çıktı verir

filter Direktifi zincirlenebilirken match direktifi zincirlenemez. Bu yüzden peş peşe yazılmış match direktiflerinden sadece ilki çalışacaktır. Birden fazla çıktı vermek istiyorsak copy eklentisini kullanmamız gerekir. copy çıktı eklentisi, olayları birden çok çıktıya kopyalar.

Genel Hatalar

“‘key’ parameter is required, in section rule”

<rule> içinde key parametresini kullanarak hangi property içinde pattern içindeki düzenli ifadeyi çalıştırdığınızı belirtmelisiniz. Aşağıdaki ekran çıktısında key ile belirtilen gunluk özelliği içinde düzenli ifadenin bulunduğunu göreceksiniz.

<source>
@type dummy
tag cem.raw
dummy [
{ "log": "1020/11/11 11:09:06 452597 ", "gunluk":" ALARM_CRITICAL .." },
{ "log": "2020/09/30 00:03:24 407613 ", "gunluk":" DEBUG [14000273.." },
{ "log": "4020/11/11 11:09:06 452597 ", "gunluk":" ALARM_cRITICAL .." }
]
</source>
<match cem.raw>
@type rewrite_tag_filter
<rule>
key log
pattern /\sALARM_[A-Z]+\s/
tag cem.alarm
</rule>
<rule>
key gunluk
pattern /\sDEBUG\s/
tag cem.debug
</rule>
</match>
<match>
@type stdout
</match>

“‘tag’ parameter is required, in section rule”

Neticede etiketi yeniden yazıyoruz (@type rewrite_tag_filter). O halde kurala (<rule>) uygun bir günlük kaydını bulursak yeniden etiketlendirebilmemiz için tag (etiket) bilgisine ihtiyacımız olacak.

Olması gereken ise :

“‘pattern’ parameter is required, in section rule”

<rule> içinde 3 parametre girilmesi gerekir: key, pattern, tag

Hangi key içinde hangi patterne göre ne bulursak/bulamazsak tag değerini değiştirmeliyiz?

Olması gereken:

Fluentd ile LOKI’ye Günlük Aktarımı

Önce docker ile bir ubuntu makinası ayaklandırıyoruz. Bu makinada günlük kayıtları üretip üstüne kurduğumuz td-agent uygulamasıyla bu kayıtları başka bir konteynerde çalışan loki sunucusuna yönlendireceğiz. Loki, gelen kayıtları veritabanına kaydedecek ve yine başka bir konteynerde koşan Grafana üstünde görüntüleyeceğiz.

Fluentd’yi doğrudan kullanabileceğimiz gibi burada td-agent ile uyguluyor olacağız. Fluentd ile td-agent arasındaki farklar için buraya bakabilirsiniz.

docker run -it --name test ubuntu:xenial

td-agent Kurulumu için buradan farklı linux sürümlerinde nasıl yapılacağını buradan takip edebilirsiniz, bizim için xenial etiketli ubuntu 16.04 sürümünün kurulumunu şöyle yapacağız (alpine temelli yansı için bkz.):

# birazdan tanımlayacağımız paket sunucusuna erişim için
# GPG anahtarını sistemimize ekleyelim
$ curl https://packages.treasuredata.com/GPG-KEY-td-agent | apt-key add -
# Sunucuyu, apt'nin paket sunucuları listesine ekleyelim
$ echo "deb http://packages.treasuredata.com/4/ubuntu/xenial/ xenial contrib" > /etc/apt/sources.list.d/treasure-data.list
# Sunucudaki paketlerin "üst bilgilerini" bilgisayarımıza indirelim
$ apt-get update
# td-agent Uygulamasını kullanıcı etkileşim olmadan (-y) kuralım
$ apt-get install -y td-agent
# LOKI'ye veri basacak eklentiyi kuralım
$ /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-grafana-loki

Şimdi fluentd’ye ayar.conf dosyasını ekleyelim. Yeniden biçimlendirdiğimiz günlük kaydını 2 hedefe (loki + dosya) yazdıralım:

<source>
@type tail
path /var/log/cinar/nrf/NRF*.log
pos_file /var/log/td-agent/vtonrf.pos
tag vtonrf
format /(?<Log_Time>\d{4}\/\d{1,2}\/\d{1,2} +\d{1,2}:\d{1,2}:\d{1,2} \d{6}) +(?<Level>\w+) \[(?<ID>\w+) (?<File>.*)] (?<Messages>.*)/
read_from_head true
</source>

<match vtonrf>

@type copy

<store>
@type loki
url "http://minikube:32001"
flush_interval 1s
flush_at_shutdown true
buffer_chunk_limit 1m
extra_labels {"label":"nrf","agent":"fluentd"}
</store>

<store>
@type file
path /opt/cinar/nrf/flogs
</store>

</match>

Deneyip görmek için aşağıdaki komutu çalıştıralım, eğer kalıcı olacaksa /etc/td-agent/… içinde bu ayar dosyasını tutarak td-agent hizmetini başlatmak yeterli olacaktır:

fluentd -c <oluşturduğunuz_conf_dosyasının_tam_yolu>

Loki’yi minikube ile ayaklandırdığımız Kubernetes içinde çalıştırdığımız için ilgili nodeport ayarlarını verip dışarıdan bizim docker konteyner erişebilir olacaktır.

Docker-compose ile Grafana+Loki cihazlarını ayaklandıracak (ayrıca uygulama sunucusu olarak nginx ve metrik toplayıcı olarak prometheus’un da olduğu) kod havuzuma buradan erişebilir, kendiniz de deneyebilirsiniz.

Kaynaklar:

--

--

Cem Topkaya
Cem Topkaya

Written by Cem Topkaya

Evlat, kardeş, ağabey, eş, baba, müzik sever, öğrenmek ister, paylaşmaya can atar, iyi biri olmaya çalışır, hakkı geçenlerden helallik ister vs.

No responses yet