İçindekiler
- 1 Ofiste Bir Sorunun İzini Sürmek: Neden İzlenebilirlik?
- 2 OpenTelemetry’yi Kafada Netleştirmek: Neyi, Nereye, Nasıl Gönderiyoruz?
- 3 Küçük Bir Mimari: Laravel, Node.js ve Aradaki Bağ
- 4 Jaeger ve Tempo’yu Hızlıca Ayağa Kaldıralım (Collector ile)
- 5 Laravel Tarafı: OTel’i Tak, Bağlamı Yay, İzleri Kolektöre Bırak
- 6 Node.js Tarafı: SDK, Otomatik Enstrümantasyon ve Bir Tutam Log Eşleştirme
- 7 Laravel → Node: Bağlamı Uçurmak, İzi Tek Parça Görmek
- 8 Örnek Senaryo: 700 ms’lik Kayıp Nerede?
- 9 Sampling, Gizlilik ve Üretimde Sakin Kalan Bir İz Akışı
- 10 Grafana, Jaeger ve Günlük Yaşam: Nereden Bakmalı?
- 11 Üretimde Ufak Tefek Taşlar: Nginx, Deploy, Versiyonlama
- 12 Uçtan Uca Küçük Bir Demo Akışı
- 13 Kapanış: Yükü Akılda Değil, İzlerde Taşımak
Ofiste Bir Sorunun İzini Sürmek: Neden İzlenebilirlik?
Hiç başınıza geldi mi? Kullanıcı “Sepete ekle çalışmıyor” der, panelde her şey yeşildir, loglarda sanki dünya güllük gülistanlık… ama gerçek dünyada biri sinirle sayfayı yeniliyordur. Benim de bir sabah tam böyle oldu. Laravel’le yazılmış API, arkasında küçük bir Node.js servis, üstte bir Nginx, arkada bir veritabanı derken zincirde bir halka gecikiyor, ama neresi olduğu bir türlü görünmüyordu. O gün anladım ki, loglar tek başına hikâyeyi tamamlamıyor; akıştaki her adımı, uçtan uca izlemek gerekiyor.
İşte burada OpenTelemetry devreye giriyor. Uygulamalar arasında gezen bir istek, Laravel’den Node’a, oradan veritabanına nasıl gidiyor, nerede oyalanıyor, kim topu düşürüyor, hepsini bir iz olarak görmek mümkün. Bu yazıda, PHP/Laravel ve Node.js servislerinde iz toplamayı nasıl kurduğumu, Jaeger ve Tempo gibi hedeflere bu izleri nasıl aktardığımı ve yolda öğrendiğim püf noktaları anlatmak istiyorum. Teknik detay var ama gözünüz korkmasın; bir kahve eşliğinde, sohbet eder gibi ilerleyeceğiz.
Mesela şöyle düşünün: İsteğinize bir GPS takıyoruz. O GPS, her uğradığı durağı not ediyor; süreleri, etiketleri, hatta bazen küçük anekdotları. Sonra bu not defterini Jaeger veya Tempo’ya veriyoruz. Orada açıp “Hangi durakta trafik vardı?” diye bakıyoruz. Basit gibi duruyor ama ilk kurulumda ufak taşlara takılmamak için bazı ipuçları var; hepsine değineceğim.
OpenTelemetry’yi Kafada Netleştirmek: Neyi, Nereye, Nasıl Gönderiyoruz?
OpenTelemetry (kısaca OTel), uygulamanızdan ölçüm, log ve iz toplayan bir çatı. Bu yazının kahramanı izler (traces) olacak. Her istek bir trace, o trace içindeki her adım bir span. Span’lerin üzerine etiketler, süreler, durumlar yazıyoruz. Laravel’de bir controller, Node.js’te bir HTTP çağrısı, Redis sorgusu veya harici API beklemesi… Hepsi birer küçük kare gibi düşünün. Kareler yan yana gelince film oluyor.
Bir de “Bu filmi nereye izlemeye taşıyoruz?” kısmı var. İki güzergâh kullanacağız: Jaeger ve Tempo. Jaeger, izleri görselleştirmesi kolay bir arayüz sunuyor. Tempo ise izleri saklamada esnek davranıyor, Grafana ile güzel bir ikili oluyor. Hatta isterseniz ikisine birden göndermek mümkün; ben çoğu zaman aracı olarak OpenTelemetry Collector kullanıyorum. Collector’ı bir kavşak gibi düşünün: Uygulamalardan izleri alır, filtreler, etiketler ve doğru yöne yollar.
Bu arada “Loglar ne olacak?” diye aklınıza gelebilir. İz tek başına güçlü; ama loglarla yan yana yürüyünce tadından yenmiyor. Biz daha önce logları nasıl sakinleştirdiğimizi anlatmıştık; isterseniz VPS’te Loki + Promtail + Grafana ile merkezi loglama yazısına da göz atabilirsiniz. Bugünkü odak iz, ama log-trace eşleşmesi de büyük rahatlık.
Küçük Bir Mimari: Laravel, Node.js ve Aradaki Bağ
Gerçek hayatta şöyle akıyor: Kullanıcı bir butona basıyor, Laravel API isteği alıyor, bir validasyon yapıyor, sonra arka planda Node.js’te çalışan bir servisle konuşuyor. Node bir hesaplama yapıyor veya başka bir API’yi yokluyor, sonucu geri veriyor. Laravel de kullanıcıya “Tamamdır” diyor. Bu yolculukta kimi zaman Nginx’in önbelleği devreye giriyor, kimi zaman veritabanı bir saniye düşünmek istiyor. Sorun olduğunda kimin suçlu olduğu hissiyatla değil, veriyle ortaya çıksın istiyoruz.
İzlenebilirlikte kritik kısım bağlam yayılımı. Yani, Laravel’de başlayan trace kimliğini Node.js’e doğru şekilde aktarmak gerekiyor. Modern dünyada bu işin ortak dili W3C’nin traceparent ve tracestate başlıkları. Şanslıyız; OTel’in varsayılanı bu. Siz ekstra bir şey yapmasanız bile doğru ayarladığınızda Laravel’den Node’a çağrı yaparken HTTP başlıklarıyla bu bağlam taşınıyor. Böylece Jaeger veya Tempo ekranında tek bir iz altında iki servisi de yan yana görüyorsunuz.
Bazen, “Nginx mikro önbellek var, izler kırılır mı?” diye soruluyor. Orada da doğru yapılandırılırsa sorun çıkmıyor; önbellek beklenmedik gecikmeleri saklayabilir ama izlerin toplamı zaten size gerçek yolculuğu anlatıyor. Bu konuda performans tarafına meraklıysanız, Nginx mikro önbellekleme ile PHP uygulamalarını hızlandırma yazısı aklınızda olsun; izler ve önbellek birlikte güzel çalışır.
Jaeger ve Tempo’yu Hızlıca Ayağa Kaldıralım (Collector ile)
Bir şeyleri görmek için önce sahneyi kurmak lazım. Aşağıdaki Docker Compose, Collector’ı merkez alarak Jaeger ve Tempo’yu birlikte koşturur. Lokal denemeler için birebir. Prod’da daha düzenli hale getirebilirsiniz.
version: "3.8"
services:
otel-collector:
image: otel/opentelemetry-collector:latest
command: ["--config=/etc/otel-collector.yaml"]
volumes:
- ./otel-collector.yaml:/etc/otel-collector.yaml
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686" # Jaeger UI
- "14250:14250" # gRPC
tempo:
image: grafana/tempo:latest
command: ["-config.file=/etc/tempo.yaml"]
volumes:
- ./tempo.yaml:/etc/tempo.yaml
ports:
- "3200:3200" # Tempo API
- "4317:4317" # OTLP gRPC (opsiyonel)
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
Collector’ın ayar dosyası izleri hem Jaeger’e hem Tempo’ya gönderecek şekilde olsun. Receiver kısmı OTLP, exporter kısmı iki hedefe birden:
# otel-collector.yaml
receivers:
otlp:
protocols:
http: {}
grpc: {}
exporters:
jaeger:
endpoint: jaeger:14250
tls:
insecure: true
otlp/tempo:
endpoint: tempo:4317
tls:
insecure: true
processors:
batch: {}
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [jaeger, otlp/tempo]
Tempo için basit bir config yeterli olur. Grafana’dan ekleyip izleri görüntüleyebilirsiniz. Jaeger için 16686 portundan arayüze bakmak çok pratik. Tempo’yu Grafana üzerinde keşfetmek isterseniz, Tempo veri kaynağını ekleyip “Explore” ekranından trace arayabilirsiniz. İsteyenler detaylar için resmi OpenTelemetry dokümantasyonu, Jaeger’in sitesi ve Grafana Tempo’nun sayfası üzerinden gezinebilir.
Laravel Tarafı: OTel’i Tak, Bağlamı Yay, İzleri Kolektöre Bırak
Laravel’de iki yaklaşım var: Otomatik enstrümantasyon ve elle ufak dokunuşlar. Otomatik kısım, HTTP, veritabanı, queue gibi alanları kendiliğinden izleyebiliyor. Başlamak için projenize OTel paketlerini ekleyin ve ortam değişkenlerini Collector’a göre ayarlayın. Komutlar kabaca şöyle:
# composer.json için paketler (örnek)
composer require open-telemetry/opentelemetry open-telemetry/opentelemetry-transport-otlp
# Laravel özel bir köprü paketi kullanabilirsiniz (varsa proje ihtiyaçlarına göre)
Ortam değişkenleri en pratik kısım. .env dosyanıza şu ayarları bırakın:
# .env
OTEL_SERVICE_NAME=laravel-api
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OTEL_TRACES_SAMPLER=parentbased_always_on
Otomatik tarafı aktive etmek için bir bootstrap dosyasında veya bir Service Provider içinde tracer’ı başlatabilirsiniz. Paketlerin sağladığı otomatik kayıtlar varsa onları tercih edin. Elle bir örnek görmek iyi olur:
<?php
// app/Providers/TelemetryServiceProvider.php
namespace AppProviders;
use IlluminateSupportServiceProvider;
use OpenTelemetrySDKTraceTracerProvider;
use OpenTelemetrySDKTraceSpanProcessorBatchSpanProcessor;
use OpenTelemetrySDKTraceSamplerParentBasedSampler;
use OpenTelemetrySDKTraceSamplerAlwaysOnSampler;
use OpenTelemetryExporterOTLPTransportFactory;
use OpenTelemetryExporterOTLPSpanExporter as OtlpExporter;
class TelemetryServiceProvider extends ServiceProvider
{
public function register(): void {}
public function boot(): void
{
$endpoint = env('OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:4318');
$serviceName = env('OTEL_SERVICE_NAME', 'laravel-api');
$exporter = new OtlpExporter((new TransportFactory())
->create($endpoint . '/v1/traces', 'application/x-protobuf'));
$provider = (new TracerProvider(
new BatchSpanProcessor($exporter),
new ParentBasedSampler(new AlwaysOnSampler())
))->setResourceAttributes(['service.name' => $serviceName]);
// Uygulama genelinde kullanmak üzere Container’a koymak faydalı
$this->app->instance(TracerProvider::class, $provider);
}
}
“Trace kimliğini response’a yazayım ki loglarla eşleştireyim” demek çok mantıklı. Bunun için küçük bir middleware işinizi görür. İzlemenin açık olup olmadığını da umursamaz, mevcutsa alır:
<?php
// app/Http/Middleware/TraceHeaders.php
namespace AppHttpMiddleware;
use Closure;
use OpenTelemetryAPITraceSpan;
class TraceHeaders
{
public function handle($request, Closure $next)
{
$response = $next($request);
$span = Span::getCurrent();
$ctx = $span->getContext();
if ($ctx && $ctx->isValid()) {
$response->headers->set('x-trace-id', $ctx->getTraceId());
$response->headers->set('x-span-id', $ctx->getSpanId());
}
return $response;
}
}
Laravel’den Node’a HTTP çağrısı yaparken, OTel bağlamı otomatik taşımak için çoğu HTTP istemcisi hazır. Gerekirse manuel de ekleyebilirsiniz. Basitçe “traceparent” başlığını propagate etmek yeter: mevcut bağlamdan alın, isteğe ekleyin. Otomatik enstrümantasyon bunu genelde sizin yerinize yapar; yine de kontrol etmeyi seviyorum. Bu arada canlıya alırken panik yaşamamak için süreçleri adım adım kurmak lazım; bu konuda Node.js’i canlıya alırken dikkat edilecekler yazısındaki deploy ritüelleri izlerin sürekliliğini korumaya da yardımcı oluyor.
Node.js Tarafı: SDK, Otomatik Enstrümantasyon ve Bir Tutam Log Eşleştirme
Node dünyasında ayaklarımız yere sağlam basıyor. @opentelemetry/sdk-node ve otomatik enstrümantasyon paketi çoğu işi hallediyor. Kurulumda bir “tracing.js” dosyası oluşturarak uygulamadan önce OTel’i ayağa kaldıralım:
// package.json (ilgili paketler)
// npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http @opentelemetry/api
// tracing.js
'use strict';
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
// İsterseniz debug açın
// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
const exporter = new OTLPTraceExporter({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT ? `${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/traces` : 'http://localhost:4318/v1/traces'
});
const sdk = new NodeSDK({
traceExporter: exporter,
serviceName: process.env.OTEL_SERVICE_NAME || 'node-worker',
instrumentations: [getNodeAutoInstrumentations()]
});
sdk.start().then(() => {
console.log('OTel tracing started');
}).catch((err) => {
console.error('OTel init error', err);
});
Sunucu kodunda tek yapmanız gereken, uygulamayı başlatmadan önce bu dosyayı import etmek. Express kullandığınızı varsayalım:
// index.js
require('./tracing');
const express = require('express');
const fetch = require('node-fetch');
const app = express();
app.get('/compute', async (req, res) => {
// Burada başka bir API'ye istek de yapabilirsiniz, otomatik enstrümantasyon HTTP çağrısını span olarak kaydeder
res.json({ ok: true });
});
app.listen(3001, () => console.log('Node worker 3001'));
Log-trace eşleşmesi için küçük bir dokunuş daha yapalım. Winston veya Pino fark etmez; önemli olan geçerli bağlamdan trace id’yi çekmek. Küçük bir yardımcı yazalım:
// trace-log.js
const { context, trace } = require('@opentelemetry/api');
function traceIds() {
const span = trace.getSpan(context.active());
const ctx = span && span.spanContext ? span.spanContext() : null;
return ctx ? { trace_id: ctx.traceId, span_id: ctx.spanId } : {};
}
module.exports = { traceIds };
// logger.js (winston örneği)
const { createLogger, format, transports } = require('winston');
const { traceIds } = require('./trace-log');
const logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.printf((info) => {
const ids = traceIds();
return `${info.timestamp} level=${info.level} ${Object.entries(ids).map(([k,v])=>`${k}=${v}`).join(' ')} msg="${info.message}"`;
})
),
transports: [new transports.Console()]
});
module.exports = logger;
Bu sayede, Grafana Loki gibi bir sistemde logları topladığınızda, Jaeger/Tempo’daki izlerle hızlıca eşleştirirsiniz. O gün yaşadığım sorunda tam da bunu yaptım; Laravel request id’siyle Node tarafındaki gecikmeyi yan yana koyunca zincir bir anda netleşti.
Laravel → Node: Bağlamı Uçurmak, İzi Tek Parça Görmek
Mesela şöyle düşünün: Laravel’de /checkout çağrısı geldi, arka tarafta Node’daki /compute tetiklendi. İki çağrıyı tek bir iz altında görmek istiyoruz. Otomatik enstrümantasyon çoğu zaman traceparent başlığını set eder. Ama gözünüz arkada kalmasın diye isterseniz manuel bir örnek:
<?php
// Laravel tarafında Guzzle ile istek atarken
use GuzzleHttpClient;
use OpenTelemetryAPITracePropagationTraceContextPropagator;
use OpenTelemetryContextContext;
$client = new Client();
$headers = [];
TraceContextPropagator::getInstance()->inject(Context::getCurrent(), $headers);
$response = $client->get('http://node:3001/compute', [ 'headers' => $headers ]);
Node’da otomatik enstrümantasyon HTTP sunucusunda traceparent’ı okuyup mevcut trace’e ekler. Böylece Jaeger ekranında tek bir iz, içinde Laravel ve Node span’leri. Tempo tarafında da aynı hikâye; Grafana Explore’da trace id’yi aratarak tüm akışı açarsınız.
Bu akışlar canlıdayken değişebilir. Deploy sırasında geçici bir karışıklık olmasın diye baştan birkaç kural koymak iyi oluyor. Blue/Green veya sıfır kesinti düzeni kurduysanız, izler de kesintisiz akar. Bu konuda veri tabanı şema değişikliklerini güvenle yapmak için yazdığımız sıfır kesinti şema değişiklikleri yazısındaki yaklaşım, servis dağıtımlarında da rahat ettirir.
Örnek Senaryo: 700 ms’lik Kayıp Nerede?
Bir akşam üstü, checkout süresi arada sırada 2-3 saniyeye vuruyor. Loglar sakin; CPU normal, bellek yerinde. İzleri açtım. Laravel controller 120 ms, veritabanı 40 ms. Sonra bir HTTP client call var, Node’a gidiyor. Node tarafı 80 ms gibi duruyor ama orada bir dış API çağrısı da var. O span 700 ms. Meğer o harici API, belirli parametrelerde throttling uyguluyormuş. O ana kadar sezgisel tahminlerle dolanırken, iz ekranda tam olarak parmağı doğru noktaya götürdü. Sonrası kolaydı; parametreleri sadeleştirdik ve kuyruğa alarak pik saatlerde hafiflettik.
Burada öğrendiğim bir şey daha oldu: İzlerde anlamlı etiketler çok iş görüyor. Örneğin “checkout.step=payment_request” gibi bir alan, veya “user.plan=premium” bilgisi, tablo gibi ağır durmadan, okuyanın gözünü yormadan fikir veriyor. Dikkat edilmesi gereken tek şey gizlilik. Kişisel veriyi veya kart bilgilerini izlere koymayın. Gerekirse maskeyle veya sadece tip bilgisini yazın.
Sampling, Gizlilik ve Üretimde Sakin Kalan Bir İz Akışı
Gelelim üretimde en çok sorulan soruya: “Hepsini mi örnekleyelim?” Cevap genelde hayır. İlk aşamada “parentbased_always_on” ile başlamak güzel; zincirin tutarlı kalmasını sağlar. Sonra trafiğiniz arttıkça “traceidratio” gibi bir oranla ayarlarsınız. Önemli aksiyonlar için oranı artırabilir, arka plan işleri için düşürebilirsiniz. Hatta hata durumlarında “tail” odaklı yaklaşımlar da var; ama ilk adımda bunu düşünmek şart değil.
Gizlilik tarafında basit bir kural koyun: “İze sadece teşhis için gerekli bilgiyi yaz.” Parametrelerin ham halini değil, türünü veya uzunluğunu yazmak çoğu zaman yeter. Kullanıcı kimliğini tamamen koymak yerine anonim bir referans kullanın. Böylece izler, günün sonunda bir güvenlik riski oluşturmadan işinizi görür.
İşletim tarafı da önemli. Collector, gönderen uygulamalardan yükü alır; kısa kuyruklar ve toplu gönderimle performansı korur. Uygulamanın kritik aksiyonlarında iz başlatırken abartıya kaçmayın; bir controller’a bir span, altındaki belirgin harici çağrılara birer span çoğu zaman yeter. Yarın bir gün daha derine inmek isterseniz zaten ekleyebilirsiniz. İzlenebilirlik bir defalık iş değil; yavaş yavaş olgunlaşan bir kas gibi.
Grafana, Jaeger ve Günlük Yaşam: Nereden Bakmalı?
Jaeger, “Hadi açıp bakalım bu izde ne var” dediğiniz anda hızlıca cevap veriyor. Hizmet adı, endpoint, süre filtreleri… Birkaç tıkla en uzun süren izleri masaya yatırırsınız. Tempo tarafında ise Grafana’nın Explore ekranı, izlerle metrikleri aynı pencerede düşünmeye güzel bir ortam yaratıyor. Mesela CPU grafiğinde bir tepe gördünüz, aynı zaman aralığında birkaç iz açtınız, ortak paydayı hızlı buldunuz. İzlerin dibine inmek istediğinizde “span logs” veya “events” alanlarına küçük notlar düşmek işe yarar.
Loglar demişken, iz ve log birlikte akınca iş ne kadar kolaylaşıyor fark ediliyor. Logları zaten toplayıp bir yerde tutmak istiyorsanız, Loki + Promtail ile log yönetimi yazısındaki tutma süreleri ve alarm pratikleri iz ekranında gördüğünüz sorunları teyit etmenize yardımcı olur. Ben günlük hayatta izden ipucunu alıp, logla teyit etmeyi seviyorum. Bir de küçük alarmlar kurunca gecikmeler büyümeden sizi dürter.
Üretimde Ufak Tefek Taşlar: Nginx, Deploy, Versiyonlama
Gerçekte her şey tertemiz işlemiyor. Nginx’te proxy ayarları, zaman aşımı limitleri, keep-alive davranışı gibi ince ayarlar izleri olduğu gibi etkiler. İzlerin “network” kısmında minik tırtıklar görürseniz aklınıza ilk bunlar gelsin. Ayrıca deploy sırasında Node veya PHP süreçleri yeniden başlarken kısa süreli kopmalar olabilir; izde boşluklar görürsünüz. Bu yüzden dağıtımda süreci yumuşatmak önemli. Canlıya alırken panik yapmamak için paylaştığımız sıfır kesinti deploy notları bu noktada çok değerli.
Bir de versiyon bilgisi eklemek harika bir alışkanlık. Hem Laravel hem Node için “service.version” gibi bir resource etiketi koyduğunuzda, bir izdeki sorunun hangi sürüme ait olduğunu tek bakışta görürsünüz. Rollback sonrası izler karışmıyor, neyin nerede oluştuğu pırıl pırıl. Küçük bir not ama büyük bir rahatlık.
Uçtan Uca Küçük Bir Demo Akışı
Toparlayalım: Collector çalışıyor, Jaeger ve Tempo ayakta. Laravel’de OTel aktif; Node’da tracing.js ayağa kalkıyor. Kullanıcı /checkout’a bastığında Laravel bir trace başlatıyor, veritabanına uğruyor, Node’a HTTP çağrısı yapıyor. Geri dönüşle birlikte ödeme sonuçlanıyor. Jaeger UI’da “laravel-api” hizmetini seçip, son 15 dakikadaki en uzun izleri listeliyorsunuz. Birini açınca alt alta span’leri görüyorsunuz: “HTTP GET /checkout”, “DB query users”, “HTTP Client → node-worker /compute”, “node-worker external API call” gibi. En uzun olan span’i açıp notlara bakıyorsunuz; belki “rate_limited=true” diye ufak bir etiket koymuşsunuz. Gizem çözülüyor.
Bu akışı gerçek bir dünyaya bağlamak isterseniz, performans tarafında Nginx mikro önbellek bir ilaçken, izler size nerede doz aşımı yaptığınızı gösterir. Detayları zaten mikro önbellekleme rehberinde anlatmıştık. Yanına merkezi loglamayı ve hafif alarmları eklerseniz, çember tamamlanır.
Kapanış: Yükü Akılda Değil, İzlerde Taşımak
Bir sorunun peşine iz olmadan düşmek, karanlık odada anahtar aramak gibi. OpenTelemetry, Laravel ve Node.js gibi farklı dillerde yazılmış servisleri aynı hikâyede buluşturuyor. Jaeger veya Tempo’ya iz akıttığınızda, “Nerede yavaşladık? Neyi yanlış bekliyoruz? Hangi API bizi oyalıyor?” sorularına veriyle cevap veriyorsunuz. Bir kez kurunca, sonraki yolculuklarda çantada hazır bir pusula gibi duruyor.
Pratik önerilerimi özetleyeyim. Başlarken her şeyi izlemeye çalışmayın; akışın omurgasını yakalayın. Anlamlı etiketler koyun ama gizlilikten şaşmayın. Collector’ı merkez alın; yükü ve yönlendirmeyi o yapsın. Deploy süreçlerini yumuşatın, versiyon etiketleri ekleyin. Loglarla izleri eşitleyin; sorunlara tek pencereden bakmak inanılmaz hız kazandırıyor. Eğer bu konuları genişletmek isterseniz, log dünyası için Loki + Promtail rehberini ve performans için mikro önbellek notlarını favorilerinize ekleyin. Umalım ki sorunlar azalsın; ama olduğunda da izler yanınızda olsun.
Umarım bu yazı size faydalı olmuştur. Sorularınız olursa çekinmeden yazın, birlikte bakalım. Bir dahaki yazıda yine sahadan, yine sıcacık bir konuyla buluşuruz.
