Dağıtık Uygulamalar Dünyasında İzleme, Merkezi Log Sistemi ve İz Sürme

Today’s infrastructures and applications, when compared to the ones a few years back, are a lot more dynamic. Microservices, auto-scaling rules, immutable systems, multiple runtime stacks, chaos monkeys all make the infrastructures feel more like living organisms than architectured systems. Existing monitoring tools assume a more static world, and they fail to keep up with the changes in the infrastructure. Packetbeat’s mission is to provide monitoring and analytics solutions for the future’s highly dynamic infrastructures.

Mayıs 2015'te elastic.co (daha önceleri “elk stack” diye bilinen şimdilerdeyse “elastic stack” diye isimlendirilen açık kaynak elasticsearch, logstash, kibana, beats vb. ürünlerin sahibi olan şirket) bünyesine dahil olan Packetbeat şirketi derdini, varlık sebebini böyle anlatmış Linkedin sayfasında. Türkçe tercümesi şöyle: “Günümüzün altyapıları ve uygulamaları, birkaç yıl öncesindekilere kıyasla çok daha fazla dinamik. Mikroservisler, otomatik ölçeklendirme için uyulması gereken kurallar, kullan at (immutable) sistemler, birden fazla çalışma ortamları, kaos maymunları (Netflix aracı). Bunların hepsi, altyapıları tasarlanan ve öyle kalan sistemlerden çok, yaşayan organizmalar gibiler. Var olan izleme araçları daha durağan/statik bir dünya öngörmektedirler, o dünyada yaşamak üzere tasarlanmışlardır. Dolayısıyla altyapılardaki değişime ayak uydurmada başarısız olmaktadırlar. Packetbeat’in amacı, geleceğin yüksek ölçüde dinamik olan altyapılarına izleme ve analiz çözümleri sağlamaktır.”

Giriş yahut biz buraya nasıl geldik?

Her dünya kendi imkanlarını ve problemlerini beraberinde getiriyor. Bir dünyanın ötekine üstün olup olmaması değil mesele. Sadece farklılar. İhtiyaçlar farklı, beklentiler farklı, imkan dahilinde olanla imkansız arasındaki çizgi farklı. Hayalgücünün sınırları farklı.

Birkaç yıldır ortada dönen fırtınayı anlamakta zorlanıyordum. Ne işe yaradığını, hangi problemi çözmeye çalıştığını, nasıl bir dünyaya ait olduğunu bilmediğim araçlar tufanı. Bilmemek insanı huzursuz ediyor. Anlam verememek insanı huzursuz ediyor. Sınıflandıramamak huzursuz ediyor. Bilinmeyenler insanı huzursuz ediyor. Bilmediğimizi bilmediklerimiz değil, bilmediğimizi bildiklerimiz. Bilmediğimizin farkında olduklarımız. Farkına varmak, görmek huzursuzluk kapısını ardına kadar açıyor bizim için. 300 yıl uyuyup ardından gözünü günümüzde bir metropolde açan biri gibi. Hız, karmaşa, binlerce araç, bilgi seli. Taşların zihnimde yavaş yavaş yerine oturmaya başladığını hissediyorum, en azından eskisine oranla bu karmaşanın ait olduğu yeni dünyayı kavramaya daha yakın olduğumu hissediyorum.

Hep şu büyük İnternet şirketleri. Oyunun kimyasını değiştirdiler. Oyunu değiştirdiler. Yapılabileceklerin sınırlarını değiştirdiler. Çıplak göze sahip insanlara teleskop verdiler. Şimdi herkes uzak yıldızlara gitmeye çalışıyor. Herkes onları örnek alıp kendi uzay mekiklerini inşa ediyorlar. Kiminin hakikaten ihtiyacı oluyor, kimisi de sadece imkan dahilinde gördüğü için, yapabileceğini düşündüğünü için bunu gerçekleştirmeye çalışıyor.

Google, Amazon vb. şirketler hakikaten büyük ölçekte oynuyorlar. Dertleri büyük. İnternet = Google diyebiliriz belki. Tüm interneti saklamak, ve tüm dünyayadaki insanlara tüm dünyadaki internet ortamına aktarılmış neredeyse tüm veri üzerinde arama yapma ve erişme olanağı sunmak. Potansiyel ölçek yaklaşık 8 milyar kişi. Ve bu insanlar arasıra değil artık tümden internete bağlı/bağımlı durumdalar. Çoğu şeyi internet üzerinden yapmaya başlamışlar. Arama, bilgi edinme, alışveriş, sosyalleşme, dizi ve film izleme, müzik dinleme, haberleşme vs. Buna da web 2.0 denmiş. Hem trafik büyük, hem de uğraşılan veri büyük. Veri büyük. Veri büyük. Aha. Büyük veri…

Bu ölçekte oynayan şirketler haliyle kendi problemlerine çözümler geliştirmeye çalışmışlar. Dişiniz zonkluyorsa sırtınızın biraz ağrımasını pek hissetmezsiniz. Acıların yahut ihtiyaçların hiyerarşisi. Dolayısıyla işlem bütünlüğü, verilerin normalizasyonu, az yer tutma, kolay sorgulanabilir olma gibi ilişkisel veritabanlarının karşıladığı ihtiyaçlar, verinin büyüklüğü ve hızı yani ölçekleme ihtiyaçları karşısında silikleşmişler. Başka bir yerleri çok daha şiddetli ağrımaya başlamış yani.

