ElasticAPM İle Monitoring

Osman Aktemur
hepsiburadatech
Published in
5 min readOct 30, 2019

ElasticAPM uygulamalarımızın performansını monitör edebilme ve günümüz dağıtık mimarisinde microservisler arasındaki pain pointleri görebilme zorluğunu distributed tracing ile görünür kılan open source bir application.
Dört ana bileşenden oluşmaktadır.

APM Agent Uygulama kodlarımızı instrument edip performans metriclerini toplamak için kullandığımız kütüphaneler. Mevcutta desteklenen diller: https://www.elastic.co/guide/en/apm/agent/index.html
APM Server APM agentlardan gelen datayı işleyen,anlamlandıran ve Elasticsearch’e gönderen application
Elasticsearch highly scalable açık kaynak kodlu tam metin arama ve analiz motoru.
Kibana Elasticsearch üzerinde bulunan datayı görselleştiren, indexler üzerinde arama yapabilmemizi sağlayan bir arayüz.

https://www.elastic.co/guide/en/apm/get-started/current/components.html

Dilerseniz örnek bi .Net Core uygulamasını nasıl trace edebileceğimize bir bakalım. Aşağıdaki komutlar ile elasticsearch, kibana ve apm serverı docker compose ile ayağa kaldıralım.

curl https://raw.githubusercontent.com/OsmanAktemur/ElasticAPM/master/docker-compose.yml --output docker-compose.yml
curl https://raw.githubusercontent.com/OsmanAktemur/ElasticAPM/master/apm-server.yml --output apm-server.yml
docker-compose up -d

apm-server.yml içerisinde ElasticAPM Server konfügürasyonları bulunmaktadır. İlk etapta default konfügürason dışında pek değişiklik yapmadım, sadece Elasticsearch’te oluşan indexleri günlük olarak oluşturmasını sağlayan bir konfügürasyon bulunuyor. Bu sayede sadece son 5 günlük datayı tutmak isterseniz curator v.b. toollarla 5 günden eski indexleri silebilirsiniz.

Docker ile elasticsearch, kibana ve apm serverı başarılı ayağa kaldırdığımız zaman http://localhost:5601/app/apm adresine giderek Elastic APM Kibana arayüzüne giriş yapabiliriz.

Örnek bi .Net Core Web API uygulamasını trace edebilmek için örnek bir api projesi oluşturalım, ve ElasticAPM agentını referans verelim

dotnet new webapi --name TestAPI
cd TestAPI
dotnet add package Elastic.Apm.NetCoreAll

Daha sonra Startup.cs içerisinde bulunan Configure metoduna aşağıdaki kod ile elastic apm middleware ekleyelim.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAllElasticApm(Configuration);
...
...

Son olarak ValuesController.cs içerisindeki api/values endpointini aşağıdaki gibi düzenleyelim

// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
HttpClient client = HttpClientFactory.Create();
var result = client.GetAsync("http://jsonplaceholder.typicode.com/todos/1").Result;
return new string[] { "value1", "value2" };
}

Daha sonra uygulamayı ayağa kaldırıp https://localhost:5001/api/values endpointine bi kaç istek yapalım ve tekrar apm kibana arayüzüne geçelim http://localhost:5601/app/apm.

Aşağıdaki ekran görüntüsünde olduğu gibi “TestAPI”servisimizi görebiliyor ve içerisindeki api/values endpointinden “jsonplaceholder.typicode.com” adresine istek yapıldığını ve ne kadar süre harcandığını görebiliyoruz.

Peki ya uygulama içerisindeki herhangi bir metodun performansını da izlemek istersek ne yapmalıyız? Bunun için de .Net Agentının Capture isimli metodunu kullanıyoruz. Bu şekilde ek olarak izlemek istediğimiz metodları da Span olarak Timeline üzerinde görebiliyoruz.

Örnek olarak:

Elastic.Apm.Agent.Tracer.CurrentTransaction.CaptureSpan("metodAdi", ApiConstants.ActionExec, ()
=>
{
//Calısacak metod veya kodlar
});

Bunun dışında .Net veya diğer dillerdeki agentlar için de geçerli temel bir kaç environment variable’ dan bahsetmekte fayda var.
ELASTIC_APM_SERVICE_NAME: Servisin adı. Aksi belirtilmedikçe assembly entryden uygulama ismini kullanır
ELASTIC_APM_SERVER_URLS: Elastic APM Server adresi. Default: http://localhost:8200
ELASTIC_APM_TRANSACTION_SAMPLE_RATE: Default olarak agentlar servise gelen bütün requestler için örnekleme alıp apm servera iletir. Fakat disk yetersizliği sorunu veya elasticsearch, apm server üzerindeki overheadi azaltmak için bu değeri düşürmekte fayda olabilir. Default değeri “1” dir, 0 ile 1 arasında değer alır. Örneğin “0.05” 100 isteğin 5'i için örnekleme al ve apm servera gönder demektir.

