{"id":1631,"date":"2025-11-10T19:30:31","date_gmt":"2025-11-10T16:30:31","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/opentelemetry-ile-izlenebilirlik-laravel-ve-node-jste-jaeger-tempoya-uctan-uca-izler-nasil-kurulur\/"},"modified":"2025-11-10T19:30:31","modified_gmt":"2025-11-10T16:30:31","slug":"opentelemetry-ile-izlenebilirlik-laravel-ve-node-jste-jaeger-tempoya-uctan-uca-izler-nasil-kurulur","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/opentelemetry-ile-izlenebilirlik-laravel-ve-node-jste-jaeger-tempoya-uctan-uca-izler-nasil-kurulur\/","title":{"rendered":"OpenTelemetry ile \u0130zlenebilirlik: Laravel ve Node.js\u2019te Jaeger\/Tempo\u2019ya U\u00e7tan Uca \u0130zler Nas\u0131l Kurulur?"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#Ofiste_Bir_Sorunun_Izini_Surmek_Neden_Izlenebilirlik\"><span class=\"toc_number toc_depth_1\">1<\/span> Ofiste Bir Sorunun \u0130zini S\u00fcrmek: Neden \u0130zlenebilirlik?<\/a><\/li><li><a href=\"#OpenTelemetryyi_Kafada_Netlestirmek_Neyi_Nereye_Nasil_Gonderiyoruz\"><span class=\"toc_number toc_depth_1\">2<\/span> OpenTelemetry\u2019yi Kafada Netle\u015ftirmek: Neyi, Nereye, Nas\u0131l G\u00f6nderiyoruz?<\/a><\/li><li><a href=\"#Kucuk_Bir_Mimari_Laravel_Nodejs_ve_Aradaki_Bag\"><span class=\"toc_number toc_depth_1\">3<\/span> K\u00fc\u00e7\u00fck Bir Mimari: Laravel, Node.js ve Aradaki Ba\u011f<\/a><\/li><li><a href=\"#Jaeger_ve_Tempoyu_Hizlica_Ayaga_Kaldiralim_Collector_ile\"><span class=\"toc_number toc_depth_1\">4<\/span> Jaeger ve Tempo\u2019yu H\u0131zl\u0131ca Aya\u011fa Kald\u0131ral\u0131m (Collector ile)<\/a><\/li><li><a href=\"#Laravel_Tarafi_OTeli_Tak_Baglami_Yay_Izleri_Kolektore_Birak\"><span class=\"toc_number toc_depth_1\">5<\/span> Laravel Taraf\u0131: OTel\u2019i Tak, Ba\u011flam\u0131 Yay, \u0130zleri Kolekt\u00f6re B\u0131rak<\/a><\/li><li><a href=\"#Nodejs_Tarafi_SDK_Otomatik_Enstrumantasyon_ve_Bir_Tutam_Log_Eslestirme\"><span class=\"toc_number toc_depth_1\">6<\/span> Node.js Taraf\u0131: SDK, Otomatik Enstr\u00fcmantasyon ve Bir Tutam Log E\u015fle\u015ftirme<\/a><\/li><li><a href=\"#Laravel_Node_Baglami_Ucurmak_Izi_Tek_Parca_Gormek\"><span class=\"toc_number toc_depth_1\">7<\/span> Laravel \u2192 Node: Ba\u011flam\u0131 U\u00e7urmak, \u0130zi Tek Par\u00e7a G\u00f6rmek<\/a><\/li><li><a href=\"#Ornek_Senaryo_700_mslik_Kayip_Nerede\"><span class=\"toc_number toc_depth_1\">8<\/span> \u00d6rnek Senaryo: 700 ms\u2019lik Kay\u0131p Nerede?<\/a><\/li><li><a href=\"#Sampling_Gizlilik_ve_Uretimde_Sakin_Kalan_Bir_Iz_Akisi\"><span class=\"toc_number toc_depth_1\">9<\/span> Sampling, Gizlilik ve \u00dcretimde Sakin Kalan Bir \u0130z Ak\u0131\u015f\u0131<\/a><\/li><li><a href=\"#Grafana_Jaeger_ve_Gunluk_Yasam_Nereden_Bakmali\"><span class=\"toc_number toc_depth_1\">10<\/span> Grafana, Jaeger ve G\u00fcnl\u00fck Ya\u015fam: Nereden Bakmal\u0131?<\/a><\/li><li><a href=\"#Uretimde_Ufak_Tefek_Taslar_Nginx_Deploy_Versiyonlama\"><span class=\"toc_number toc_depth_1\">11<\/span> \u00dcretimde Ufak Tefek Ta\u015flar: Nginx, Deploy, Versiyonlama<\/a><\/li><li><a href=\"#Uctan_Uca_Kucuk_Bir_Demo_Akisi\"><span class=\"toc_number toc_depth_1\">12<\/span> U\u00e7tan Uca K\u00fc\u00e7\u00fck Bir Demo Ak\u0131\u015f\u0131<\/a><\/li><li><a href=\"#Kapanis_Yuku_Akilda_Degil_Izlerde_Tasimak\"><span class=\"toc_number toc_depth_1\">13<\/span> Kapan\u0131\u015f: Y\u00fck\u00fc Ak\u0131lda De\u011fil, \u0130zlerde Ta\u015f\u0131mak<\/a><\/li><\/ul><\/div>\n<h2 id=\"section-1\"><span id=\"Ofiste_Bir_Sorunun_Izini_Surmek_Neden_Izlenebilirlik\">Ofiste Bir Sorunun \u0130zini S\u00fcrmek: Neden \u0130zlenebilirlik?<\/span><\/h2>\n<p>Hi\u00e7 ba\u015f\u0131n\u0131za geldi mi? Kullan\u0131c\u0131 \u201cSepete ekle \u00e7al\u0131\u015fm\u0131yor\u201d der, panelde her \u015fey ye\u015fildir, loglarda sanki d\u00fcnya g\u00fcll\u00fck g\u00fclistanl\u0131k\u2026 ama ger\u00e7ek d\u00fcnyada biri sinirle sayfay\u0131 yeniliyordur. Benim de bir sabah tam b\u00f6yle oldu. Laravel\u2019le yaz\u0131lm\u0131\u015f API, arkas\u0131nda k\u00fc\u00e7\u00fck bir Node.js servis, \u00fcstte bir Nginx, arkada bir veritaban\u0131 derken zincirde bir halka gecikiyor, ama neresi oldu\u011fu bir t\u00fcrl\u00fc g\u00f6r\u00fcnm\u00fcyordu. O g\u00fcn anlad\u0131m ki, loglar tek ba\u015f\u0131na hik\u00e2yeyi tamamlam\u0131yor; ak\u0131\u015ftaki her ad\u0131m\u0131, u\u00e7tan uca izlemek gerekiyor.<\/p>\n<p>\u0130\u015fte burada <strong>OpenTelemetry<\/strong> devreye giriyor. Uygulamalar aras\u0131nda gezen bir istek, Laravel\u2019den Node\u2019a, oradan veritaban\u0131na nas\u0131l gidiyor, nerede oyalan\u0131yor, kim topu d\u00fc\u015f\u00fcr\u00fcyor, hepsini bir iz olarak g\u00f6rmek m\u00fcmk\u00fcn. Bu yaz\u0131da, PHP\/Laravel ve Node.js servislerinde iz toplamay\u0131 nas\u0131l kurdu\u011fumu, <strong>Jaeger<\/strong> ve <strong>Tempo<\/strong> gibi hedeflere bu izleri nas\u0131l aktard\u0131\u011f\u0131m\u0131 ve yolda \u00f6\u011frendi\u011fim p\u00fcf noktalar\u0131 anlatmak istiyorum. Teknik detay var ama g\u00f6z\u00fcn\u00fcz korkmas\u0131n; bir kahve e\u015fli\u011finde, sohbet eder gibi ilerleyece\u011fiz.<\/p>\n<p>Mesela \u015f\u00f6yle d\u00fc\u015f\u00fcn\u00fcn: \u0130ste\u011finize bir GPS tak\u0131yoruz. O GPS, her u\u011frad\u0131\u011f\u0131 dura\u011f\u0131 not ediyor; s\u00fcreleri, etiketleri, hatta bazen k\u00fc\u00e7\u00fck anekdotlar\u0131. Sonra bu not defterini Jaeger veya Tempo\u2019ya veriyoruz. Orada a\u00e7\u0131p \u201cHangi durakta trafik vard\u0131?\u201d diye bak\u0131yoruz. Basit gibi duruyor ama ilk kurulumda ufak ta\u015flara tak\u0131lmamak i\u00e7in baz\u0131 ipu\u00e7lar\u0131 var; hepsine de\u011finece\u011fim.<\/p>\n<h2 id=\"section-2\"><span id=\"OpenTelemetryyi_Kafada_Netlestirmek_Neyi_Nereye_Nasil_Gonderiyoruz\">OpenTelemetry\u2019yi Kafada Netle\u015ftirmek: Neyi, Nereye, Nas\u0131l G\u00f6nderiyoruz?<\/span><\/h2>\n<p>OpenTelemetry (k\u0131saca OTel), uygulaman\u0131zdan \u00f6l\u00e7\u00fcm, log ve iz toplayan bir \u00e7at\u0131. Bu yaz\u0131n\u0131n kahraman\u0131 izler (traces) olacak. Her istek bir <strong>trace<\/strong>, o trace i\u00e7indeki her ad\u0131m bir <strong>span<\/strong>. Span\u2019lerin \u00fczerine etiketler, s\u00fcreler, durumlar yaz\u0131yoruz. Laravel\u2019de bir controller, Node.js\u2019te bir HTTP \u00e7a\u011fr\u0131s\u0131, Redis sorgusu veya harici API beklemesi\u2026 Hepsi birer k\u00fc\u00e7\u00fck kare gibi d\u00fc\u015f\u00fcn\u00fcn. Kareler yan yana gelince film oluyor.<\/p>\n<p>Bir de \u201cBu filmi nereye izlemeye ta\u015f\u0131yoruz?\u201d k\u0131sm\u0131 var. \u0130ki g\u00fczerg\u00e2h kullanaca\u011f\u0131z: <strong>Jaeger<\/strong> ve <strong>Tempo<\/strong>. Jaeger, izleri g\u00f6rselle\u015ftirmesi kolay bir aray\u00fcz sunuyor. Tempo ise izleri saklamada esnek davran\u0131yor, Grafana ile g\u00fczel bir ikili oluyor. Hatta isterseniz ikisine birden g\u00f6ndermek m\u00fcmk\u00fcn; ben \u00e7o\u011fu zaman arac\u0131 olarak <strong>OpenTelemetry Collector<\/strong> kullan\u0131yorum. Collector\u2019\u0131 bir kav\u015fak gibi d\u00fc\u015f\u00fcn\u00fcn: Uygulamalardan izleri al\u0131r, filtreler, etiketler ve do\u011fru y\u00f6ne yollar.<\/p>\n<p>Bu arada \u201cLoglar ne olacak?\u201d diye akl\u0131n\u0131za gelebilir. \u0130z tek ba\u015f\u0131na g\u00fc\u00e7l\u00fc; ama loglarla yan yana y\u00fcr\u00fcy\u00fcnce tad\u0131ndan yenmiyor. Biz daha \u00f6nce loglar\u0131 nas\u0131l sakinle\u015ftirdi\u011fimizi anlatm\u0131\u015ft\u0131k; isterseniz <a href=\"https:\/\/www.dchost.com\/blog\/merkezi-loglama-ve-gozlemlenebilirlik-vpste-loki-promtail-grafana-ile-sakin-kalan-bir-zihin\/\">VPS\u2019te Loki + Promtail + Grafana ile merkezi loglama<\/a> yaz\u0131s\u0131na da g\u00f6z atabilirsiniz. Bug\u00fcnk\u00fc odak iz, ama log-trace e\u015fle\u015fmesi de b\u00fcy\u00fck rahatl\u0131k.<\/p>\n<h2 id=\"section-3\"><span id=\"Kucuk_Bir_Mimari_Laravel_Nodejs_ve_Aradaki_Bag\">K\u00fc\u00e7\u00fck Bir Mimari: Laravel, Node.js ve Aradaki Ba\u011f<\/span><\/h2>\n<p>Ger\u00e7ek hayatta \u015f\u00f6yle ak\u0131yor: Kullan\u0131c\u0131 bir butona bas\u0131yor, Laravel API iste\u011fi al\u0131yor, bir validasyon yap\u0131yor, sonra arka planda Node.js\u2019te \u00e7al\u0131\u015fan bir servisle konu\u015fuyor. Node bir hesaplama yap\u0131yor veya ba\u015fka bir API\u2019yi yokluyor, sonucu geri veriyor. Laravel de kullan\u0131c\u0131ya \u201cTamamd\u0131r\u201d diyor. Bu yolculukta kimi zaman Nginx\u2019in \u00f6nbelle\u011fi devreye giriyor, kimi zaman veritaban\u0131 bir saniye d\u00fc\u015f\u00fcnmek istiyor. Sorun oldu\u011funda kimin su\u00e7lu oldu\u011fu hissiyatla de\u011fil, veriyle ortaya \u00e7\u0131ks\u0131n istiyoruz.<\/p>\n<p>\u0130zlenebilirlikte kritik k\u0131s\u0131m <strong>ba\u011flam yay\u0131l\u0131m\u0131<\/strong>. Yani, Laravel\u2019de ba\u015flayan trace kimli\u011fini Node.js\u2019e <em>do\u011fru<\/em> \u015fekilde aktarmak gerekiyor. Modern d\u00fcnyada bu i\u015fin ortak dili W3C\u2019nin <strong>traceparent<\/strong> ve <strong>tracestate<\/strong> ba\u015fl\u0131klar\u0131. \u015eansl\u0131y\u0131z; OTel\u2019in varsay\u0131lan\u0131 bu. Siz ekstra bir \u015fey yapmasan\u0131z bile do\u011fru ayarlad\u0131\u011f\u0131n\u0131zda Laravel\u2019den Node\u2019a \u00e7a\u011fr\u0131 yaparken HTTP ba\u015fl\u0131klar\u0131yla bu ba\u011flam ta\u015f\u0131n\u0131yor. B\u00f6ylece Jaeger veya Tempo ekran\u0131nda tek bir iz alt\u0131nda iki servisi de yan yana g\u00f6r\u00fcyorsunuz.<\/p>\n<p>Bazen, \u201cNginx mikro \u00f6nbellek var, izler k\u0131r\u0131l\u0131r m\u0131?\u201d diye soruluyor. Orada da do\u011fru yap\u0131land\u0131r\u0131l\u0131rsa sorun \u00e7\u0131km\u0131yor; \u00f6nbellek beklenmedik gecikmeleri saklayabilir ama izlerin toplam\u0131 zaten size <strong>ger\u00e7ek<\/strong> yolculu\u011fu anlat\u0131yor. Bu konuda performans taraf\u0131na merakl\u0131ysan\u0131z, <a href=\"https:\/\/www.dchost.com\/blog\/nginx-mikro-onbellekleme-ile-php-uygulamalarini-ucurmak-1-5-sn-cache-bypass-ve-purge-ne-zaman-nasil\/\">Nginx mikro \u00f6nbellekleme ile PHP uygulamalar\u0131n\u0131 h\u0131zland\u0131rma<\/a> yaz\u0131s\u0131 akl\u0131n\u0131zda olsun; izler ve \u00f6nbellek birlikte g\u00fczel \u00e7al\u0131\u015f\u0131r.<\/p>\n<h2 id=\"section-4\"><span id=\"Jaeger_ve_Tempoyu_Hizlica_Ayaga_Kaldiralim_Collector_ile\">Jaeger ve Tempo\u2019yu H\u0131zl\u0131ca Aya\u011fa Kald\u0131ral\u0131m (Collector ile)<\/span><\/h2>\n<p>Bir \u015feyleri g\u00f6rmek i\u00e7in \u00f6nce sahneyi kurmak laz\u0131m. A\u015fa\u011f\u0131daki Docker Compose, Collector\u2019\u0131 merkez alarak Jaeger ve Tempo\u2019yu birlikte ko\u015fturur. Lokal denemeler i\u00e7in birebir. Prod\u2019da daha d\u00fczenli hale getirebilirsiniz.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">version: &quot;3.8&quot;\nservices:\n  otel-collector:\n    image: otel\/opentelemetry-collector:latest\n    command: [&quot;--config=\/etc\/otel-collector.yaml&quot;]\n    volumes:\n      - .\/otel-collector.yaml:\/etc\/otel-collector.yaml\n    ports:\n      - &quot;4317:4317&quot;   # OTLP gRPC\n      - &quot;4318:4318&quot;   # OTLP HTTP\n\n  jaeger:\n    image: jaegertracing\/all-in-one:latest\n    ports:\n      - &quot;16686:16686&quot; # Jaeger UI\n      - &quot;14250:14250&quot; # gRPC\n\n  tempo:\n    image: grafana\/tempo:latest\n    command: [&quot;-config.file=\/etc\/tempo.yaml&quot;]\n    volumes:\n      - .\/tempo.yaml:\/etc\/tempo.yaml\n    ports:\n      - &quot;3200:3200&quot;   # Tempo API\n      - &quot;4317:4317&quot;   # OTLP gRPC (opsiyonel)\n\n  grafana:\n    image: grafana\/grafana:latest\n    ports:\n      - &quot;3000:3000&quot;\n<\/code><\/pre>\n<p>Collector\u2019\u0131n ayar dosyas\u0131 izleri hem Jaeger\u2019e hem Tempo\u2019ya g\u00f6nderecek \u015fekilde olsun. Receiver k\u0131sm\u0131 OTLP, exporter k\u0131sm\u0131 iki hedefe birden:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># otel-collector.yaml\nreceivers:\n  otlp:\n    protocols:\n      http: {}\n      grpc: {}\n\nexporters:\n  jaeger:\n    endpoint: jaeger:14250\n    tls:\n      insecure: true\n  otlp\/tempo:\n    endpoint: tempo:4317\n    tls:\n      insecure: true\n\nprocessors:\n  batch: {}\n\nservice:\n  pipelines:\n    traces:\n      receivers: [otlp]\n      processors: [batch]\n      exporters: [jaeger, otlp\/tempo]\n<\/code><\/pre>\n<p>Tempo i\u00e7in basit bir config yeterli olur. Grafana\u2019dan ekleyip izleri g\u00f6r\u00fcnt\u00fcleyebilirsiniz. Jaeger i\u00e7in 16686 portundan aray\u00fcze bakmak \u00e7ok pratik. Tempo\u2019yu Grafana \u00fczerinde ke\u015ffetmek isterseniz, Tempo veri kayna\u011f\u0131n\u0131 ekleyip \u201cExplore\u201d ekran\u0131ndan trace arayabilirsiniz. \u0130steyenler detaylar i\u00e7in <a href=\"https:\/\/opentelemetry.io\/docs\/\" rel=\"nofollow noopener\" target=\"_blank\">resmi OpenTelemetry dok\u00fcmantasyonu<\/a>, <a href=\"https:\/\/www.jaegertracing.io\/\" rel=\"nofollow noopener\" target=\"_blank\">Jaeger\u2019in sitesi<\/a> ve <a href=\"https:\/\/grafana.com\/oss\/tempo\/\" rel=\"nofollow noopener\" target=\"_blank\">Grafana Tempo\u2019nun sayfas\u0131<\/a> \u00fczerinden gezinebilir.<\/p>\n<h2 id=\"section-5\"><span id=\"Laravel_Tarafi_OTeli_Tak_Baglami_Yay_Izleri_Kolektore_Birak\">Laravel Taraf\u0131: OTel\u2019i Tak, Ba\u011flam\u0131 Yay, \u0130zleri Kolekt\u00f6re B\u0131rak<\/span><\/h2>\n<p>Laravel\u2019de iki yakla\u015f\u0131m var: Otomatik enstr\u00fcmantasyon ve elle ufak dokunu\u015flar. Otomatik k\u0131s\u0131m, HTTP, veritaban\u0131, queue gibi alanlar\u0131 kendili\u011finden izleyebiliyor. Ba\u015flamak i\u00e7in projenize OTel paketlerini ekleyin ve ortam de\u011fi\u015fkenlerini Collector\u2019a g\u00f6re ayarlay\u0131n. Komutlar kabaca \u015f\u00f6yle:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># composer.json i\u00e7in paketler (\u00f6rnek)\ncomposer require open-telemetry\/opentelemetry open-telemetry\/opentelemetry-transport-otlp\n# Laravel \u00f6zel bir k\u00f6pr\u00fc paketi kullanabilirsiniz (varsa proje ihtiya\u00e7lar\u0131na g\u00f6re)\n<\/code><\/pre>\n<p>Ortam de\u011fi\u015fkenleri en pratik k\u0131s\u0131m. .env dosyan\u0131za \u015fu ayarlar\u0131 b\u0131rak\u0131n:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># .env\nOTEL_SERVICE_NAME=laravel-api\nOTEL_EXPORTER_OTLP_PROTOCOL=http\/protobuf\nOTEL_EXPORTER_OTLP_ENDPOINT=http:\/\/localhost:4318\nOTEL_TRACES_SAMPLER=parentbased_always_on\n<\/code><\/pre>\n<p>Otomatik taraf\u0131 aktive etmek i\u00e7in bir bootstrap dosyas\u0131nda veya bir Service Provider i\u00e7inde tracer\u2019\u0131 ba\u015flatabilirsiniz. Paketlerin sa\u011flad\u0131\u011f\u0131 otomatik kay\u0131tlar varsa onlar\u0131 tercih edin. Elle bir \u00f6rnek g\u00f6rmek iyi olur:<\/p>\n<pre class=\"language-php line-numbers\"><code class=\"language-php\">&lt;?php\n\/\/ app\/Providers\/TelemetryServiceProvider.php\nnamespace AppProviders;\n\nuse IlluminateSupportServiceProvider;\nuse OpenTelemetrySDKTraceTracerProvider;\nuse OpenTelemetrySDKTraceSpanProcessorBatchSpanProcessor;\nuse OpenTelemetrySDKTraceSamplerParentBasedSampler;\nuse OpenTelemetrySDKTraceSamplerAlwaysOnSampler;\nuse OpenTelemetryExporterOTLPTransportFactory;\nuse OpenTelemetryExporterOTLPSpanExporter as OtlpExporter;\n\nclass TelemetryServiceProvider extends ServiceProvider\n{\n    public function register(): void {}\n\n    public function boot(): void\n    {\n        $endpoint = env('OTEL_EXPORTER_OTLP_ENDPOINT', 'http:\/\/localhost:4318');\n        $serviceName = env('OTEL_SERVICE_NAME', 'laravel-api');\n\n        $exporter = new OtlpExporter((new TransportFactory())\n            -&gt;create($endpoint . '\/v1\/traces', 'application\/x-protobuf'));\n\n        $provider = (new TracerProvider(\n            new BatchSpanProcessor($exporter),\n            new ParentBasedSampler(new AlwaysOnSampler())\n        ))-&gt;setResourceAttributes(['service.name' =&gt; $serviceName]);\n\n        \/\/ Uygulama genelinde kullanmak \u00fczere Container\u2019a koymak faydal\u0131\n        $this-&gt;app-&gt;instance(TracerProvider::class, $provider);\n    }\n}\n<\/code><\/pre>\n<p>\u201cTrace kimli\u011fini response\u2019a yazay\u0131m ki loglarla e\u015fle\u015ftireyim\u201d demek \u00e7ok mant\u0131kl\u0131. Bunun i\u00e7in k\u00fc\u00e7\u00fck bir middleware i\u015finizi g\u00f6r\u00fcr. \u0130zlemenin a\u00e7\u0131k olup olmad\u0131\u011f\u0131n\u0131 da umursamaz, mevcutsa al\u0131r:<\/p>\n<pre class=\"language-php line-numbers\"><code class=\"language-php\">&lt;?php\n\/\/ app\/Http\/Middleware\/TraceHeaders.php\nnamespace AppHttpMiddleware;\n\nuse Closure;\nuse OpenTelemetryAPITraceSpan;\n\nclass TraceHeaders\n{\n    public function handle($request, Closure $next)\n    {\n        $response = $next($request);\n        $span = Span::getCurrent();\n        $ctx = $span-&gt;getContext();\n        if ($ctx &amp;&amp; $ctx-&gt;isValid()) {\n            $response-&gt;headers-&gt;set('x-trace-id', $ctx-&gt;getTraceId());\n            $response-&gt;headers-&gt;set('x-span-id', $ctx-&gt;getSpanId());\n        }\n        return $response;\n    }\n}\n<\/code><\/pre>\n<p>Laravel\u2019den Node\u2019a HTTP \u00e7a\u011fr\u0131s\u0131 yaparken, OTel ba\u011flam\u0131 otomatik ta\u015f\u0131mak i\u00e7in \u00e7o\u011fu HTTP istemcisi haz\u0131r. Gerekirse manuel de ekleyebilirsiniz. Basit\u00e7e \u201ctraceparent\u201d ba\u015fl\u0131\u011f\u0131n\u0131 propagate etmek yeter: mevcut ba\u011flamdan al\u0131n, iste\u011fe ekleyin. Otomatik enstr\u00fcmantasyon bunu genelde sizin yerinize yapar; yine de kontrol etmeyi seviyorum. Bu arada canl\u0131ya al\u0131rken panik ya\u015famamak i\u00e7in s\u00fcre\u00e7leri ad\u0131m ad\u0131m kurmak laz\u0131m; bu konuda <a href=\"https:\/\/www.dchost.com\/blog\/node-jsi-canliya-alirken-panik-yapma-pm2-systemd-nginx-ssl-ve-sifir-kesinti-deploy-nasil-kurulur\/\">Node.js\u2019i canl\u0131ya al\u0131rken dikkat edilecekler<\/a> yaz\u0131s\u0131ndaki deploy rit\u00fcelleri izlerin s\u00fcreklili\u011fini korumaya da yard\u0131mc\u0131 oluyor.<\/p>\n<h2 id=\"section-6\"><span id=\"Nodejs_Tarafi_SDK_Otomatik_Enstrumantasyon_ve_Bir_Tutam_Log_Eslestirme\">Node.js Taraf\u0131: SDK, Otomatik Enstr\u00fcmantasyon ve Bir Tutam Log E\u015fle\u015ftirme<\/span><\/h2>\n<p>Node d\u00fcnyas\u0131nda ayaklar\u0131m\u0131z yere sa\u011flam bas\u0131yor. @opentelemetry\/sdk-node ve otomatik enstr\u00fcmantasyon paketi \u00e7o\u011fu i\u015fi hallediyor. Kurulumda bir \u201ctracing.js\u201d dosyas\u0131 olu\u015fturarak uygulamadan \u00f6nce OTel\u2019i aya\u011fa kald\u0131ral\u0131m:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/\/ package.json (ilgili paketler)\n\/\/ npm i @opentelemetry\/sdk-node @opentelemetry\/auto-instrumentations-node @opentelemetry\/exporter-trace-otlp-http @opentelemetry\/api\n<\/code><\/pre>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/\/ tracing.js\n'use strict';\nconst { NodeSDK } = require('@opentelemetry\/sdk-node');\nconst { getNodeAutoInstrumentations } = require('@opentelemetry\/auto-instrumentations-node');\nconst { OTLPTraceExporter } = require('@opentelemetry\/exporter-trace-otlp-http');\nconst { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry\/api');\n\n\/\/ \u0130sterseniz debug a\u00e7\u0131n\n\/\/ diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);\n\nconst exporter = new OTLPTraceExporter({\n  url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT ? `${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}\/v1\/traces` : 'http:\/\/localhost:4318\/v1\/traces'\n});\n\nconst sdk = new NodeSDK({\n  traceExporter: exporter,\n  serviceName: process.env.OTEL_SERVICE_NAME || 'node-worker',\n  instrumentations: [getNodeAutoInstrumentations()]\n});\n\nsdk.start().then(() =&gt; {\n  console.log('OTel tracing started');\n}).catch((err) =&gt; {\n  console.error('OTel init error', err);\n});\n<\/code><\/pre>\n<p>Sunucu kodunda tek yapman\u0131z gereken, uygulamay\u0131 ba\u015flatmadan \u00f6nce bu dosyay\u0131 import etmek. Express kulland\u0131\u011f\u0131n\u0131z\u0131 varsayal\u0131m:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/\/ index.js\nrequire('.\/tracing');\nconst express = require('express');\nconst fetch = require('node-fetch');\n\nconst app = express();\n\napp.get('\/compute', async (req, res) =&gt; {\n  \/\/ Burada ba\u015fka bir API'ye istek de yapabilirsiniz, otomatik enstr\u00fcmantasyon HTTP \u00e7a\u011fr\u0131s\u0131n\u0131 span olarak kaydeder\n  res.json({ ok: true });\n});\n\napp.listen(3001, () =&gt; console.log('Node worker 3001')); \n<\/code><\/pre>\n<p>Log-trace e\u015fle\u015fmesi i\u00e7in k\u00fc\u00e7\u00fck bir dokunu\u015f daha yapal\u0131m. Winston veya Pino fark etmez; \u00f6nemli olan ge\u00e7erli ba\u011flamdan trace id\u2019yi \u00e7ekmek. K\u00fc\u00e7\u00fck bir yard\u0131mc\u0131 yazal\u0131m:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/\/ trace-log.js\nconst { context, trace } = require('@opentelemetry\/api');\n\nfunction traceIds() {\n  const span = trace.getSpan(context.active());\n  const ctx = span &amp;&amp; span.spanContext ? span.spanContext() : null;\n  return ctx ? { trace_id: ctx.traceId, span_id: ctx.spanId } : {};\n}\n\nmodule.exports = { traceIds };\n<\/code><\/pre>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/\/ logger.js (winston \u00f6rne\u011fi)\nconst { createLogger, format, transports } = require('winston');\nconst { traceIds } = require('.\/trace-log');\n\nconst logger = createLogger({\n  level: 'info',\n  format: format.combine(\n    format.timestamp(),\n    format.printf((info) =&gt; {\n      const ids = traceIds();\n      return `${info.timestamp} level=${info.level} ${Object.entries(ids).map(([k,v])=&gt;`${k}=${v}`).join(' ')} msg=&quot;${info.message}&quot;`;\n    })\n  ),\n  transports: [new transports.Console()]\n});\n\nmodule.exports = logger;\n<\/code><\/pre>\n<p>Bu sayede, Grafana Loki gibi bir sistemde loglar\u0131 toplad\u0131\u011f\u0131n\u0131zda, Jaeger\/Tempo\u2019daki izlerle h\u0131zl\u0131ca e\u015fle\u015ftirirsiniz. O g\u00fcn ya\u015fad\u0131\u011f\u0131m sorunda tam da bunu yapt\u0131m; Laravel request id\u2019siyle Node taraf\u0131ndaki gecikmeyi yan yana koyunca zincir bir anda netle\u015fti.<\/p>\n<h2 id=\"section-7\"><span id=\"Laravel_Node_Baglami_Ucurmak_Izi_Tek_Parca_Gormek\">Laravel \u2192 Node: Ba\u011flam\u0131 U\u00e7urmak, \u0130zi Tek Par\u00e7a G\u00f6rmek<\/span><\/h2>\n<p>Mesela \u015f\u00f6yle d\u00fc\u015f\u00fcn\u00fcn: Laravel\u2019de \/checkout \u00e7a\u011fr\u0131s\u0131 geldi, arka tarafta Node\u2019daki \/compute tetiklendi. \u0130ki \u00e7a\u011fr\u0131y\u0131 tek bir iz alt\u0131nda g\u00f6rmek istiyoruz. Otomatik enstr\u00fcmantasyon \u00e7o\u011fu zaman traceparent ba\u015fl\u0131\u011f\u0131n\u0131 set eder. Ama g\u00f6z\u00fcn\u00fcz arkada kalmas\u0131n diye isterseniz manuel bir \u00f6rnek:<\/p>\n<pre class=\"language-php line-numbers\"><code class=\"language-php\">&lt;?php\n\/\/ Laravel taraf\u0131nda Guzzle ile istek atarken\nuse GuzzleHttpClient;\nuse OpenTelemetryAPITracePropagationTraceContextPropagator;\nuse OpenTelemetryContextContext;\n\n$client = new Client();\n$headers = [];\nTraceContextPropagator::getInstance()-&gt;inject(Context::getCurrent(), $headers);\n$response = $client-&gt;get('http:\/\/node:3001\/compute', [ 'headers' =&gt; $headers ]);\n<\/code><\/pre>\n<p>Node\u2019da otomatik enstr\u00fcmantasyon HTTP sunucusunda traceparent\u2019\u0131 okuyup mevcut trace\u2019e ekler. B\u00f6ylece Jaeger ekran\u0131nda tek bir iz, i\u00e7inde Laravel ve Node span\u2019leri. Tempo taraf\u0131nda da ayn\u0131 hik\u00e2ye; Grafana Explore\u2019da trace id\u2019yi aratarak t\u00fcm ak\u0131\u015f\u0131 a\u00e7ars\u0131n\u0131z.<\/p>\n<p>Bu ak\u0131\u015flar canl\u0131dayken de\u011fi\u015febilir. Deploy s\u0131ras\u0131nda ge\u00e7ici bir kar\u0131\u015f\u0131kl\u0131k olmas\u0131n diye ba\u015ftan birka\u00e7 kural koymak iyi oluyor. Blue\/Green veya s\u0131f\u0131r kesinti d\u00fczeni kurduysan\u0131z, izler de kesintisiz akar. Bu konuda veri taban\u0131 \u015fema de\u011fi\u015fikliklerini g\u00fcvenle yapmak i\u00e7in yazd\u0131\u011f\u0131m\u0131z <a href=\"https:\/\/www.dchost.com\/blog\/mysqlde-sifir-kesinti-sema-degisiklikleri-gh-ost-ve-pt-online-schema-change-ile-blue-green-nasil-kurulur\/\">s\u0131f\u0131r kesinti \u015fema de\u011fi\u015fiklikleri<\/a> yaz\u0131s\u0131ndaki yakla\u015f\u0131m, servis da\u011f\u0131t\u0131mlar\u0131nda da rahat ettirir.<\/p>\n<h2 id=\"section-8\"><span id=\"Ornek_Senaryo_700_mslik_Kayip_Nerede\">\u00d6rnek Senaryo: 700 ms\u2019lik Kay\u0131p Nerede?<\/span><\/h2>\n<p>Bir ak\u015fam \u00fcst\u00fc, checkout s\u00fcresi arada s\u0131rada 2-3 saniyeye vuruyor. Loglar sakin; CPU normal, bellek yerinde. \u0130zleri a\u00e7t\u0131m. Laravel controller 120 ms, veritaban\u0131 40 ms. Sonra bir HTTP client call var, Node\u2019a gidiyor. Node taraf\u0131 80 ms gibi duruyor ama orada bir d\u0131\u015f API \u00e7a\u011fr\u0131s\u0131 da var. O span 700 ms. Me\u011fer o harici API, belirli parametrelerde throttling uyguluyormu\u015f. O ana kadar sezgisel tahminlerle dolan\u0131rken, iz ekranda tam olarak parma\u011f\u0131 do\u011fru noktaya g\u00f6t\u00fcrd\u00fc. Sonras\u0131 kolayd\u0131; parametreleri sadele\u015ftirdik ve kuyru\u011fa alarak pik saatlerde hafiflettik.<\/p>\n<p>Burada \u00f6\u011frendi\u011fim bir \u015fey daha oldu: \u0130zlerde <strong>anlaml\u0131 etiketler<\/strong> \u00e7ok i\u015f g\u00f6r\u00fcyor. \u00d6rne\u011fin \u201ccheckout.step=payment_request\u201d gibi bir alan, veya \u201cuser.plan=premium\u201d bilgisi, tablo gibi a\u011f\u0131r durmadan, okuyan\u0131n g\u00f6z\u00fcn\u00fc yormadan fikir veriyor. Dikkat edilmesi gereken tek \u015fey gizlilik. Ki\u015fisel veriyi veya kart bilgilerini izlere koymay\u0131n. Gerekirse maskeyle veya sadece tip bilgisini yaz\u0131n.<\/p>\n<h2 id=\"section-9\"><span id=\"Sampling_Gizlilik_ve_Uretimde_Sakin_Kalan_Bir_Iz_Akisi\">Sampling, Gizlilik ve \u00dcretimde Sakin Kalan Bir \u0130z Ak\u0131\u015f\u0131<\/span><\/h2>\n<p>Gelelim \u00fcretimde en \u00e7ok sorulan soruya: \u201cHepsini mi \u00f6rnekleyelim?\u201d Cevap genelde hay\u0131r. \u0130lk a\u015famada \u201cparentbased_always_on\u201d ile ba\u015flamak g\u00fczel; zincirin tutarl\u0131 kalmas\u0131n\u0131 sa\u011flar. Sonra trafi\u011finiz artt\u0131k\u00e7a \u201ctraceidratio\u201d gibi bir oranla ayarlars\u0131n\u0131z. \u00d6nemli aksiyonlar i\u00e7in oran\u0131 art\u0131rabilir, arka plan i\u015fleri i\u00e7in d\u00fc\u015f\u00fcrebilirsiniz. Hatta hata durumlar\u0131nda \u201ctail\u201d odakl\u0131 yakla\u015f\u0131mlar da var; ama ilk ad\u0131mda bunu d\u00fc\u015f\u00fcnmek \u015fart de\u011fil.<\/p>\n<p>Gizlilik taraf\u0131nda basit bir kural koyun: \u201c\u0130ze sadece te\u015fhis i\u00e7in gerekli bilgiyi yaz.\u201d Parametrelerin ham halini de\u011fil, t\u00fcr\u00fcn\u00fc veya uzunlu\u011funu yazmak \u00e7o\u011fu zaman yeter. Kullan\u0131c\u0131 kimli\u011fini tamamen koymak yerine anonim bir referans kullan\u0131n. B\u00f6ylece izler, g\u00fcn\u00fcn sonunda bir g\u00fcvenlik riski olu\u015fturmadan i\u015finizi g\u00f6r\u00fcr.<\/p>\n<p>\u0130\u015fletim taraf\u0131 da \u00f6nemli. Collector, g\u00f6nderen uygulamalardan y\u00fck\u00fc al\u0131r; k\u0131sa kuyruklar ve toplu g\u00f6nderimle performans\u0131 korur. Uygulaman\u0131n kritik aksiyonlar\u0131nda iz ba\u015flat\u0131rken abart\u0131ya ka\u00e7may\u0131n; bir controller\u2019a bir span, alt\u0131ndaki belirgin harici \u00e7a\u011fr\u0131lara birer span \u00e7o\u011fu zaman yeter. Yar\u0131n bir g\u00fcn daha derine inmek isterseniz zaten ekleyebilirsiniz. \u0130zlenebilirlik bir defal\u0131k i\u015f de\u011fil; yava\u015f yava\u015f olgunla\u015fan bir kas gibi.<\/p>\n<h2 id=\"section-10\"><span id=\"Grafana_Jaeger_ve_Gunluk_Yasam_Nereden_Bakmali\">Grafana, Jaeger ve G\u00fcnl\u00fck Ya\u015fam: Nereden Bakmal\u0131?<\/span><\/h2>\n<p>Jaeger, \u201cHadi a\u00e7\u0131p bakal\u0131m bu izde ne var\u201d dedi\u011finiz anda h\u0131zl\u0131ca cevap veriyor. Hizmet ad\u0131, endpoint, s\u00fcre filtreleri\u2026 Birka\u00e7 t\u0131kla en uzun s\u00fcren izleri masaya yat\u0131r\u0131rs\u0131n\u0131z. Tempo taraf\u0131nda ise Grafana\u2019n\u0131n Explore ekran\u0131, izlerle metrikleri ayn\u0131 pencerede d\u00fc\u015f\u00fcnmeye g\u00fczel bir ortam yarat\u0131yor. Mesela CPU grafi\u011finde bir tepe g\u00f6rd\u00fcn\u00fcz, ayn\u0131 zaman aral\u0131\u011f\u0131nda birka\u00e7 iz a\u00e7t\u0131n\u0131z, ortak payday\u0131 h\u0131zl\u0131 buldunuz. \u0130zlerin dibine inmek istedi\u011finizde \u201cspan logs\u201d veya \u201cevents\u201d alanlar\u0131na k\u00fc\u00e7\u00fck notlar d\u00fc\u015fmek i\u015fe yarar.<\/p>\n<p>Loglar demi\u015fken, iz ve log birlikte ak\u0131nca i\u015f ne kadar kolayla\u015f\u0131yor fark ediliyor. Loglar\u0131 zaten toplay\u0131p bir yerde tutmak istiyorsan\u0131z, <a href=\"https:\/\/www.dchost.com\/blog\/vps-log-yonetimi-nasil-rayina-oturur-grafana-loki-promtail-ile-merkezi-loglama-tutma-sureleri-ve-alarm-kurallari\/\">Loki + Promtail ile log y\u00f6netimi<\/a> yaz\u0131s\u0131ndaki tutma s\u00fcreleri ve alarm pratikleri iz ekran\u0131nda g\u00f6rd\u00fc\u011f\u00fcn\u00fcz sorunlar\u0131 teyit etmenize yard\u0131mc\u0131 olur. Ben g\u00fcnl\u00fck hayatta izden ipucunu al\u0131p, logla teyit etmeyi seviyorum. Bir de k\u00fc\u00e7\u00fck alarmlar kurunca gecikmeler b\u00fcy\u00fcmeden sizi d\u00fcrter.<\/p>\n<h2 id=\"section-11\"><span id=\"Uretimde_Ufak_Tefek_Taslar_Nginx_Deploy_Versiyonlama\">\u00dcretimde Ufak Tefek Ta\u015flar: Nginx, Deploy, Versiyonlama<\/span><\/h2>\n<p>Ger\u00e7ekte her \u015fey tertemiz i\u015flemiyor. Nginx\u2019te proxy ayarlar\u0131, zaman a\u015f\u0131m\u0131 limitleri, keep-alive davran\u0131\u015f\u0131 gibi ince ayarlar izleri oldu\u011fu gibi etkiler. \u0130zlerin \u201cnetwork\u201d k\u0131sm\u0131nda minik t\u0131rt\u0131klar g\u00f6r\u00fcrseniz akl\u0131n\u0131za ilk bunlar gelsin. Ayr\u0131ca deploy s\u0131ras\u0131nda Node veya PHP s\u00fcre\u00e7leri yeniden ba\u015flarken k\u0131sa s\u00fcreli kopmalar olabilir; izde bo\u015fluklar g\u00f6r\u00fcrs\u00fcn\u00fcz. Bu y\u00fczden da\u011f\u0131t\u0131mda s\u00fcreci yumu\u015fatmak \u00f6nemli. Canl\u0131ya al\u0131rken panik yapmamak i\u00e7in payla\u015ft\u0131\u011f\u0131m\u0131z <a href=\"https:\/\/www.dchost.com\/blog\/node-jsi-canliya-alirken-panik-yapma-pm2-systemd-nginx-ssl-ve-sifir-kesinti-deploy-nasil-kurulur\/\">s\u0131f\u0131r kesinti deploy notlar\u0131<\/a> bu noktada \u00e7ok de\u011ferli.<\/p>\n<p>Bir de versiyon bilgisi eklemek harika bir al\u0131\u015fkanl\u0131k. Hem Laravel hem Node i\u00e7in \u201cservice.version\u201d gibi bir resource etiketi koydu\u011funuzda, bir izdeki sorunun hangi s\u00fcr\u00fcme ait oldu\u011funu tek bak\u0131\u015fta g\u00f6r\u00fcrs\u00fcn\u00fcz. Rollback sonras\u0131 izler kar\u0131\u015fm\u0131yor, neyin nerede olu\u015ftu\u011fu p\u0131r\u0131l p\u0131r\u0131l. K\u00fc\u00e7\u00fck bir not ama b\u00fcy\u00fck bir rahatl\u0131k.<\/p>\n<h2 id=\"section-12\"><span id=\"Uctan_Uca_Kucuk_Bir_Demo_Akisi\">U\u00e7tan Uca K\u00fc\u00e7\u00fck Bir Demo Ak\u0131\u015f\u0131<\/span><\/h2>\n<p>Toparlayal\u0131m: Collector \u00e7al\u0131\u015f\u0131yor, Jaeger ve Tempo ayakta. Laravel\u2019de OTel aktif; Node\u2019da tracing.js aya\u011fa kalk\u0131yor. Kullan\u0131c\u0131 \/checkout\u2019a bast\u0131\u011f\u0131nda Laravel bir trace ba\u015flat\u0131yor, veritaban\u0131na u\u011fruyor, Node\u2019a HTTP \u00e7a\u011fr\u0131s\u0131 yap\u0131yor. Geri d\u00f6n\u00fc\u015fle birlikte \u00f6deme sonu\u00e7lan\u0131yor. Jaeger UI\u2019da \u201claravel-api\u201d hizmetini se\u00e7ip, son 15 dakikadaki en uzun izleri listeliyorsunuz. Birini a\u00e7\u0131nca alt alta span\u2019leri g\u00f6r\u00fcyorsunuz: \u201cHTTP GET \/checkout\u201d, \u201cDB query users\u201d, \u201cHTTP Client \u2192 node-worker \/compute\u201d, \u201cnode-worker external API call\u201d gibi. En uzun olan span\u2019i a\u00e7\u0131p notlara bak\u0131yorsunuz; belki \u201crate_limited=true\u201d diye ufak bir etiket koymu\u015fsunuz. Gizem \u00e7\u00f6z\u00fcl\u00fcyor.<\/p>\n<p>Bu ak\u0131\u015f\u0131 ger\u00e7ek bir d\u00fcnyaya ba\u011flamak isterseniz, performans taraf\u0131nda Nginx mikro \u00f6nbellek bir ila\u00e7ken, izler size nerede doz a\u015f\u0131m\u0131 yapt\u0131\u011f\u0131n\u0131z\u0131 g\u00f6sterir. Detaylar\u0131 zaten <a href=\"https:\/\/www.dchost.com\/blog\/nginx-mikro-onbellekleme-ile-php-uygulamalarini-ucurmak-1-5-sn-cache-bypass-ve-purge-ne-zaman-nasil\/\">mikro \u00f6nbellekleme rehberinde<\/a> anlatm\u0131\u015ft\u0131k. Yan\u0131na merkezi loglamay\u0131 ve hafif alarmlar\u0131 eklerseniz, \u00e7ember tamamlan\u0131r.<\/p>\n<h2 id=\"section-13\"><span id=\"Kapanis_Yuku_Akilda_Degil_Izlerde_Tasimak\">Kapan\u0131\u015f: Y\u00fck\u00fc Ak\u0131lda De\u011fil, \u0130zlerde Ta\u015f\u0131mak<\/span><\/h2>\n<p>Bir sorunun pe\u015fine iz olmadan d\u00fc\u015fmek, karanl\u0131k odada anahtar aramak gibi. OpenTelemetry, Laravel ve Node.js gibi farkl\u0131 dillerde yaz\u0131lm\u0131\u015f servisleri ayn\u0131 hik\u00e2yede bulu\u015fturuyor. Jaeger veya Tempo\u2019ya iz ak\u0131tt\u0131\u011f\u0131n\u0131zda, \u201cNerede yava\u015flad\u0131k? Neyi yanl\u0131\u015f bekliyoruz? Hangi API bizi oyal\u0131yor?\u201d sorular\u0131na veriyle cevap veriyorsunuz. Bir kez kurunca, sonraki yolculuklarda \u00e7antada haz\u0131r bir pusula gibi duruyor.<\/p>\n<p>Pratik \u00f6nerilerimi \u00f6zetleyeyim. Ba\u015flarken her \u015feyi izlemeye \u00e7al\u0131\u015fmay\u0131n; ak\u0131\u015f\u0131n omurgas\u0131n\u0131 yakalay\u0131n. Anlaml\u0131 etiketler koyun ama gizlilikten \u015fa\u015fmay\u0131n. Collector\u2019\u0131 merkez al\u0131n; y\u00fck\u00fc ve y\u00f6nlendirmeyi o yaps\u0131n. Deploy s\u00fcre\u00e7lerini yumu\u015fat\u0131n, versiyon etiketleri ekleyin. Loglarla izleri e\u015fitleyin; sorunlara tek pencereden bakmak inan\u0131lmaz h\u0131z kazand\u0131r\u0131yor. E\u011fer bu konular\u0131 geni\u015fletmek isterseniz, log d\u00fcnyas\u0131 i\u00e7in <a href=\"https:\/\/www.dchost.com\/blog\/vps-log-yonetimi-nasil-rayina-oturur-grafana-loki-promtail-ile-merkezi-loglama-tutma-sureleri-ve-alarm-kurallari\/\">Loki + Promtail rehberini<\/a> ve performans i\u00e7in <a href=\"https:\/\/www.dchost.com\/blog\/nginx-mikro-onbellekleme-ile-php-uygulamalarini-ucurmak-1-5-sn-cache-bypass-ve-purge-ne-zaman-nasil\/\">mikro \u00f6nbellek notlar\u0131n\u0131<\/a> favorilerinize ekleyin. Umal\u0131m ki sorunlar azals\u0131n; ama oldu\u011funda da izler yan\u0131n\u0131zda olsun.<\/p>\n<p>Umar\u0131m bu yaz\u0131 size faydal\u0131 olmu\u015ftur. Sorular\u0131n\u0131z olursa \u00e7ekinmeden yaz\u0131n, birlikte bakal\u0131m. Bir dahaki yaz\u0131da yine sahadan, yine s\u0131cac\u0131k bir konuyla bulu\u015furuz.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>\u0130&ccedil;indekiler1 Ofiste Bir Sorunun \u0130zini S\u00fcrmek: Neden \u0130zlenebilirlik?2 OpenTelemetry\u2019yi Kafada Netle\u015ftirmek: Neyi, Nereye, Nas\u0131l G\u00f6nderiyoruz?3 K\u00fc\u00e7\u00fck Bir Mimari: Laravel, Node.js ve Aradaki Ba\u011f4 Jaeger ve Tempo\u2019yu H\u0131zl\u0131ca Aya\u011fa Kald\u0131ral\u0131m (Collector ile)5 Laravel Taraf\u0131: OTel\u2019i Tak, Ba\u011flam\u0131 Yay, \u0130zleri Kolekt\u00f6re B\u0131rak6 Node.js Taraf\u0131: SDK, Otomatik Enstr\u00fcmantasyon ve Bir Tutam Log E\u015fle\u015ftirme7 Laravel \u2192 Node: Ba\u011flam\u0131 U\u00e7urmak, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1632,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1631","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1631","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/comments?post=1631"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1631\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media\/1632"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media?parent=1631"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/categories?post=1631"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/tags?post=1631"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}