Google örneğinden ilerleyecek olursak; “Google’ın misyonu, tüm dünyadaki bilgileri düzenlemek ve bunları herkes için erişilebilir kılarak kullanışlı hale getirmektir.” şeklinde ifade etmiş kendini. Google bu devasa veriyi ilişkisel veritabanlarında değil, daha sonra Cassandra benzeri NoSQL veritabanlarına da örnek teşkil edecek olan ve dağıtık GFS (Google File System) üzerine inşa edilen BigTable dağıtık veritabanınını geliştirerek orada saklamış. Dağıtık olarak tutulan bu veriler üzerinde arama ve dönüştürme işlemi yapmak için MapReduce tekniğini/aracını geliştirmişler. Birden fazla düğümdeki/sunucudaki veri tabanı üzerinde eş zamanlı sorgu çalıştırıp, her bir düğümdeki arama sonucunun elde edilip istenilen formata dönüştürülerek ana makineye iletilmesi (map), ve paralel sorguların sonuçların ana makinede birleştirilmesi ve nihai sonucun elde edilmesi tekniği (reduce). Ardından bu veritabanıyla ilgili bir makale yayınlamışlar ve problem ve çözümlerini dış dünya ile paylaşmışlar.

Bu ölçekte işlemci, bellek, IO, bant genişliği vb. ihtiyaçlar da devasa oluyor haliyle. Tabi web ölçeği bile eskinin ölçeği olmaya başladı. Mobil uygulamalar, akıllı hale getirilebilen tüm nesnelerin de ağa dahiliyle (işlemci, bellek koyarsan akıllı oluyor, bir de ağa bağladın mı nesneler haberleşmiş oluyor ve nesnelerin interneti diye söylenilen hadise ortaya çıkıyor; akıllı ev, araç takip sistemleri, tren/metro üzerinde sürekli veri üretip ileten sensörler vesaire) uğraşılan verinin hacmi, hızı, çeşitliliği daha da artıyor artacak. Veriler hem içeri hem dışarı doğru akıyor, artarak akmaya devam edecek. Büyüklük sürekli artıyor artacak. Devamlı büyüyen bu şeyi barındırmak için kutuyu da sürekli büyütmek gerekir. Çocuk sayısı artıp ev küçük gelmeye başlayınca ilk çözüm olarak daha büyük bir eve geçilir. O çocukların da çocukları olunca, onların da olunca birilerinin gitmesi gerekir, çünkü evlerin fiziksel bir büyüklük sınırı vardır. Yani büyük ailenin de bir büyüklük sınırı vardır. Ne kadar büyük aile? Kutunun yani sunucunun da fiziksel olarak büyümesinin (dikey büyüme) sınırları vardır. Bir sunucunun işlemcisi ne kadar artırılabilir? Belleği dünyayı içine alır mı? 8 milyar insanı içine alacak devasa bir ev yapılabilir mi? Yapmaya çalışmak mantıklı mı? Yoksa problemi küçük parçalara ayırarak mı halletmeli? Ülkeler, şehirler, ilçeler, mahalleler, sokaklar, apartmanlar ve evler. Dağıtık bir yapı. Google da bu ikinci yoldan ilerlemiş. İçine Dünyanın verisini koymak üzere devase bir makine yapmak yerine, kolaylıkla bir başkasıyla değiştirilebilen daha ucuz olan milyonlarca küçük küçük makineyi (commodity hardware) bir araya getirmiş ve dünyanın farklı yerlerindeki farklı veri merkezlerinde veriyi saklar ve işlemleri yapar hale gelmiş.

Kaynak: sevgili internet. Yatay ölçekleme ve dikey ölçekleme farkı, ve aralarındaki yaklaşım farkı.

Google kendi içinde kendi problemlerini çözmek için altyapısını kendisi oluştururken, e-ticaret işiyle uğraşan Amazon da kendi altyapısını oluşturmuş ve bunula yetinmeyip kendi altyapısını dışarıya açmış, ve Amazon Web Services (AWS) yi dünyaya getirmiş. Dananın kuyruğu da bu noktadan sonra kopmuş galiba. Altyapıların servis olarak sunulduğu, ağları, sunucuları, yük dengeleyicileri, yönlendiricilerin, veritabanlarını web arayüzü veya terminal üzerinden tanımlanabildiği, hatta bu işleri yapılabildiği sürükle bırak web arayüzlerinin ortaya çıktığı, sanallaştırmanın zirvesine çıkıldığı bir dünya ortaya çıkmış. SDX. Software Defined Everything. Her şeyin yazılım ile tanımlanabildiği bir dünya. Ve tabi SDN. Sofware Defined Networking. Ağ bileşenlerinin yazılımla tanımlanması. Telekom sektöründeki firmaların uğraş alanlarından biri. Ve de tabi XaaS: IaaS, PaaS, SaaS, BaaS, vs. Sanal makineler, platformlar, yazılımlar servis olarak sunulmaya başlamış. Temel kaynakları verince (sanal/fiziksel sunucuyu, depolama, işlemci) IaaS (Infrastructure as a Service) oluyor. Yani altyapının hizmet olarak verilmesi. Mesela Amazon EC2, S3 hizmetleri. Temel kaynakların üzerine bir değer katıp bir platform sağlanınca onda da PaaS (Platform as a Service) demişler. Sanal makineye işletim sistemi kurup, güncellemek, yedeklemek, ölçeklemek, veritabanı kurmak gibi şeylerle sen uğraşmıyorsun. Web arayüzünden veya API ilgili hizmeti ekleyip kullanıyorsun, yazdığın uygulamaya bağlıyorsun. Mesela Amazon SQS servisi, veritabanı servisi, filan. Veya Heroku, force.com, Google App Engine vb. platformlar. Bir üste çıkınca gmail, analytics, veya online CRM ürünleri sunan Salesforce gibi firmaların modeline de SaaS (Software as a Service) demişler. Ne verinin tutulmasına, ne sistemin işlemesine, ne işletilmesine, ne bakıma, ne de yedeklemeye sen karışmıyorsun. Senin verin ama onda duruyor. Sen sadece kullanıyorsun hizmeti.

Kaynak: sevgili internet. Pizza hizmet modeli benzetmesi. Benzetmeler anlamayı kolaylaştırsalar da, bir yandan da gerçeğin biraz üstünü örterler.

Google, Rackspace, Microsoft, VMWare ve büyüklü küçüklü bir çok şirket Amazon’a rakip olarak kendi ürünlerini ortaya koymuşlar, Amazonun tek başına yediği pastayı tırtıklamaya başlamışlar.

Altyapının hizmet olarak alınması, yani altyapının otomasyonu. Altyapının bir API yani yazılım aracılığıyla tanımlanması. Bir sanal makine için bir API çağrısı, bir veri tabanı için bir API çağrısı, bir yük dengeleyici için bir API çağrısı, bir uygulama sunucusu için bir API çağrısı. Sanallaştırma. Önce bu hizmeti kendi sunucuları üzerinden vermişler. Kurumsal dünyanın veri gizliliği vb ihtiyaçları için ilgili kurumun veri merkezinde çalışmak üzere bunu altyapıyı paketleyip satmaya başlamışlar buna da on-premise denmiş. Alıp kendi veri merkezine/kendi makinelerine kuruyorsun. Bu ikisini harmanlayanlara hibrit demişler. Daha sonra bu işi yapan açık kaynak yazılımlar çıkmış OpenStack benzeri. Kendi Amazonu’nu yapmak isteyenler için. OpenShift, CloudFoundry benzeri şeyler çıkmış kendi Heroku’sunu yapmak isteyenler için.

Nihayetinde konteynır teknolojisi çıkmış. Sanal makineler kadar büyük olmayan. Daha hafif, daha az yer kaplayan, soğanın kabukları gibi katmanlı bir dosya sistemine sahip olan, birkaç saniyede ayağa kalkıp birkaç saniyede kapanan ve uygulamalara sanal makine kadar olmasa da izole bir ortam sunan. Konteynırın içindeki uygulama açısından etkileşim, normal bir işletim sistemi ile bir uygulama arasındaki etkileşimin aynısı. Yani okyanusun içindeki teknenin içine konulan akvuryumlarda yaşıyor bizim balıklar. Her bir balığa ayrı bir akvaryum. Balık için akvaryum veya deniz farketmiyor. O suyu tanıyor.

Google hali hazırdaki veri merkezlerinde her şey konteynırlaştırılmış, yani konteynıra konup paketlenmiş ve öyle çalıştırılıyormuş. Yaklaşık 2 milyar konteynırdan söz ediyorlar.

Herkes Google, Amazon vb şirketler ölçeğinde iş yapmıyor; ama kullandıkları teknolojilerin dışa açılması, veya benzerlerinin başka şirketlerce çoğunlukla da açık kaynak olarak yapılıyor olması, imkan dahilinde olan ile imkansız arasındaki çizgiyi değiştirdi küçük şirketler için de. Bu yeni araçlar kümesi yeni bir dünya yarattı. Bu da insanların yazılım geliştirme tekniklerini, uygulama mimarilerini değiştirdi. Seçenekler, faydalar, problemler çeşitlendi, değişti. Artık insanlar Google’ın ve benzerlerinin kullandığı teknolojilerin muadillerini kendi sistemlerinde kullanabilir hale geldi. Kullanmak gerekli mi gereksiz mi bu duruma göre değişir, ama artık kullanmak mümkün hale geldi, bu da herşeyi değiştirdi.

