Gözlemlenebilirliğe gerçekten ihtiyaç duyduğunuz ilk an, sakin bir şekilde kontrol paneline baktığınız zamanlar değildir. Bir kullanıcı "ödeme yavaş" yazdığında, hata grafiği normal görünüyor ve günlüklerde yalnızca bir dizi bağlantısız mesaj buluyorsunuz.
OpenTelemetry o anı önlemek için yaratıldı: daha fazla grafiğe sahip olmak için değil, parçaları birleştirmek için. Bir istek API'e girer, bir veritabanını çağırır, harici bir sağlayıcıdan geçer, sıraya alınmış bir işi yayınlar ve belki daha sonra üç hizmette başarısız olur. Dağıtılmış izleme olmadan bu hikayeyi elle yeniden oluşturursunuz. OpenTelemetry ile en azından bir haritanız var.
Önemli olan trace değil, hikaye
Bir trace, span dizisidir. Böyle söylersek kulağa soğuk geliyor. Pratikte her span hikayenin bir parçasıdır: POST /checkout, SELECT inventory, call payment provider, publish order.created.
Değer, gerçek soruları yanıtlamaya başladığınızda ortaya çıkar:
- hangi harici hizmet yavaşlıyor?
- hatalar belirli bir sürümden mi kaynaklanıyor?
- sorun herkesi mi etkiliyor, yoksa yalnızca bir kiracıyı mı?
- yeniden deneme bir zaman aşımını mı gizliyor?
- asenkron iş başlıyor ama sonra başka bir yerde mi ölüyor?
Bu sorular aceleyle atılan bir console.log ile çözülemez. Aslında, acil bir durumda eklenen kütük genellikle bugün size yardımcı olur ve yarın gürültüye dönüşür.
Bunu bir uygulamaya nasıl koyarım Node.js
En sağlıklı kurulum basittir: Uygulama telemetri üretir, Collector bunun nereye gönderileceğine karar verir.
Node.js app -> OpenTelemetry Collector -> backend di observability
Neden doğrudan satıcıya ihracat yapmıyorsunuz? İlk başta daha hızlı göründüğü için, daha sonra her hizmetin farklı yapılandırmalara, farklı yeniden denemelere, farklı filtrelere sahip olduğunu ve hassas verileri kaldıracak veya hedefi değiştirecek merkezi bir noktaya sahip olmadığını fark edersiniz.
Collector her bakımdan sıkıcıdır. OTLP alır, toplu işlem yapar, filtreleyebilir, örnekleme yapabilir, ortak özellikler ekleyebilir ve birden fazla sisteme aktarım yapabilir.
Kişisel enstrümantasyon: iyi ama yeterli değil
Node.js'da otomatik enstrümantasyonla başlayacaktım. Size HTTP'ye, desteklenen çerçevelere, veritabanlarına ve ortak kitaplıklara anında görünürlük sağlar.
npm install @opentelemetry/sdk-node \ @opentelemetry/auto-instrumentations-node \ @opentelemetry/exporter-trace-otlp-http
Daha sonra uygulamanın geri kalanından önce SDK'yi başlatırsınız:
import { NodeSDK } from '@opentelemetry/sdk-node'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; const sdk = new NodeSDK({ traceExporter: new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, }), instrumentations: [getNodeAutoInstrumentations()], }); sdk.start();
Ancak bu, ürününüzü değil çerçeveyi görür. Bir sorgu yaptığınızı biliyor ancak sorgunun "sipariş oluştur" veya "aboneliği yenile" konumunda olduğunu bilmiyor. Bunun için hakimiyetin önemli olduğu noktalarda span kılavuzlara ihtiyacınız var.
const span = tracer.startSpan('checkout.create_order'); try { span.setAttribute('cart.items_count', input.items.length); const order = await createOrder(input); span.setAttribute('order.id', order.id); return order; } catch (error) { span.recordException(error as Error); throw error; } finally { span.end(); }
span kılavuzlarını hiçbir yere koymam. Onları sabahın üçte kod tabanının yarısını okumadan ne olduğunu anlamak istediğim yere koyardım.
Çok fazla kaosu önleyen üç kural
İlk kural: her hizmetin service.name, ortamı ve sürümü olmalıdır. Önemsiz görünüyor, ancak bu özellikler olmadan trace çok daha az kullanışlıdır. Bir dağıtım bir şeyi bozduğunda iki saniye içinde sürüme göre filtrelemek istersiniz.
İkinci kural: Niteliklere hassas veriler koymayın. E-postalar, belirteçler, tamsayı verileri ve adresler kazara gözlemlenebilirlik arka ucuna düşmemelidir. Bir kullanıcıyı tanımlamanız gerekiyorsa dahili kimlikleri, karmaları veya daha az hassas alanları göz önünde bulundurun.
Üçüncü kural: kardinaliteye dikkat edin. user.id, trace'nin bir özelliği olarak anlamlı olabilir. Bir metrik etiket olarak maliyetlerinizi ve performansınızı yok edebilir.
Metrikler: az ama iyi
Çok pratik ölçümlerle başlayacağım:
- taleplerin oranları, hataları ve süreleri;
- dış bağımlılıkların gecikmesi;
- zaman aşımı ve yeniden deneme sayısı;
- kuyrukların derinliği;
- iş süresi;
- sürüm başına hata yüzdesi.
Gerisi ihtiyaç duyulduğunda eklenir. Kimsenin bakmadığı grafiklerle dolu kontrol panelleri gözlemlenebilirlik değil mobilyadır.
Günlükler: Hala kullanışlı ancak bağlantılı
Günlükler kaybolmaz. trace_id ve span_id taşıdıklarında çok daha kullanışlı hale gelirler. Böylece bir hata günlüğünden başlayıp trace'yi açabilir veya yavaş trace'den başlayıp yalnızca o yolda üretilen günlükleri okuyabilirsiniz.
Korelasyon olmadan iğne arıyorsunuz. Korelasyonla en azından hangi çekmeceye bakmanız gerektiğini bilirsiniz.
"Kapsamdayız" demeden önce kullanacağım kontrol listesi
- trace aslında birden fazla hizmeti geçiyor.
- Günlükler
trace_idvespan_id'yi içerir. - Collector toplu işlem ve bellek limitleriyle yapılandırılmıştır.
- Hatalar span'ye kaydedilir.
- Bir numune alma politikası vardır.
- Metrikler kontrollü kardinaliteye sahiptir.
- Hassas veriler filtrelenir.
- Uyarılar rastgele grafiklerden değil, kullanıcı belirtilerinden başlar.
Sonuç
OpenTelemetryTek başına üretim sorunlarını çözmez. Ancak onlarla başa çıkma şekliniz değişir. Günlükleri körü körüne eklemek yerine, bir isteğin gerçek yolunu izlemeye başlarsınız.
Benim için bunun işe yaradığının işareti basit: Bir şey olduğunda ekip "nereye bakıyoruz?" diye sormayı bırakıyor. ve "bu parça neden yavaş?" diye sormaya başlıyor. Gözlemlenebilirliğin bir gösterge tablosu koleksiyonu değil, bir araç haline geldiği yer burasıdır.