Biz Hepsiburada Order Management takımında Elastic APM’ i nasıl kullandığımızı ve örnek olarak bir siparişin oluşturulma sürecini nasıl izlediğimize göz atalım.

Hepsiburada örnek sipariş oluşturma akışı

Yukarıda örnek bir sipariş oluşturma transaction sample görebiliyoruz. Endor_Adapter_Consumer_Checkout uygulaması Checkout ekibi tarafından sipariş oluşturuldu eventini dinleyip Endor API’ a (order management servis diye düşünebilirsiniz) sipariş oluştur commandini vuran anti corruption layer. Yeri gelmişken bahsetmekte fayda var Endor_Adapter_Consumer_Checkout dediğimiz uygulama bir web api uygulaması değil bunu nasıl trace ediyoruz dersek yine aynı “Elastic.Apm.NetCoreAll” package kullanarak trace etmek istediğimiz metod başlamadan, daha önce gördüğümüz “CaptureSpan” metodu yerine “CaptureTransaction” metodunu kullanmamız yeterli oluyor. Ek olarak dış servislere atlan istekleri veya Entity Framework kullanıyorsanız sql sorgularını trace etmek için aşağıdaki şekilde Subscriberları kullanabilirsiniz.

Agent.Subscribe(new HttpDiagnosticsSubscriber());
Agent.Subscribe(new EfCoreDiagnosticsSubscriber());

Farklı dillerde yazılan agentların farklı yetenekleri bulunabilmekte. Örneğin NodeJS Express agentı MongoDB querylerini de otomatik olarak trace edebiliyor. Neyse lafı uzatmadan devam edelim.

Yukarıdaki ekran görüntüsünde görüldüğü üzere consumer uygulama Checkout tarafından publish edilen OrderCreated eventini dinleyip Endor uygulamasına CreateOrder commandini hazırlıyor. Bu commandi hazırlarken gerek duyduğu diğer bilgiler için Hepsiburadadaki diğer servislere istek atıyor ve nihayetinde Endor API’ a CreateOrder requesti gönderiyor. Ondan sonra gözüken yeşil kısımlar ise CreateOrder sırasında Endor API içerisinde gerçekleşen işlemler.

Bunların dışında APM tarafından sunulan diğer metricleri nasıl okuyacağımıza bir bakalım. Servisler listesinden monitör etmek istediğimiz bir servise tıkladığımız zaman sol üst tarafta “Transaction Duration” bölümünü görebiliyoruz. Bu bize servis bazında bize servisin Avg , 95th percentile ve 99 percentile değerlerini vermekte. (Aynı metricleri endpoint bazında görmek istersek servis içerisinde bulunan endpoint listesinden istediğimiz endpointe tıklamamız yeterli)

Transaction duration

Avg değeri servisin ortalama response verme süresini gösterirken, 95th percentile ve 99 percentile bize herhangi bir T zamanda servisin isteklerin yüzde 95'ini ya da 99'unu kaç X ms altında bitirdiğini göstermektedir. Örneğin 15.54:00'da isteklerin ortalaması 81ms iken, isteklerin 95% inin 523 ms altında cevap verdiği gözüküyor. Percentile terimi genel olarak ortalama değerlerin çok net cevaplar veremediği aykırı durumları tespit etmek için kullanılıyor.

Sağ tarafta ise dakika başına gelen istekleri ve http response codelarını görebiliyoruz

Üst taraftaki bulunan “Errors” tabinden servis içerisinde oluşan hataları, kaç kere tekrarlandıklarını ve en son ne zaman tekrarlandıklarını, “Metrics” tabinden ise servis CPU ve RAM kullanımlarını görebiliyoruz.

Son olarak herhangi bir transactionın süre dağılımını görmek için ilgili transactiona tıklayıp “Transactions duration distribution” paneline bakabiliriz. İsteklerin ne kadarının hangi aralıklarda response verdiğini, geç response veren aralıklardaki bi kümeye tıklayarak oradan bir transaction sample alıp nerelerde dar boğaz olduğunu görebiliriz.

Özet olarak Hepsiburada OMS takımı olarak ElasticAPM’i nasıl kullandığımızı, darboğazları nasıl görmemize olanak sağladığını ve kolay bir şekilde servislerimize implemente ettiğimizi göstermeye çalıştım.

Okuduğunuz için teşekkürler.

--

--