Docker gibi konteynır teknolojisini kullanan araçlar, Ansible, Chef, Puppet gibi yapılandırma araçları, Mesos, Kubernetes, Docker Swarm gibi konteynır kümelerini (cluster) yönetme araçları, dinamik olarak pat diye ayağa kalkan, veya sonlandırılan konteynırların otomatik kaydeden servis keşif araçları Consul, Zookeper, Eureka gibi, yeni mimari kalıpları uygulamayı kolaylaştıran yeni kütüphaneler, yeni izleme araçları, merkezi log sistemleri, kısacası dağıtık uygulama mimarisi için gerekli olan araçların hızla artmasının verdiği ivmeyle de servis temelli mimarinin yeni bir yaklaşımı ortaya çıktı: mikroservisler. Mikro servisler. Yani tek bir uygulama yerine birbiriyle ağ üzerinden haberleşecek şekilde gevşek bağlı, bağımsız ekiplerce bağımsızca geliştirilip bağımsızca sürüm çıkılan, sunuculara kurulan uygulamalar. Küçük parçalara ayırmak bazı sorunlardan kurtarsa da (ölçekleme, bağımsız olarak sürüm çıkılıp çalıştırılma, farklı teknolojileri tüm sistemi etkilemeden deneyebilme, daha hızlı sürümler çıkabilme, teslimat sürelerinin kısalması vb.) yeni sorunlar getirdi beraberinde. Mikroservis mimarisine geçen şirketler kucaklarında buldukları yeni dertleri için yeni araçlar ortaya koydular, başkaları o araçları kullanır oldu, onlar da bir adım daha giderek yeni araçlar ürettiler. Biraz tavuk-yumurta ilişkisi oldu. Mikroservislerin vadettikleri ve bunu gerçekleştirmeye yetecek görünen araçlar diğerlerini cezbedip mikroservis mimarisine çekti, onlar da bu yeni mimarinin getirdiği problemlere daha iyi cevap verecek araçlar üretmeye çalıştılar, çalışıyorlar. Daha çözülecek çok problem var, işlerin, karmaşıklığı yönetmenin, izlemenin, takip etmenin kolaylaşması lazım.

Kaynak: Adrian Cockcroft. Kurulumların hızlanarak evrilmesi.

Toparlamaya çalışacak olursak, artık günümüzün dünyası, altyapıların dakikalar mertebesinde inşa edilebildiği, dakikalar içinde koca uygulama topolojisinin hep birlikte sıfırdan ayağa kalkabildiği ve isteğe göre ölçeklenebildiği (bir uygulamadan istediğin kadar kopya) bir dünya. Konteynır imajı oluşturulan bir uygulamayı birkaç saniyede ayağa kadırıbiliyoruz, ardından onu çöpe atıp yenisini oluşturubiliyoruz. Bu nedenle bunlara ölümlü (ephemeral) veya üzerinde değişiklik tamirat yapılmayan anlamında kullan at (immutable) diyorlar.

Asıl konumuza bağlanırken…

Bu dünya ve bu araçlar kümesi, ve bu dünyanın vaadettikleri, şirketleri (siz insanlar anlayın) mikroservislere çekiyor. Her nekadar var olan araçlar bir çok şeyi kolaylaştırsa da çözülmesi gereken daha bir çok problem var. Bunlardan biri de karmaşıklığı şirketten şirkete değişen uygulama sistemini takip etmek, yönetmek, performansını ölçebilmek, davranışını öğrenmek, izleyebilmek, hata oluştuğunda loglar arasında iz sürebilmek.

Tek bir uygulamaya (monolitik) sahip olduğumuzda onların loglarını da tek bir dosyaya yazarız. Belki ölçekleme yapıyoruzdur, ve bir yük dengeleyinin ardına stick_session kullanarak veya oturum bilgisini redis vb bir veritabanında tutarak bir kaç uygulamanın birkaç kopyasını (instance) daha çalıştırıyoruzdur. Bir veritabanı vardır, yedekli bir şekilde. Arada belki http istekleri varnish üzerinden geçiriliyordur her istek için uygulamaya gitmek yerine bazı istekleri ara bellekten (cache) sağlıyor olabiliriz. Biraz daha basit veya biraz daha karmaşık. Bu mimari oldukça statik bir yapıya sahiptir. Ortada birkaç makine, birkaç uygulama ve hızla değişmeyen bir mimari, oldukça durağan bir yapı.

Mikroservislerin dünyası ise her saniye yeni konteynırların ayağa kalktığı veya çöpe atıldığı, yeni yeni servislerin ortaya çıktığı, dağıtık (siz kaotik anlayın) ve dinamik bir yapıya sahip. Bir sürü makine var, bu makinelerde çalışan bir sürü servis var. Web arayüzünden bir işlemi yapmak için bir düğmeye basıyorsunuz o gidiyor bir sürü servis çağırıyor, o servisler de gidiyor başka servisleri çağrısı yapıyor, o servisler da başka servisleri çağırıyor, bazen dairesel çağrı zincirleri oluşuyor. Çünkü veri dağıtık bir şekilde servislerde tutuluyor. Hiç kimse her şeyi bilmiyor. Elimdeki bilgi sadece bütünün küçük bir parçasını teşkil ediyor. Elimde makalenin numarası var, Bir servise gidip o makaleyi istiyorum. Ancak o servis de sadece bölüm numaralarını biliyor. Ve o da her bir bölüm numarası ile ilgili servislere gidiyor ve o bölümleri alıyor. Ardından bölümleri sıraya koyuyor, birleştiriyor ve makale haline getiriyor ve cevap olarak geri gönderiyor. Bu servisler ayrı ayrı (sanal veya fiziksel) makinelerde çalışıyorlar. Ayrı ayrı log yazıyorlar. Bir hata oluştuğunda logların takibini yapmak güçleşiyor. Ayrıca konteynırlar ölümlü. Yani şimdi varlar ama birazdan olmayabilirler. Dolayısıyla ürettikleri logların da bir yerde tutulması, bir yere, bir veri deposuna aktarılması lazım.

Kaynak: Tudor Golubenco & Monica Sarbu. Mikroservislerin karmaşık iletişim dünyası.

Karşılamaya çalıştığımız ihtiyaç ne?

İhtiyacın iki ana odak noktası var, her ne kadar tamamen ayrı olmasalar da. İlki izleme. Sunucuların ve servislerin ve diğer bileşenlerin izlenmesi. Sahip olduğumuz kaynakların takibi, kullanım, doyum oranları, performans takibi. Ağ trafiğinin izlenmesi. İkincisi ise loglar. Logların toplanması, saklanması, loglarda iz sürme (distributed tracing) yahut samanlıkta iğne arama ve tabi loglara anlam kazandırılması yani analiz ve tabi görselleştirme, görsel analiz yahut görünür kılmak.

Servislerin ve altyapının izlenmesi

Tom Wilkie’nin hafızaya kazınan ifadesiyle “Eski dünyada izleme sisteminin birincil anahtarı (primary key) makineydi (host), mikroservislerin bulunduğu yeni dünyada ise birincil anahtar uygulama veya servistir”. Eskiden kullanageldiğimiz araçlar makineleri ve makinlerdeki kaynakları izliyorlar, yani makine merkezli ölçümler (metrik) topluyorlar. Yeni dinamik dünyada dinamik olarak değişen, ihtiyaca göre otomatik olarak ölçeklenen servisler merkeze oturmak zorunda. İzleme araçları servis merkezli olmalı.

Kaynak: http://blog.takipi.com/appdynamics-vs-dynatrace-battle-of-the-enterprise-monitoring-giants/. AppDynamics uygulama topoloji haritası.

Monolitik uygulamalara nazaran daha kaotik bir yapıya sahip oldukları için mikroservisleri izlemek, davranışını anlamak, karşılaşılan hataların kaynağını tespit edebilmek ve çözmek elzem ama bir o kadar da zor. “Building Microservices” kitabında Sam Newman çok çarpıcı biçimde ifade etmiş: “Bir problem ile karşılaştığımızda servis mi hatalıdır, servise ait bir konteynır mı arızalı, hepsi mi, tüm servisler mi, sistematik bir problem mi var?

Karmaşık bir sistemin ölçümlerine bakarken normalin/iyinin nasıl gözüktüğünü, ne olduğunu, neyin iyi/normal olduğunu bilmek zordur. Web sitemiz saniye 50 tane 500 hatası veriyor, bu iyi bişey mi, normal bişey mi? Katalog servisindeki işlemci kullanımı %20 arttı, bu normal mi? Bu kötü mü? Bir hata, problem mi var? Bir şeylerde terslik mi var? Ne zaman panik yapacağını, ne zaman sakin olacağını bilmenin yolu, “davranış biçimi” apaçık ortaya çıkacak kadar uzun bir süre boyunca sistemin nasıl davrandığı, davranışları hakkında ölçüm yapmaktır. “Normalin belirlenmesi”. Otomatik olarak ayarlanıp anında ayağa kaldırılan servislerin olduğu bir ortamda, her bir makineye ait ölçümleri hızla toplamaya başlayacak bir sisteme ihtiyaç bulunmaktadır…”

Dağıtık uygulamaların izlenmesi, performans takibi (APM), ağ trafik akış takibi. Yeni dünyanın izleme araçları olarak bazıları New Relic, DynaTrace, DataDog, AppDynamics, WeaweWorks, Sensu vb. araçlar öne çıkıyor. Bunların bazıları SaaS modeliyle çalışıyor, bazıları komple çözümler sunuyor, bazıları daha temel ölçümleri gösteriyorlar. Daha statik bir dünyanın araçları, bir önceki nesil izleme araçları olarak ise makine temelli izleme yapan nagios, zabbix vb. araçlar sayılıyor.

Servislerin haritası, bu harita üzerinde servisler arasındaki bağımlıkların, servislerin hata/başarı oranlarının, cevap verme sürelerinin, ortalam istek sayılarının gösterilmesi. Servislerin kaç kopyasının olduğu, kaynak kullanımı vb. metriklerin ölçülmesi. Belirli durumlar oluştuğunda alarm gönderilmesi. Ve tabi ölçmek, ölçmek, ölçmek. Uygulamanın performansını şu an için yükseltmeye ihtiyacımız olmasa da en azından performansımızın ne olduğunu bilmek. Normali ve anormali ortaya koymak. Ve tabi servislere tepeden kuş bakışı bakabilmek, büyük resmi görmek.

Kaynak: https://bigpanda.io/monitoringscape/ İzleme araçları

Log dünyası

Bundan birkaç yıl öncesine kadar benim için uygulama logları demek; Tomcat, WebLogic, Websphere vb. uygulama sunucuları üzerinde çalışan geliştirdiğimiz web uygulamasının bir dosyaya yazdığı loglardı. Log yazma mekanızmasını oluşturmak için Log4j kütüphanesini Java web uygulamasına entegre eder ve log rotasyonu, log formatı, log satırlarında nelerin içerileceği, hangi “context” bilgilerinin yer alacağını, log seviyelerini filan ayarlardık *.xml veya *.properties yapılandırma dosyalarını kullanarak.

Güncel tüm loglar tek bir dosyada olurdu (eski loglar log rotasyonu ayarlamasına bağlı olarak başka dosyalarda). Zaten tek bir uygulamamız, onun da çoğunlukla tek bir kopyası bazen de yedek olması için iki kopyası olurdu. Bu durumda işler nispeten basitti. Bir problem olduğunda ilgili kişinin/isteğin kimliği/numarası vb ile ilişkili logları bulmak çok zor değildi. Ya sayfada biraz aşağı yukarı gitmek eğer geliştirme ortamında ise, veya “grep”lemek çok log varsa yani gerçek veya test ortamında ise.

Sam Newman şöyle ifade ediyor problemi: “Web sitesinin hatalı davrandığı raporlanıyor. İlk önce neyi bilmeye ihtiyaç duyarsınız? Hatalı çalışan ne? Monolitik uygulamaların dünyasında araştırmaya başlamak için ilk olarak bakılacak yer bellidir: monolitik uygulama. Web sitesi yavaş: monolitik uygulama. Web sitesi garip hatalar veriyor: monolitik uygulama. İşlemci %100 e dayandı: monolitik uygulama. … İzlenecek birden fazla sunucu, bakılacak birden fazla log dosyası, probleme sebep olabilecek ağ gecikmelerinin olabileceği birden fazla yer. nereye bakacağız? probleme nasıl yaklaşmak lazım? Kimse kaotik, birbirine karışmış dolaşmış bir yumakla uğraşmak istemez. Problemin dolaysız bir cözümü var: büyük resmin görünmesi için logların toplanması.”

Bir sürü makinede bir sürü servisin ürettiği logların tek bir merkeze aktarılması gerekiyor bir problemi bir ayda çözmek istemiyorsak. Merkezi log sunucusu/sistemleri deniyor bunlara. Üç ana parçadan oluşuyor çözüm. Logların uygulamalardan toplanması, saklanması ve bir web arayüzünden insanlara sunulması. Yine tonlarca araç var bu alanda. Ücretli olanlar, açık kaynak ücretsiz olanlar, ikisini harmanlayanlar. Belli başlıları Splunk, Sumo Logic, Elastic Stack, Prometheus, Graphite, GrayLog vb….

Bir sürü araç, bir sürü farklı kombinasyon..

Logları bir yere toplamak problemin bir bölümü çözüyor. Aynı anda binlerce/milyonlarca istek bir servise gelip buradan farklı bir sürü servise dağılıp bir cevap geri gönderiyor ve bu esnada milyonlarca log üretiyor. Bir hata oluştuğunda bu hatayı bu log yığınının arasından ayıklayıp, sıraya koyup problemin nereden kaynaklandığını nasıl tespit edeceğiz, hatayı nasıl gidereceğiz? Bir sınıf düşünün, bu sınıftaki tüm öğrencilerin kitaplarını ve defterleri öğretmenleri alıp masanın üstüne koysun ve karıştırsın. Ardından herkese kitaplarını ve defterlerini almasını söylesin. Ne olur? Eğer kitap ve defterlerin üzerinde ayırt edici bir iz, bir işaret varsa isim varsa, bir kimlik numarası varsa problemin çözümü basittir, herkes kendi işaretini görüp kendisine ait olanı alır. Yani kitaplar ve defterler ile öğrenciler arasında bir karşılıklı ilişki (correlation) kurulmuş olur. Neyin kime ait oluduğu belli olur. Log dünyasında da benzer bir yaklaşım izleniyor. Her bir istek ayırt edici bir işaret konuluyor, bir korelasyon/kimlik numarası (coorelation id) enjekte ediliyor. Böylelikle o istek servisler arasında dolaşırken ardında kırmızı bir iz bırakıyor (şaka şaka) biz de o izi takip ederek hangi servislere gitmiş, ne cevap almış logları filtreleyerek görebiliyoruz.

Logları farklı seviyelerde izleyebilir/filtreyebilir olmamız gerekiyor:

  1. Kullanıcı seviyesinde: Sisteme giriş yapmış kullanıcının yaptığı tüm işlemleri/istekleri filtreyebilmemiz gerekiyor.
  2. İstek seviyesinde: Her bir isteği takip edip istek bazlı ayrım yapabilir olmamız gerekiyor.
  3. Alt istek/işlem seviyesinde: Bir istek kapsamında üretilen alt işlemlerin/isteklerin takip edibilir olması gerekiyor.
Kaynak: https://tech.knewton.com/blog/2016/04/distributed-tracing-design-architecture/. Dağıtık sistemde iz sürme. Çağrı zinciri. Context bilgisinin oluşturulması ve aktarımı.

Dağıtık bir sistemde yapılan bir isteğin hiyerarşik şekilde loglarını ilişkilendirilip erişilmesine dağıtık iz sürme (distributed tracing) deniyor. Google bu amaçla Dapper isimli bir aracı geliştirmiş ve kullanıyormuş. Açık kaynak bir örnek ise Twitter tarafından geliştirilmiş olan Zipkin. Ayrıca bkz: http://opentracing.io/ Temelde yaptıkları şey dağıtık uygulamalar için chrome geliştirici araçlarındaki ağ (network) sekmesinde sunulan işeve benzer işlev sunmak.

Kaynak: sevgili internet. Zipkin ve dağıtık iz sürme.

Loglar hata ayıklamanın ötesinde servisi izlemek, cevap verme sürelerini, hata sayılarını, oranlarını, istek sayılarını, servisin kullanımıyla ilgili bilgileri de işlemek ortaya çıkarmak üzere bir hammadde olarak ortada duruyor. Etkin bir şekilde analiz edip görselleştirildiğinde hem geliştiriciler, hem operasyon ekibi, hem de iş birimi için değer ifade edecek varlığı içinde barındırıyor. Her bir kitlenin işine yarayacak olan bilgi farklı, ilgi alanına girecek bilgi farklı, ihtiyaç duyduğu bilgi farklı. Ancak herkes için bir şeyler var burada. Geriye bu veriyi işleyip ortaya çıkarmak kalıyor. Aradığın kudret log verisinin içinde mevcuttur gibi bişey.

Elactic Stack

Elasticsearch, Logstash, Kibana, Beats ve ek ürünlerden oluşan araçlar kümesine verilen isim Elastic Stack, eski adıyla ELK stack. Beats kısmı yeni eklendi. Merkezi log sistemi için kullanılan açık kaynak bir araç.

Kaynak: sevgili internet. Elastic merkezi log sistemi mimarisi.

Loglar önce logstash a aktarılıyor. Logstash toplama aracı. Logstash depolanmak ve indekslenmek üzere Elasticsearch e iletiyor. Ön tarafta ise Elasticsearch’teki veriye erişmek ve görselleştimek, grafikler ve panolar oluşturmak için bir web arayüzü: Kibana.

Logstash:

  • Ruby ile yazılmış, açık kaynak.
  • Log toplama, ayrıştırma, zenginleştirme ve kaydetmek üzere iletmeye yarıyor.
  • Girdi + İşleme + Çıktıdan oluşuyor.
  • Farklı girdi tipleri için adaptörleri var. (syslog, gelf, veritabanı, beats, kafka, log4j, …)
  • Gelen log verisini işleyip, filtreleme, zenginleştirme işlemleri yapabiliyor.
  • Farklı çıktı tipleri için adaptörleri var. (eposta, elasticsearch, veri tabanı…)

Elasticsearch:

  • Lucene üzerine inşa edilmiş veri depolama, indeksleme ve metin bazlı arama aracı (full-text search). (açık kaynak rakiplerinden biri solr, o da lucene temelli)
  • Java ile yazılmış, açık kaynak.
  • Dağıtık lucene gibi düşünebilir.
  • Dağıtık, yatay olarak ölçeklenebilir.
  • REST arayüzü sunuyor, REST API ile karmaşık sorgulamalar yapılabiliyor.

Kibana:

  • JS ile yazılmış, Angular, Flot ve D3 kütüphaneleri kullanılmış
  • Eklenti yazılabiliyor
  • Elastic Stack in görselleştirme katmanı
  • Dört bölümden oluşuyor: Aramalar, Görselleştirmeler, Pano ekranı, Ayarlar
  • Aramalar, grafikler kaydedilebiliyor, pano ekranı oluşturulabiliyor.
  • Demo: http://demo.elastic.co/packetbeat

Beats:

elastic.co önce Packetbeat’i satın alıyor, ardından o strateji kapsamında beats modülünü geliştiriyor ve sunuyor. Ailenin ilk bireyi Packetbeat oluyor, ardından Logstash-forwarder Filebeat ismiyle aileye katılıyor, ardından diğer Metricbeat vb araçlar aileye katılıyor. Temelde sistemden veri toplayıp ileten küçük araçlar beats araçları. Log dosyalarını iletmek, sistem kaynaklarına ait bilgileri iletmek, tcp ve ağ trafiğini iletmek vb. işlevler için ayrı birer araç bulunuyor.

Kibana Kibana söyle bana…

Aslında sihirli olan Elasticsearch, Kibana onun önünde kullanıcı arayüzü sadece. İnsanlar için etkileşim arayüzü. Peki ne tür sorulara cevap bulabiliriz?

  • İstemci konumları
  • Zamana göre hataların sayısı
  • Başarılı/başarısız işlem sayısı
  • HTTP hata kodları ile ilgili grafikler
  • Gecikme/cevap verme süresi histogramları
  • En üstteki 5 sorgu için HTTP durum kodları
  • Saniyede işlenen istek sayısı (throughput)
  • Yazma ve okuma isteklerinin karşılaştırılması
  • En yavaş sorgular
  • En sık yapılan HTTP istekleri
  • En yavaş istekler
  • Normalde hızlı olduğu halde yavaş cevap vermeye başlayan servisler, anomali tespiti
  • Normalde yavaş olduğu halde hızlı cevap vermeye başlayan servisler, anomali tespiti
  • Normalden daha fazla sayıda 502 veya 400 hatası almaya başlanılan servisler, anomali tespiti

Bir log kaydında yer alan hemen hemen tüm terimleri kullanarak analizler yapmak, sorular sormak, grafikler üretmek mümkün.

Elasticsearch ün API si ile Kibana arayüzü birebir örtüşüyor. Kibana arayüzünden yapılan sorgu/görselleştime seçenekleri Elasticsearch API ye REST API isteği olarak tercüme ediliyor, gelen cevap ekranda gösteriliyor. Kibana terminolojisi ile Elasticsearch terminolojisi dolayısıyla örtüşüyor. Birine aşina olan diğerine de büyük ölçüde aşina olmuş oluyor.

Kibana’daki grafik tipleri: dikey çubuk grafiği, pasta grafiği, halka grafiği, harita, alan grafiği, çizgi grafiği, metrik.

Kibana’da (dolayısıyla elasticsearch’te) görselleştirme konusunda iki temel kavram bulunmaktadır. Bu iki kavramı iyi anlamak hayati. İlk kavram metrik (metric). İkincisi ise sepet (bucket). İlki bir istatikseksel fonksiyonu ifade ediyor. Toplam, ortalama vb. Aynen sql deki gibi. İkincisi ise gruplama yapmaya yarıyor. Verileri (her bir log verisi elasticsearch terminolojisinde bir döküman olarak isismlendiriliyor) farklı kriterlere göre gruplayabiliyoruz. Yani her bir sepete bir kriter tanımlıyoruz ve o kritere uyanları o sepete koyuluyor. Bu açıdan bakıldığında bir Doküman birden fazla sepete konulabilir. Örneğin uygulamanın hata döndüğü durumları gösteren bir grafik olulturmaya kalktığımızda, 502 hata kodu dönülmüş bir istek logu, hem 502, hem 500 ve üzeri, hem de hatalı cevaplar sepetlerine dahil olur. Gruplama da aynen sql deki group by ifadesi gibi gruplamaya yarıyor. Ayrıca bir sepeti alt sepetlere (gruplara/alt kümelere) ayıabiliyoruz. Böylelikle 500 ve üzeri hata kodu dönmüş isteklerin ne kadarının 500, ne kadarının 502, ne kadarının 503 olduğunu oransal olarak veya sayısal olarak görebiliyoruz.

Metrik ve sepet birleşip toplamı/sorgu sonucunu (aggregation) oluşturuyor.

Sepet/gruplama tipleri: zaman histogramı, histogram, aralık, zaman aralığı, ipv4 aralığı, terimler, filtreler, önemli terimler den oluşmaktadır.

Metrik tipleri: adet, en büyük, en küçük, ortalama, toplam, yüzde, farklı adet (unique count)

Bir toplam sadece metrik içerebilir, sadece sepet içerebilir, veya ikisinin farklı kombinasyonlarını. Verileri gruplayarak sepetlere koyuyoruz ve ardından istatiksel fonksiyonları çalıştırarak her bir sepet için sayısal bir değer üretiyoruz. 500 hatası veren istek sayısı 100. 502 hatası verenler 60 tane. Hata kodu 500 ve üzeri olan istek sayısı ise 300. Gibi şeyler. Bunları çubuk, çizgi, pasta, halka vb. Grafiklerde ifade edip görselleştiribiliyoruz. İstersek tablo ile ifade edebiliyoruz.

Sadece lafta kalmasın…

Merkezi log sistemi için örnek bir uygulama oluşturdum. Kullanılan teknolojiler Docker, Docker Compose, ELK, ağ topolojisi ve konteynırların görselleştirilmesi için WeaveScope, ve tabi golang ile yazılmış çok basit bir web uygulaması. Web uygulaması sadece “Merhaba” diyebiliyor, ve konteynır içinde paketlenmiş bir şekilde çalışıyor. Diğer bileşenlerin de hepsi Docker konteynırların içinde çalışıyor. Docker compose ise bu konteynırların hepsini birden ayağa kaldırmak, yönetmek için kullanılıyor. Merhaba web uygulaması isteği ve cevabı logluyor, Docker konteynırı gelf protokolüyle logları Logstash’e gönderiyor. Logstash ise Elasticsearch e aktarıyor logları. Ardından Kibana web önyüz uygulaması ile bu logları görüntüleyip, görselleştirip grafikler oluşturabiliyoruz.

Demo proje için: https://github.com/sfazilyesil/log-monitor-helloserver

Sonlandırırken…

Eksiğiyle gediğiyle paylaşmak istedim. Bazıları hem okuyup hem tecrübe ettiklerim, bazıları ise sadece okuduğum şeyler. Sadece okuyup aktardıklarım daha yüzeysel olmakla malul doğal olarak. Faydalı olduysa ne mutlu.

Bazı Kaynaklar

Video Kaynakları

Kitaplar

Web Kaynakları