fluentd Notlarım
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 direktifsource
olacak.
Fluentd giriş kaynakları, kaynak direktifleri kullanılarak istenen giriş eklentileri seçilerek ve yapılandırılarak etkinleştirilir. Fluentd standart giriş eklentilerihttp
veforward
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ı eklentilerifile
veforward
eklentileridir. Genelliklematch
direktifiyle çıktıya yönlendiririz ancak@type rewrite_tag_filter
parametresiyletag
değiştirilip tekrar işlenebilecek başkafilter
tarafından alınabilir.
- “
filter
” yönergeleri olay işleme ardışık düzenlerini belirler.filter
yönergesimatch
ile aynı sözdizimine sahiptir, ancakfilter
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şıktag
işlemeyi azaltır. Bunu biraz açalım.source
direktifiyletail
,forward
,http
gibi kaynaklardan günlük kayıtlarını çeker,tag
ile işaretler ve etiketine uygun ardışıkfilter
direktifleri ile günlük kaydını işler vematch
direktifiylestdout
,elasticsearch
,mongodb
,mail
,file
gibi çıktılara yönlendiririz. İşte günlük kaydının işlendiği süreçleri gruplamak içinlabel
kullanır ve doğrudan ilgililabel
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.
Buna göre tail fonksiyonunun gerekli ve seçimli parametrelerini görelim:
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ğiyletail
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ındatail -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.
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 pattern
e 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: