Bu codelab hakkında
1. Giriş
Son güncelleme tarihi: 15.07.2022
Uygulamanın gözlemlenebilirliği
Gözlemlenebilirlik ve OpenTemetri
Gözlemlenebilirlik, bir sistemin özelliklerini tanımlamak için kullanılan terimdir. Gözlemlenebilirliğe sahip bir sistem, ekiplerin sistemlerinde etkin bir şekilde hata ayıklamasına olanak tanır. Bu bağlamda, gözlemlenebilirliğin üç ayağı; günlükler, metrikler ve izler, sistemin gözlemlenebilirlik elde etmesi için temel araçlardır.
OpenTelemetry, gözlemlenebilirliğin gerektirdiği telemetri verilerinin (günlükler, metrikler ve izler) enstrümantasyonunu ve dışa aktarılmasını hızlandıran bir spesifikasyonlar, kitaplıklar ve aracılar grubudur. OpenTelemetry, CNCF kapsamındaki açık standart ve topluluk odaklı bir projedir. Projenin ve ekosisteminin sağladığı kitaplıklardan yararlanan geliştiriciler, uygulamalarını satıcıdan bağımsız bir şekilde ve birden fazla mimariye karşı enstrümantasyonlarını kullanarak gerçekleştirebilirler.
Gözlemlenebilirliğin üç temel dayanağına ek olarak, sürekli profil çıkarma gözlemlenebilirlik açısından başka bir temel bileşendir ve sektördeki kullanıcı tabanını genişletmektedir. Kaynaklardan biri olan Cloud Profiler, uygulama çağrı yığınlarındaki performans metriklerini ayrıntılı olarak incelemek için kolay bir arayüz sunar.
Bu codelab, serinin 1. bölümüdür ve OpenTelemetry ve Cloud Trace ile mikro hizmetlerdeki dağıtılmış izlerin enstrümantasyonunu ele alır. 2. bölümde, Cloud Profiler ile sürekli profil oluşturma ele alınmaktadır.
Dağıtılmış İz
Günlükler, metrikler ve izler arasında, sistemdeki sürecin belirli bir bölümünün gecikmesini bildiren telemetri telemetridir. Özellikle mikro hizmet çağında, dağıtılmış izleme, genel olarak dağıtılmış sistemdeki gecikme sorunlarını tespit etmek için güçlü bir etmendir.
Dağıtılmış izleri analiz ederken iz verilerini görselleştirme, genel sistem gecikmelerini bir bakışta anlamanın anahtarıdır. Dağıtılmış izlemede, sistem giriş noktasına yapılan tek bir isteği birden çok aralık içeren Trace biçiminde işlemek için bir dizi çağrıyı ele alırız.
Yayılma, dağıtılmış bir sistemde yapılan tek bir iş birimini temsil eder ve başlangıç ve bitiş zamanlarını kaydeder. Aralıklar genellikle birbirleriyle hiyerarşik ilişkilere sahiptir. Aşağıdaki resimde daha küçük aralıkların alt aralıkları, geniş /mesajlar aralığının alt aralıklarıdır ve bir sistemdeki çalışmanın yolunu gösteren tek bir İzde birleştirilmiştir.
Dağıtılmış izleme arka ucu seçeneklerinden biri olan Google Cloud Trace, Google Cloud'daki diğer ürünlerle iyi entegre edilmiştir.
Oluşturacaklarınız
Bu codelab'de "Shakespeare uygulaması" adlı hizmetlerdeki enstrüman izleme bilgilerini kullanacaksınız. (diğer adıyla Shakesapp) olan bir uygulamadır. Shakesapp'in mimarisi aşağıda açıklandığı gibidir:
- Loadgen, HTTP'de istemciye bir sorgu dizesi gönderir
- İstemciler sorguyu gRPC'deki yük kaynağından sunucuya iletir
- Sunucu; istemciden gelen sorguyu kabul eder, tüm Shakespare eserlerini Google Cloud Storage'dan metin biçiminde getirir, sorguyu içeren satırları arar ve istemciyle eşleşen satırın numarasını döndürür.
İzleme bilgilerini istek genelinde kullanacaksınız. Bundan sonra, sunucuya bir profil aracı aracısı yerleştirecek ve tıkanıklığı araştıracaksınız.
Neler öğreneceksiniz?
- Go projesindeki OpenTelemetry Trace kitaplıklarını kullanmaya başlama
- Kitaplıkla aralık oluşturma
- Aralık bağlamlarını kablo genelinde uygulama bileşenleri arasında yayma
- İz verileri Cloud Trace'e nasıl gönderilir?
- Cloud Trace'te izi analiz etme
Bu codelab'de, mikro hizmetlerinizi nasıl kullanacağınız açıklanmaktadır. Anlaşılmasını kolaylaştırmak için bu örnekte yalnızca 3 bileşen (yük oluşturucu, istemci ve sunucu) vardır. Ancak bu codelab'de açıklanan süreci daha karmaşık ve büyük sistemlere de uygulayabilirsiniz.
Gerekenler
- Go hakkında temel düzeyde bilgi
- Kubernetes hakkında temel bilgiler
2. Kurulum ve Gereksinimler
Kendi hızınızda ortam kurulumu
Google Hesabınız (Gmail veya Google Apps) yoksa bir hesap oluşturmanız gerekir. Google Cloud Platform konsolunda ( console.cloud.google.com) oturum açın ve yeni bir proje oluşturun.
Zaten bir projeniz varsa konsolun sol üst köşesindeki proje seçimi açılan menüsünü tıklayın:
Sonra ‘YENİ PROJE’yi tıklayın. düğmesini tıklayın:
Henüz projeniz yoksa ilk projenizi oluşturmak için şuna benzer bir iletişim kutusu görmeniz gerekir:
Sonraki proje oluşturma iletişim kutusu yeni projenizin ayrıntılarını girmenize olanak tanır:
Tüm Google Cloud projeleri için benzersiz bir ad olan proje kimliğini unutmayın (yukarıdaki ad daha önce alınmış ve size uygun olmayacaktır!). Bu kod, bu codelab'in ilerleyen bölümlerinde PROJECT_ID olarak adlandırılacaktır.
Sonraki adımda, henüz yapmadıysanız Developers Console'da faturalandırmayı etkinleştirmeniz ve Google Cloud kaynaklarını kullanmak ve Cloud Trace API'yi etkinleştirmek için yapmanız gerekir.
Bu codelab'i çalıştırmanın maliyeti birkaç dolardan fazla değildir. Ancak daha fazla kaynak kullanmaya karar verirseniz veya bu kaynakları çalışır durumda bırakırsanız daha yüksek ücret ödemeniz gerekebilir (bu belgenin sonundaki "temizlik" bölümüne bakın). Google Cloud Trace, Google Kubernetes Engine ve Google Artifact Registry'nin fiyatları resmi belgelerde belirtilmiştir.
- Google Cloud işlem paketi için fiyatlandırma | İşlem Paketi
- Fiyatlandırma | Kubernetes Engine Belgeleri
- Artifact Registry Fiyatlandırması | Artifact Registry belgeleri
Yeni Google Cloud Platform kullanıcıları, bu codelab'i tamamen ücretsiz hale getirecek 300 ABD doları değerindeki ücretsiz denemeden yararlanabilir.
Google Cloud Shell Kurulumu
Google Cloud ve Google Cloud Trace, dizüstü bilgisayarınızdan uzaktan çalıştırılabilse de bu codelab'de Cloud'da çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacağız.
Bu Debian tabanlı sanal makine, ihtiyacınız olan tüm geliştirme araçlarıyla yüklüdür. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud'da çalışarak ağ performansını ve kimlik doğrulamasını büyük ölçüde iyileştirir. Yani bu codelab'de ihtiyacınız olan tek şey bir tarayıcıdır (Evet, Chromebook'ta çalışır).
Cloud Console'dan Cloud Shell'i etkinleştirmek için Cloud Shell'i Etkinleştir'i tıklamanız yeterlidir (sağlanması ve ortama bağlanması birkaç dakika sürer).
Cloud Shell'e bağlandıktan sonra kimliğinizin doğrulandığını ve projenin PROJECT_ID
olarak ayarlanmış olduğunu göreceksiniz.
gcloud auth list
Komut çıkışı
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
Komut çıkışı
[core] project = <PROJECT_ID>
Herhangi bir nedenle proje ayarlanmamışsa şu komutu vermeniz yeterlidir:
gcloud config set project <PROJECT_ID>
PROJECT_ID
cihazınızı mı arıyorsunuz? Kurulum adımlarında kullandığınız kimliği kontrol edin veya Cloud Console kontrol panelinden arayın:
Cloud Shell bazı ortam değişkenlerini de varsayılan olarak ayarlar. Bu değişkenler, gelecekte komut çalıştırdığınızda işinize yarayabilir.
echo $GOOGLE_CLOUD_PROJECT
Komut çıkışı
<PROJECT_ID>
Son olarak, varsayılan alt bölgeyi ve proje yapılandırmasını ayarlayın.
gcloud config set compute/zone us-central1-f
Çeşitli farklı alt bölgeler seçebilirsiniz. Daha fazla bilgi için Bölgeler ve Bölgeler.
Go dil kurulumu
Bu codelab'de tüm kaynak kodları için Go'yu kullanacağız. Cloud Shell'de aşağıdaki komutu çalıştırın ve Go sürümünün 1.17 veya üzeri bir sürüm olup olmadığını onaylayın.
go version
Komut çıkışı
go version go1.18.3 linux/amd64
Google Kubernetes Kümesi oluşturma
Bu codelab'de, Google Kubernetes Engine'de (GKE) bir mikro hizmet kümesi çalıştıracaksınız. Bu codelab'de süreç aşağıdaki gibidir:
- Temel projeyi Cloud Shell'e indirme
- Container'larda mikro hizmetler derleme
- Kapsayıcıları Google Artifact Registry'ye (GAR) yükleme
- Container'ları GKE'ye dağıtma
- İzleme araçları için hizmetlerin kaynak kodunu değiştirin
- 2. adıma git
Kubernetes Engine'i etkinleştirme
İlk olarak Shakesapp'in GKE'de çalıştığı bir Kubernetes kümesi oluşturmak için GKE'yi etkinleştirmemiz gerekiyor. "Kubernetes Engine" menüsüne gidin ETKİNLEŞTİR düğmesine basın.
Artık Kubernetes kümesi oluşturmaya hazırsınız.
Kubernetes kümesi oluşturma
Cloud Shell'de, Kubernetes kümesi oluşturmak için aşağıdaki komutu çalıştırın. Lütfen Artifact Registry deposu oluşturmak için kullanacağınız bölge değerinin altında olduğunu onaylayın. Depo bölgeniz, alt bölgeyi kapsamıyorsa us-central1-f
alt bölge değerini değiştirin.
gcloud container clusters create otel-trace-codelab2 \ --zone us-central1-f \ --release-channel rapid \ --preemptible \ --enable-autoscaling \ --max-nodes 8 \ --no-enable-ip-alias \ --scopes cloud-platform
Komut çıkışı
Note: Your Pod address range (`--cluster-ipv4-cidr`) can accommodate at most 1008 node(s). Creating cluster otel-trace-codelab2 in us-central1-f... Cluster is being health-checked (master is healthy)...done. Created [https://container.googleapis.com/v1/projects/development-215403/zones/us-central1-f/clusters/otel-trace-codelab2]. To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-f/otel-trace-codelab2?project=development-215403 kubeconfig entry generated for otel-trace-codelab2. NAME: otel-trace-codelab2 LOCATION: us-central1-f MASTER_VERSION: 1.23.6-gke.1501 MASTER_IP: 104.154.76.89 MACHINE_TYPE: e2-medium NODE_VERSION: 1.23.6-gke.1501 NUM_NODES: 3 STATUS: RUNNING
Artifact Registry ve skaffold kurulumu
Artık dağıtıma hazır bir Kubernetes kümemiz var. Şimdi, container'ları push ve dağıtma işlemleri için container kaydı için hazırlayacağız. Bu adımlar için bir Artifact Registry (GAR) oluşturmamız ve bunu kullanmak için kaykay yapmamız gerekir.
Artifact Registry kurulumu
"Artifact Registry" menüsüne gidin ETKİNLEŞTİR düğmesine basın.
Bir süre sonra GAR'nin depo tarayıcısını göreceksiniz. "REPOSITORY OLUŞTUR"u tıklayın. düğmesini tıklayın ve deponun adını girin.
Bu codelab'de yeni depoyu trace-codelab
olarak adlandırıyorum. Yapının biçimi "Docker"dır ve konum türü "Bölge" ise. Google Compute Engine varsayılan alt bölgesi için belirlediğinize yakın bölgeyi seçin. Örneğin, bu örnek "us-central1-f"yi seçti Burada "us-central1 (Iowa)"yı seçiyoruz. Ardından "OLUŞTUR"u tıklayın. düğmesini tıklayın.
Artık "trace-codelab"i görüyorsunuz. kod deposunda toplanır.
Kayıt defteri yolunu kontrol etmek için daha sonra buraya geri döneceğiz.
Skaffold kurulumu
Skaffold, Kubernetes üzerinde çalışan mikro hizmetler oluştururken kullanabileceğiniz pratik bir araçtır. Uygulama container'larını oluşturma, aktarma ve dağıtma iş akışını küçük bir komut grubuyla yönetir. Skaffold, container kayıt defteri olarak varsayılan olarak Docker Registry'yi kullanır. Bu nedenle, container'lara aktarılırken GAR'yi tanımak için skaffold'u yapılandırmanız gerekir.
Cloud Shell'i tekrar açın ve skaffold yüklü olup olmadığını onaylayın. (Cloud Shell'i varsayılan olarak ortama yükler.) Aşağıdaki komutu çalıştırarak skaffold sürümünü görebilirsiniz.
skaffold version
Komut çıkışı
v1.38.0
Şimdi, varsayılan depoyu skaf Fold'un kullanması için kaydedebilirsiniz. Kayıt defteri yolunu almak için Artifact Registry kontrol paneline gidin ve önceki adımda ayarladığınız deponun adını tıklayın.
Ardından, sayfanın üst kısmında içerik haritası yollarını görürsünüz. Kayıt defteri yolunu panoya kopyalamak için simgesini tıklayın.
Kopyala düğmesini tıkladığınızda, tarayıcının en altında aşağıdakine benzer bir mesaj içeren bir iletişim kutusu görürsünüz:
"us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab" kopyalandı
Cloud Shell'e geri dönün. Kontrol panelinden kopyaladığınız değerle skaffold config set default-repo
komutunu çalıştırın.
skaffold config set default-repo us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab
Komut çıkışı
set value default-repo to us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab for context gke_stackdriver-sandbox-3438851889_us-central1-b_stackdriver-sandbox
Ayrıca, kayıt defterini Docker yapılandırmasına göre yapılandırmanız gerekir. Aşağıdaki komutu çalıştırın:
gcloud auth configure-docker us-central1-docker.pkg.dev --quiet
Komut çıkışı
{ "credHelpers": { "gcr.io": "gcloud", "us.gcr.io": "gcloud", "eu.gcr.io": "gcloud", "asia.gcr.io": "gcloud", "staging-k8s.gcr.io": "gcloud", "marketplace.gcr.io": "gcloud", "us-central1-docker.pkg.dev": "gcloud" } } Adding credentials for: us-central1-docker.pkg.dev
Artık GKE'de Kubernetes container'ı oluşturma adımına geçebilirsiniz.
Özet
Bu adımda codelab ortamınızı kuracaksınız:
- Cloud Shell'i kurma
- Container kayıt defteri için Artifact Registry deposu oluşturuldu
- Container kayıt defterini kullanmak için skaffold'u ayarlama
- codelab mikro hizmetlerinin çalıştırıldığı bir Kubernetes kümesi oluşturuldu
Sonraki bölüm
Bir sonraki adımda mikro hizmetlerinizi derleyecek, kümeye aktaracak ve dağıtacaksınız.
3. Mikro hizmetleri derleme, aktarma ve dağıtma
Codelab materyalini indirin
Önceki adımda bu codelab için tüm ön koşulları ayarladık. Artık tüm mikro hizmetleri bunların üzerinde çalıştırmaya hazırsınız. Codelab materyali GitHub'da barındırıldığından aşağıdaki git komutuyla verileri Cloud Shell ortamına indirin.
cd ~ git clone https://github.com/ymotongpoo/opentelemetry-trace-codelab-go.git cd opentelemetry-trace-codelab-go
Projenin dizin yapısı aşağıdaki gibidir:
. ├── README.md ├── step0 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step1 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step2 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step3 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step4 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src ├── step5 │ ├── manifests │ ├── proto │ ├── skaffold.yaml │ └── src └── step6 ├── manifests ├── proto ├── skaffold.yaml └── src
- manifest'ler: Kubernetes manifest dosyaları
- proto: istemci ve sunucu arasındaki iletişimin proto tanımı
- src: her hizmetin kaynak kodu için dizinler
- skaffold.yaml: Skaffold için yapılandırma dosyası
Bu codelab'de, step0
klasörünün altında bulunan kaynak kodunu güncelleyeceksiniz. Aşağıdaki adımlarda verilen yanıtlar için step[1-6]
klasöründeki kaynak koda da bakabilirsiniz. (1. Bölüm 0. adımdan 4. adıma, 2. Bölüm 5. ve 6. adımları kapsar)
skaffold komutunu çalıştırma
Artık tüm içeriği derlemeye, aktarmaya ve az önce oluşturduğunuz Kubernetes kümesine dağıtmaya hazırsınız. Bu araç birden fazla adım içeriyormuş gibi görünüyor, ancak gerçek kaykay, her şeyi sizin için yapıyor. Bunu aşağıdaki komutla deneyelim:
cd step0 skaffold dev
Komutu çalıştırır çalıştırmaz docker build
günlük çıkışını görürsünüz ve bunların kayıt defterine başarıyla aktarıldığını onaylayabilirsiniz.
Komut çıkışı
... ---> Running in c39b3ea8692b ---> 90932a583ab6 Successfully built 90932a583ab6 Successfully tagged us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/serverservice:step1 The push refers to repository [us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/serverservice] cc8f5a05df4a: Preparing 5bf719419ee2: Preparing 2901929ad341: Preparing 88d9943798ba: Preparing b0fdf826a39a: Preparing 3c9c1e0b1647: Preparing f3427ce9393d: Preparing 14a1ca976738: Preparing f3427ce9393d: Waiting 14a1ca976738: Waiting 3c9c1e0b1647: Waiting b0fdf826a39a: Layer already exists 88d9943798ba: Layer already exists f3427ce9393d: Layer already exists 3c9c1e0b1647: Layer already exists 14a1ca976738: Layer already exists 2901929ad341: Pushed 5bf719419ee2: Pushed cc8f5a05df4a: Pushed step1: digest: sha256:8acdbe3a453001f120fb22c11c4f6d64c2451347732f4f271d746c2e4d193bbe size: 2001
Tüm hizmet container'ları aktarıldıktan sonra Kubernetes dağıtımları otomatik olarak başlar.
Komut çıkışı
sha256:b71fce0a96cea08075dc20758ae561cf78c83ff656b04d211ffa00cedb77edf8 size: 1997 Tags used in deployment: - serverservice -> us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/serverservice:step4@sha256:8acdbe3a453001f120fb22c11c4f6d64c2451347732f4f271d746c2e4d193bbe - clientservice -> us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/clientservice:step4@sha256:b71fce0a96cea08075dc20758ae561cf78c83ff656b04d211ffa00cedb77edf8 - loadgen -> us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/loadgen:step4@sha256:eea2e5bc8463ecf886f958a86906cab896e9e2e380a0eb143deaeaca40f7888a Starting deploy... - deployment.apps/clientservice created - service/clientservice created - deployment.apps/loadgen created - deployment.apps/serverservice created - service/serverservice created
Dağıtımdan sonra her container'da stdout'a yayınlanan gerçek uygulama günlüklerini aşağıdaki gibi görürsünüz:
Komut çıkışı
[client] 2022/07/14 06:33:15 {"match_count":3040} [loadgen] 2022/07/14 06:33:15 query 'love': matched 3040 [client] 2022/07/14 06:33:15 {"match_count":3040} [loadgen] 2022/07/14 06:33:15 query 'love': matched 3040 [client] 2022/07/14 06:33:16 {"match_count":3040} [loadgen] 2022/07/14 06:33:16 query 'love': matched 3040 [client] 2022/07/14 06:33:19 {"match_count":463} [loadgen] 2022/07/14 06:33:19 query 'tear': matched 463 [loadgen] 2022/07/14 06:33:20 query 'world': matched 728 [client] 2022/07/14 06:33:20 {"match_count":728} [client] 2022/07/14 06:33:22 {"match_count":463} [loadgen] 2022/07/14 06:33:22 query 'tear': matched 463
Bu aşamada, sunucudan gelen tüm iletileri görmek istediğinizi unutmayın. Tamam, nihayet hizmetlerin dağıtılmış izlemesi için OpenTelemetry ile uygulamanıza enstrümantasyon yapmaya hazırsınız.
Hizmetin enstrümantasyonuna başlamadan önce lütfen Ctrl-C tuşlarına basarak kümenizi kapatın.
Komut çıkışı
... [client] 2022/07/14 06:34:57 {"match_count":1} [loadgen] 2022/07/14 06:34:57 query 'what's past is prologue': matched 1 ^CCleaning up... - W0714 06:34:58.464305 28078 gcp.go:120] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.25+; use gcloud instead. - To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke - deployment.apps "clientservice" deleted - service "clientservice" deleted - deployment.apps "loadgen" deleted - deployment.apps "serverservice" deleted - service "serverservice" deleted
Özet
Bu adımda, codelab materyalini ortamınızda hazırladınız ve patenin beklendiği gibi çalıştığını onayladınız.
Sonraki bölüm
Sonraki adımda iz bilgilerini kullanmak için loadgen hizmetinin kaynak kodunu değiştireceksiniz.
4. HTTP Enstrümantasyonu
İz enstrümantasyonu ve yayılımı kavramı
Kaynak kodunu düzenlemeden önce, dağıtılmış izlerin nasıl çalıştığını basit bir diyagramda kısaca açıklayayım.
Bu örnekte, İzleme ve Aralık bilgilerini Cloud Trace'e aktarmak ve iz bağlamını, istekteki loadgen hizmetinden sunucu hizmetine yaymak için kodda işlemleri gerçekleştiriyoruz.
Uygulamaların, aynı iz kimliğine sahip tüm aralıkları tek izde derlemesi için Cloud Trace'in işlemesi için İzleme Kimliği ve Span Kimliği gibi İz meta verileri göndermesi gerekir. Ayrıca uygulamanın, aşağı akış hizmetleri isteğinde bulunurken iz bağlamlarını (üst aralığın İzleme Kimliği ve Aralık Kimliği kombinasyonu) yayması gerekir. Böylece kullanıcılar hangi izleme bağlamını işlediklerini öğrenebilir.
OpenTelemetry size şu konularda yardımcı olur:
- benzersiz İzleme Kimliği ve Aralık Kimliği oluşturmak için
- arka uca iz kimliğini ve yayılma kimliğini aktarmak için
- izleme bağlamlarını diğer hizmetlere yaymak için
- Böylece, izleri analiz etmeye yardımcı olan ekstra meta veriler yerleştirmek için
OpenTelemetry Trace'teki Bileşenler
OpenTelemetry ile uygulama izleme işlemi aşağıdaki gibidir:
- Dışa aktarıcı oluşturma
- Dışa aktarıcı için 1 bağlantıda bir TracerProvider oluşturun ve global olarak ayarlayın.
- Yayılım yöntemini ayarlamak için TextMapPropagaror'ı ayarlayın
- TracerProvider'dan Tracer alma
- İzleyiciden Aralık Oluşturma
Şimdilik, her bileşenin ayrıntılı özelliklerini anlamanız gerekmez ancak unutulmaması gereken en önemli noktalar şunlardır:
- buradaki dışa aktarıcı TracerProvider'a bağlanabilir
- TracerProvider, iz örnekleme ve dışa aktarmayla ilgili tüm yapılandırmayı içerir
- tüm izler, Tracer nesnesinde gruplanır
Bunu anladıktan sonra gerçek kodlama işlemine geçelim.
Enstrüman ilk aralık
Enstrüman yük oluşturma hizmeti
Cloud Shell'in sağ üst tarafında bulunan düğmeye basarak Cloud Shell Düzenleyici'yi açın. Sol bölmedeki gezginden
step0/src/loadgen/main.go
uygulamasını açın ve ana işlevi bulun.
step0/src/loadgen/main.go
func main() { ... for range t.C { log.Printf("simulating client requests, round %d", i) if err := run(numWorkers, numConcurrency); err != nil { log.Printf("aborted round with error: %v", err) } log.Printf("simulated %d requests", numWorkers) if numRounds != 0 && i > numRounds { break } i++ } }
Ana işlevde, run
fonksiyonunu çağıran döngüyü görürsünüz. Geçerli uygulamada, bölümde işlev çağrısının başlangıcını ve sonunu kaydeden 2 günlük satırı bulunur. Şimdi fonksiyon çağrısının gecikmesini izlemek için Span bilgilerini kullanalım.
Önceki bölümde belirtildiği gibi, önce OpenTelemetry için tüm yapılandırmaları ayarlayalım. OpenTelemetry paketlerini aşağıdaki gibi ekleyin:
step0/src/loadgen/main.go
import ( "context" // step1. add packages "encoding/json" "fmt" "io" "log" "math/rand" "net/http" "net/url" "time" // step1. add packages "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.10.0" "go.opentelemetry.io/otel/trace" // step1. end add packages )
Okunabilirlik için initTracer
adında bir kurulum işlevi oluşturup main
işlevinde bu işlevi çağırıyoruz.
step0/src/loadgen/main.go
// step1. add OpenTelemetry initialization function func initTracer() (*sdktrace.TracerProvider, error) { // create a stdout exporter to show collected spans out to stdout. exporter, err := stdout.New(stdout.WithPrettyPrint()) if err != nil { return nil, err } // for the demonstration, we use AlwaysSmaple sampler to take all spans. // do not use this option in production. tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithBatcher(exporter), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.TraceContext{}) return tp, nil }
OpenTelemetry'yi ayarlama prosedürünün önceki bölümde açıklandığı gibi olduğunu görebilirsiniz. Bu uygulamada, tüm iz bilgilerini yapılandırılmış bir biçimde stdout'a aktaran bir stdout
dışa aktarıcısı kullanırız.
Ardından, bunu ana işlevden çağırırsınız. initTracer()
hattını arayın ve uygulamayı kapattığınızda TracerProvider.Shutdown()
işlevini çağırdığınızdan emin olun.
step0/src/loadgen/main.go
func main() { // step1. setup OpenTelemetry tp, err := initTracer() if err != nil { log.Fatalf("failed to initialize TracerProvider: %v", err) } defer func() { if err := tp.Shutdown(context.Background()); err != nil { log.Fatalf("error shutting down TracerProvider: %v", err) } }() // step1. end setup log.Printf("starting worder with %d workers in %d concurrency", numWorkers, numConcurrency) log.Printf("number of rounds: %d (0 is inifinite)", numRounds) ...
Kurulumu tamamladıktan sonra benzersiz bir İz Kimliği ve Yayılma Kimliği olan bir Span oluşturmanız gerekir. OpenTelemetry bu uygulama için kullanışlı bir kitaplık sağlar. Araç HTTP istemcisine ekstra yeni paketler ekleyin.
step0/src/loadgen/main.go
import ( "context" "encoding/json" "fmt" "io" "log" "math/rand" "net/http" "net/http/httptrace" // step1. add packages "net/url" "time" // step1. add packages "go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" // step1. end add packages "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.10.0" "go.opentelemetry.io/otel/trace" )
Yük oluşturucu, runQuery
işlevindeki net/http
ile HTTP'de istemci hizmetini çağırdığından, net/http
için yardımcı paketini kullanırız ve httptrace
ile otelhttp
paketinin uzantısıyla araçları etkinleştiririz.
Öncelikle, kullanılan istemci aracılığıyla HTTP isteklerini çağırmak için httpClient paket genel değişkeni ekleyin.
step0/src/loadgen/main.go
var httpClient = http.Client{ Transport: otelhttp.NewTransport(http.DefaultTransport) }
Ardından, OpenTelemetry ve özel HTTP istemcisinden otomatik olarak oluşturulan aralığı kullanarak özel aralığı oluşturmak için runQuery
işlevine enstrümantasyon ekleyin. Yapmanız gerekenler:
otel.Tracer()
ile globalTracerProvider
sağlayıcısından bir Tracer alınTracer.Start()
yöntemiyle kök aralığı oluşturma- Kök aralığını rastgele bir zamanlamada sonlandırın (bu örnekte
runQuery
işlevinin sonu)
step0/src/loadgen/main.go
reqURL.RawQuery = v.Encode() // step1. replace http.Get() with custom client call // resp, err := http.Get(reqURL.String()) // step1. instrument trace ctx := context.Background() tr := otel.Tracer("loadgen") ctx, span := tr.Start(ctx, "query.request", trace.WithAttributes( semconv.TelemetrySDKLanguageGo, semconv.ServiceNameKey.String("loadgen.runQuery"), attribute.Key("query").String(s), )) defer span.End() ctx = httptrace.WithClientTrace(ctx, otelhttptrace.NewClientTrace(ctx)) req, err := http.NewRequestWithContext(ctx, "GET", reqURL.String(), nil) if err != nil { return -1, fmt.Errorf("error creating HTTP request object: %v", err) } resp, err := httpClient.Do(req) // step1. end instrumentation if err != nil { return -1, fmt.Errorf("error sending request to %v: %v", reqURL.String(), err) }
Artık loadgen'deki (HTTP istemci uygulaması) araçları tamamlamış oldunuz. Lütfen go.mod
ve go.sum
komutlarınızı go mod
komutuyla güncellediğinizden emin olun.
go mod tidy
Araç müşteri hizmetleri
Önceki bölümde, aşağıdaki çizimde kırmızı dikdörtgen içine alınan parçaya enstrümantasyon yöntemini uyguladık. Aralık bilgilerini yük oluşturma aracı hizmetinde kullandık. Yük oluşturma hizmetine benzer şekilde, şimdi istemci hizmetinde de enstrümantasyon yapmamız gerekir. Yük oluşturma hizmeti ile farkı, istemci hizmetinin, HTTP üstbilgisindeki yük oluşturucu hizmetinden yayılan İz Kimliği bilgilerini ayıklaması ve bu bilgiyi Aralıkları oluşturmak için kullanmasıdır.
Cloud Shell Düzenleyici'yi açın ve yük oluşturma aracı hizmeti için yaptığımız gibi gerekli paketleri ekleyin.
step0/src/client/main.go
import ( "context" "encoding/json" "fmt" "io" "log" "net/http" "net/url" "os" "time" "opentelemetry-trace-codelab-go/client/shakesapp" // step1. add new import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" // step1. end new import )
Tekrar, OpenTelemtry'yi kurmamız gerekir. initTracer
işlevini loadgen'den kopyalayıp istemci hizmetinin main
işlevinde de çağırmanız yeterlidir.
step0/src/client/main.go
// step1. add OpenTelemetry initialization function func initTracer() (*sdktrace.TracerProvider, error) { // create a stdout exporter to show collected spans out to stdout. exporter, err := stdout.New(stdout.WithPrettyPrint()) if err != nil { return nil, err } // for the demonstration, we use AlwaysSmaple sampler to take all spans. // do not use this option in production. tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithBatcher(exporter), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.TraceContext{}) return tp, nil }
Şimdi enstrümanları kullanma zamanı. İstemci hizmetinin loadgen hizmetinden gelen HTTP isteklerini kabul etmesi gerektiğinden, işleyiciyi izlemesi gerekir. İstemci hizmetindeki HTTP sunucusu net/http ile uygulanır ve otelhttp
paketini yükleyicide yaptığımız gibi kullanabilirsiniz.
Öncelikle işleyici kaydını otelhttp
İşleyicisi ile değiştiririz. main
işlevinde, HTTP işleyicinin http.HandleFunc()
ile kaydedildiği satırları bulun.
step0/src/client/main.go
// step1. change handler to intercept OpenTelemetry related headers // http.HandleFunc("/", svc.handler) otelHandler := otelhttp.NewHandler(http.HandlerFunc(svc.handler), "client.handler") http.Handle("/", otelHandler) // step1. end intercepter setting http.HandleFunc("/_genki", svc.health)
Daha sonra, gerçek aralığı işleyicinin içinde ölçeriz. Func (*clientService) işleyici() işleyicisini bulun ve trace.SpanFromContext()
ile aralık enstrümantasyonu ekleyin.
step0/src/client/main.go
func (cs *clientService) handler(w http.ResponseWriter, r *http.Request) { ... ctx := r.Context() ctx, cancel := context.WithCancel(ctx) defer cancel() // step1. instrument trace span := trace.SpanFromContext(ctx) defer span.End() // step1. end instrument ...
Bu araçla, handler
yönteminin başlangıcından sonuna kadar olan aralıkları elde edersiniz. Aralıkların analiz edilmesini kolaylaştırmak için, eşleşen sayısını sorguya depolayan ekstra bir özellik ekleyin. Günlük satırının hemen önüne aşağıdaki kodu ekleyin.
func (cs *clientService) handler(w http.ResponseWriter, r *http.Request) { ... // step1. add span specific attribute span.SetAttributes(attribute.Key("matched").Int64(resp.MatchCount)) // step1. end adding attribute log.Println(string(ret)) ...
Yukarıdaki tüm araçları kullanarak loadgen ile istemci arasındaki izleme enstrümantasyonunu tamamladınız. Şimdi, bunun işleyiş şekline bakalım. Kodu skaffold ile tekrar çalıştırın.
skaffold dev
Hizmetleri GKE kümesinde çalıştırdıktan bir süre sonra, aşağıdaki gibi çok sayıda günlük mesajı göreceksiniz:
Komut çıkışı
[loadgen] { [loadgen] "Name": "query.request", [loadgen] "SpanContext": { [loadgen] "TraceID": "cfa22247a542beeb55a3434392d46b89", [loadgen] "SpanID": "18b06404b10c418b", [loadgen] "TraceFlags": "01", [loadgen] "TraceState": "", [loadgen] "Remote": false [loadgen] }, [loadgen] "Parent": { [loadgen] "TraceID": "00000000000000000000000000000000", [loadgen] "SpanID": "0000000000000000", [loadgen] "TraceFlags": "00", [loadgen] "TraceState": "", [loadgen] "Remote": false [loadgen] }, [loadgen] "SpanKind": 1, [loadgen] "StartTime": "2022-07-14T13:13:36.686751087Z", [loadgen] "EndTime": "2022-07-14T13:14:31.849601964Z", [loadgen] "Attributes": [ [loadgen] { [loadgen] "Key": "telemetry.sdk.language", [loadgen] "Value": { [loadgen] "Type": "STRING", [loadgen] "Value": "go" [loadgen] } [loadgen] }, [loadgen] { [loadgen] "Key": "service.name", [loadgen] "Value": { [loadgen] "Type": "STRING", [loadgen] "Value": "loadgen.runQuery" [loadgen] } [loadgen] }, [loadgen] { [loadgen] "Key": "query", [loadgen] "Value": { [loadgen] "Type": "STRING", [loadgen] "Value": "faith" [loadgen] } [loadgen] } [loadgen] ], [loadgen] "Events": null, [loadgen] "Links": null, [loadgen] "Status": { [loadgen] "Code": "Unset", [loadgen] "Description": "" [loadgen] }, [loadgen] "DroppedAttributes": 0, [loadgen] "DroppedEvents": 0, [loadgen] "DroppedLinks": 0, [loadgen] "ChildSpanCount": 5, [loadgen] "Resource": [ [loadgen] { [loadgen] "Key": "service.name", [loadgen] "Value": { [loadgen] "Type": "STRING", [loadgen] "Value": "unknown_service:loadgen" ...
stdout
dışa aktarıcısı bu mesajları yayar. Loadgen'e göre tüm aralıkların üst öğeleri için TraceID: 00000000000000000000000000000000
olduğunu fark edersiniz. Bunun nedeni, kök aralığı, yani izdeki ilk aralık olması nedeniyle bu aralıktır. Ayrıca "query"
yerleştirme özelliğinin, istemci hizmetine iletilen sorgu dizesine sahip olduğunu gördünüz.
Özet
Bu adımda, HTTP'de iletişim kuran yük oluşturma aracı hizmeti ve istemci hizmetiniz var. Bağlamı başarılı bir şekilde hizmetler arasında yayabildiğinizi ve Span bilgilerini her iki hizmetten stdout'a aktarabildiğinizi onayladınız.
Sonraki bölüm
Sonraki adımda gRPC aracılığıyla Bağlam İzlemenin nasıl yayılacağını doğrulamak için istemci hizmeti ve sunucu hizmetini kullanacaksınız.
5. gRPC için Enstrümantasyon
Önceki adımda, isteğin ilk yarısını bu mikro hizmetlerde ayarladık. Bu adımda istemci hizmeti ile sunucu hizmeti arasında gRPC iletişimini sağlamaya çalışırız. (Aşağıdaki resimde yeşil ve mor dikdörtgen)
gRPC istemcisi için önceden derleme aracı
OpenTelemetry'nin ekosistemi, geliştiricilerin uygulamaları kullanmasına yardımcı olan birçok kullanışlı kitaplık sunar. Önceki adımda, net/http
paketi için önceden derleme araçları kullandık. Bu adımda, gRPC aracılığıyla Trace Bağlamı yayılmaya çalışırken bunun için kitaplığı kullanacağız.
Önce, otelgrpc
adlı önceden oluşturulmuş gRPC paketini içe aktarırsınız.
step0/src/client/main.go
import ( "context" "encoding/json" "fmt" "io" "log" "net/http" "net/url" "os" "time" "opentelemetry-trace-codelab-go/client/shakesapp" // step2. add prebuilt gRPC package (otelgrpc) "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" )
Bu kez istemci hizmeti, sunucu hizmetine karşı bir gRPC istemcisi olduğundan gRPC istemcisinde enstrümantasyon yapmanız gerekir. mustConnGRPC
işlevini bulun ve istemcinin sunucuya her istek gönderdiğinde yeni aralıklar belirleyen gRPC önleyicilerini ekleyin.
step0/src/client/main.go
// Helper function for gRPC connections: Dial and create client once, reuse. func mustConnGRPC(ctx context.Context, conn **grpc.ClientConn, addr string) { var err error // step2. add gRPC interceptor interceptorOpt := otelgrpc.WithTracerProvider(otel.GetTracerProvider()) *conn, err = grpc.DialContext(ctx, addr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor(interceptorOpt)), grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(interceptorOpt)), grpc.WithTimeout(time.Second*3), ) // step2: end adding interceptor if err != nil { panic(fmt.Sprintf("Error %s grpc: failed to connect %s", err, addr)) } }
Önceki bölümde OpenTelemetry'yi zaten ayarladığınızdan bunu yapmanıza gerek yoktur.
gRPC sunucusu için önceden oluşturulmuş araçlar
gRPC istemcisi için yaptığımız gibi, biz de gRPC sunucusu için önceden oluşturulmuş araç diyoruz. İçe aktarma bölümüne yeni paket ekleyin. Örneğin:
step0/src/server/main.go
import ( "context" "fmt" "io/ioutil" "log" "net" "os" "regexp" "strings" "opentelemetry-trace-codelab-go/server/shakesapp" "cloud.google.com/go/storage" // step2. add OpenTelemetry packages including otelgrpc "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "go.opentelemetry.io/otel" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/grpc" healthpb "google.golang.org/grpc/health/grpc_health_v1" )
Bu, araç sunucusuna ilk kez giriliyor. Bu nedenle, loadgen ve istemci hizmetlerinde yaptığımıza benzer şekilde, önce OpenTelemetry'yi kurmanız gerekir.
step0/src/server/main.go
// step2. add OpenTelemetry initialization function func initTracer() (*sdktrace.TracerProvider, error) { // create a stdout exporter to show collected spans out to stdout. exporter, err := stdout.New(stdout.WithPrettyPrint()) if err != nil { return nil, err } // for the demonstration, we use AlwaysSmaple sampler to take all spans. // do not use this option in production. tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithBatcher(exporter), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.TraceContext{}) return tp, nil } func main() { ... // step2. setup OpenTelemetry tp, err := initTracer() if err != nil { log.Fatalf("failed to initialize TracerProvider: %v", err) } defer func() { if err := tp.Shutdown(context.Background()); err != nil { log.Fatalf("error shutting down TracerProvider: %v", err) } }() // step2. end setup ...
Son olarak, sunucu önleyicilerini eklemeniz gerekir. main
işlevinde, grpc.NewServer()
işlevinin çağrıldığı yeri bulun ve işleve önleyiciler ekleyin.
step0/src/server/main.go
func main() { ... svc := NewServerService() // step2: add interceptor interceptorOpt := otelgrpc.WithTracerProvider(otel.GetTracerProvider()) srv := grpc.NewServer( grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor(interceptorOpt)), grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor(interceptorOpt)), ) // step2: end adding interceptor shakesapp.RegisterShakespeareServiceServer(srv, svc) ...
Mikro hizmeti çalıştırıp izini onaylayın
Ardından, değiştirdiğiniz kodu skaffold komutuyla çalıştırın.
skaffold dev
Şimdi tekrar, stdout ile ilgili bir dizi span bilgisi görüyorsunuz.
Komut çıkışı
... [server] { [server] "Name": "shakesapp.ShakespeareService/GetMatchCount", [server] "SpanContext": { [server] "TraceID": "89b472f213a400cf975e0a0041649667", [server] "SpanID": "96030dbad0061b3f", [server] "TraceFlags": "01", [server] "TraceState": "", [server] "Remote": false [server] }, [server] "Parent": { [server] "TraceID": "89b472f213a400cf975e0a0041649667", [server] "SpanID": "cd90cc3859b73890", [server] "TraceFlags": "01", [server] "TraceState": "", [server] "Remote": true [server] }, [server] "SpanKind": 2, [server] "StartTime": "2022-07-14T14:05:55.74822525Z", [server] "EndTime": "2022-07-14T14:06:03.449258891Z", [server] "Attributes": [ ... [server] ], [server] "Events": [ [server] { [server] "Name": "message", [server] "Attributes": [ ... [server] ], [server] "DroppedAttributeCount": 0, [server] "Time": "2022-07-14T14:05:55.748235489Z" [server] }, [server] { [server] "Name": "message", [server] "Attributes": [ ... [server] ], [server] "DroppedAttributeCount": 0, [server] "Time": "2022-07-14T14:06:03.449255889Z" [server] } [server] ], [server] "Links": null, [server] "Status": { [server] "Code": "Unset", [server] "Description": "" [server] }, [server] "DroppedAttributes": 0, [server] "DroppedEvents": 0, [server] "DroppedLinks": 0, [server] "ChildSpanCount": 0, [server] "Resource": [ [server] { ... [server] ], [server] "InstrumentationLibrary": { [server] "Name": "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc", [server] "Version": "semver:0.33.0", [server] "SchemaURL": "" [server] } [server] } ...
Aralık adı yerleştirmediğinizi ve trace.Start()
ya da span.SpanFromContext()
ile manuel olarak kapsam oluşturmadığınızı fark ettiniz. gRPC önleyicileri bunları oluşturduğu için yine de çok sayıda aralık elde edersiniz.
Özet
Bu adımda OpenTelemetry ekosistem kitaplıklarının desteğiyle gRPC tabanlı iletişimi geliştirdiniz.
Sonraki bölüm
Sonraki adımda, son olarak Cloud Trace ile izi görselleştirecek ve toplanan aralıkları nasıl analiz edeceğinizi öğreneceksiniz.
6. Cloud Trace ile izi görselleştirme
OpenTelemetry ile tüm sistemde enstrümantasyonlu izler kullandınız. Şu ana kadar HTTP ve gRPC hizmetlerinin nasıl kullanılacağını öğrendiniz. Bunları nasıl kullanacağınızı öğrendiniz ancak yine de nasıl analiz edeceğinizi öğrenmediniz. Bu bölümde, stdout dışa aktarıcılarını Cloud Trace dışa aktarıcılarıyla değiştirecek ve izlerinizi nasıl analiz edeceğinizi öğreneceksiniz.
Cloud Trace dışa aktarıcısını kullanma
OpenTelemetry'nin güçlü özelliklerinden biri takılabilirliğidir. Araçlarınız tarafından toplanan tüm aralıkları görselleştirmek için yapmanız gereken, stdout Exporter'ı Cloud Trace aktarıcısıyla değiştirmektir.
Her hizmetin main.go
dosyasını açın ve initTracer()
işlevini bulun. Satırı silerek stdout dışa aktarıcısı oluşturun ve bunun yerine Cloud Trace dışa aktarıcısı oluşturun.
step0/src/loadgen/main.go
import ( ... // step3. add OpenTelemetry for Cloud Trace package cloudtrace "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" ) // step1. add OpenTelemetry initialization function func initTracer() (*sdktrace.TracerProvider, error) { // step3. replace stdout exporter with Cloud Trace exporter // cloudtrace.New() finds the credentials to Cloud Trace automatically following the // rules defined by golang.org/x/oauth2/google.findDefaultCredentailsWithParams. // https://pkg.go.dev/golang.org/x/oauth2/google#FindDefaultCredentialsWithParams exporter, err := cloudtrace.New() // step3. end replacing exporter if err != nil { return nil, err } // for the demonstration, we use AlwaysSmaple sampler to take all spans. // do not use this option in production. tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithBatcher(exporter), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.TraceContext{}) return tp, nil }
Bu işlevi istemci ve sunucu hizmetinde de düzenlemeniz gerekir.
Mikro hizmeti çalıştırıp izini onaylayın
Düzenlemeden sonra kümeyi skaffold komutuyla normal şekilde çalıştırın.
skaffold dev
Bu durumda, dışa aktarıcıyı Cloud Trace One ile değiştirdiğinizden stdout'ta yapılandırılmış günlükler biçiminde çok fazla aralık bilgisi görmezsiniz.
Komut çıkışı
[loadgen] 2022/07/14 15:01:07 simulated 20 requests [loadgen] 2022/07/14 15:01:07 simulating client requests, round 37 [loadgen] 2022/07/14 15:01:14 query 'sweet': matched 958 [client] 2022/07/14 15:01:14 {"match_count":958} [client] 2022/07/14 15:01:14 {"match_count":3040} [loadgen] 2022/07/14 15:01:14 query 'love': matched 3040 [client] 2022/07/14 15:01:15 {"match_count":349} [loadgen] 2022/07/14 15:01:15 query 'hello': matched 349 [client] 2022/07/14 15:01:15 {"match_count":484} [loadgen] 2022/07/14 15:01:15 query 'faith': matched 484 [loadgen] 2022/07/14 15:01:15 query 'insolence': matched 14 [client] 2022/07/14 15:01:15 {"match_count":14} [client] 2022/07/14 15:01:21 {"match_count":484} [loadgen] 2022/07/14 15:01:21 query 'faith': matched 484 [client] 2022/07/14 15:01:21 {"match_count":728} [loadgen] 2022/07/14 15:01:21 query 'world': matched 728 [client] 2022/07/14 15:01:22 {"match_count":484} [loadgen] 2022/07/14 15:01:22 query 'faith': matched 484 [loadgen] 2022/07/14 15:01:22 query 'hello': matched 349 [client] 2022/07/14 15:01:22 {"match_count":349} [client] 2022/07/14 15:01:23 {"match_count":1036} [loadgen] 2022/07/14 15:01:23 query 'friend': matched 1036 [loadgen] 2022/07/14 15:01:28 query 'tear': matched 463 ...
Şimdi de tüm aralıkların Cloud Trace'e doğru şekilde gönderilip gönderilmediğini onaylayalım. Cloud Console'a erişip "İz listesi"ne gidin. Bu özelliğe arama kutusundan kolayca erişebilirsiniz. Aksi takdirde, sol bölmedeki menüyü tıklayabilirsiniz. .
Sonra, gecikme grafiğinde çok sayıda mavi noktanın dağılımını görüyorsunuz. Her nokta tek bir izi temsil eder.
Bunlardan birini tıkladığınızda iz içindeki ayrıntıları görebilirsiniz. .
Bu basit hızlı bakışta bile birçok bilgiyi zaten biliyorsunuz. Örneğin, şelale grafiğinden, gecikmenin çoğunlukla shakesapp.ShakespeareService/GetMatchCount
adlı aralıktan kaynaklandığını görebilirsiniz. (Yukarıdaki resimde 1'e bakın) Bunu özet tablosundan doğrulayabilirsiniz. (En sağdaki sütun, her aralığın süresini gösterir.) Ayrıca bu iz, "arkadaş" sorgusu içindi. (Yukarıdaki resimde 2. öğeye bakın.)
Bu kısa analizler ışığında, GetMatchCount
yönteminde daha ayrıntılı aralıkları bilmeniz gerektiğini fark edebilirsiniz. Stdout bilgilerine kıyasla görselleştirme güçlüdür. Cloud Trace ayrıntıları hakkında daha fazla bilgi edinmek için lütfen resmi belgelerimizi inceleyin.
Özet
Bu adımda, stdout dışa aktarıcısını Cloud Trace One ile ve Cloud Trace'te görselleştirilmiş izlerle değiştirdiniz. Ayrıca izleri analiz etmeye nasıl başlayacağınızı da öğrendiniz.
Sonraki bölüm
Sonraki adımda, GetMatchCount'a bir alt kapsam eklemek için sunucu hizmetinin kaynak kodunu değiştireceksiniz.
7. Daha iyi analiz için alt aralık ekleyin
Bir önceki adımda, loadgen'de gözlemlenen gidiş dönüş süresinin nedeninin, çoğunlukla sunucu hizmetindeki gRPC işleyici olan GetMatchCount yöntemindeki süreç olduğunu gördünüz. Ancak işleyici dışında herhangi bir araç kullanmadığımız için şelale grafiğinden daha fazla bilgi elde edemiyoruz. Bu, mikro hizmetler için enstrümantasyona başladığımız yaygın bir durumdur.
Bu bölümde, sunucunun Google Cloud Storage'ı çağırdığı bir alt alanı ayarlayacağız. Bunun nedeni, bazı harici ağ G/Ç'lerinin sürecin uzun sürdüğü ve bunun nedeninin çağrı olup olmadığının belirlenmesidir.
Sunucuda bir alt aralık kullanma
Sunucuda main.go
öğesini açın ve readFiles
işlevini bulun. Bu işlev, Shakespeare eserlerinin tüm metin dosyalarını getirmek için Google Cloud Storage'a istek çağırıyor. Bu işlevde, istemci hizmetinde HTTP sunucu enstrümantasyonu için yaptığınız gibi bir alt aralık oluşturabilirsiniz.
step0/src/server/main.go
func readFiles(ctx context.Context, bucketName, prefix string) ([]string, error) { type resp struct { s string err error } // step4: add an extra span span := trace.SpanFromContext(ctx) span.SetName("server.readFiles") span.SetAttributes(attribute.Key("bucketname").String(bucketName)) defer span.End() // step4: end add span ...
Yeni bir kapsam eklemek için hepsi bu. Uygulamayı çalıştırarak bunun nasıl gittiğine bakalım.
Mikro hizmeti çalıştırıp izini onaylayın
Düzenlemeden sonra kümeyi skaffold komutuyla normal şekilde çalıştırın.
skaffold dev
Ayrıca iz listesinden query.request
adlı bir iz seçin. shakesapp.ShakespeareService/GetMatchCount
altındaki yeni aralık haricinde benzer bir iz şelale grafiği göreceksiniz. (Aşağıda kırmızı bir dikdörtgenle çevrili aralık)
Bu grafikten, Google Cloud Storage'a yapılan harici çağrının büyük miktarda gecikme yaşamasına rağmen gecikmenin büyük kısmını oluşturan başka unsurlar olduğunu söyleyebilirsiniz.
Sadece iz şelale grafiğindeki birkaç bakış açısıyla birçok bilgi edindiniz. Başvurunuzdaki performansla ilgili diğer ayrıntıları nasıl edinebilirsiniz? Profil oluşturucu devreye girer ancak şimdilik bu codelab'in sonunu getirelim ve tüm profil oluşturucu eğiticilerini 2. bölüme ayıralım.
Özet
Bu adımda, sunucu hizmetinde başka bir aralığı uyguladınız ve sistem gecikmesiyle ilgili daha ayrıntılı analizler elde ettiniz.
8. Tebrikler
OpenTelemery ile dağıtılmış izleri başarıyla oluşturdunuz ve Google Cloud Trace'te mikro hizmetteki istek gecikmelerini onayladınız.
Genişletilmiş egzersizler için aşağıdaki konuları kendiniz deneyebilirsiniz.
- Mevcut uygulama, durum denetimi tarafından oluşturulan tüm aralıkları gönderir. (
grpc.health.v1.Health/Check
) Bu aralıkları Cloud Traces'te nasıl filtrelersiniz? İpucuna buradan ulaşabilirsiniz. - Olay günlüklerini aralıklarla ilişkilendirin ve Google Cloud Trace ve Google Cloud Logging'de nasıl çalıştığını öğrenin. İpucuna buradan ulaşabilirsiniz.
- Bazı hizmetleri başka bir dildeki bir hizmetle değiştirin ve söz konusu dil için OpenTelemetry ile enstrümantasyon yöntemini kullanmayı deneyin.
Ayrıca, bundan sonra profil oluşturucu hakkında daha fazla bilgi edinmek isterseniz lütfen 2. bölüme geçin. Bu durumda, aşağıdaki temizleme bölümünü atlayabilirsiniz.
Temizleme
Bu codelab'den sonra Google Kubernetes Engine, Google Cloud Trace ve Google Artifact Registry'de beklenmedik ücretlerle karşılaşmamak için lütfen Kubernetes kümesini durdurun ve projeyi sildiğinizden emin olun.
İlk olarak kümeyi silin. Kümeyi skaffold dev
ile çalıştırıyorsanız Ctrl-C tuşlarına basmanız yeterlidir. Kümeyi skaffold run
ile çalıştırıyorsanız aşağıdaki komutu çalıştırın:
skaffold delete
Komut çıkışı
Cleaning up... - deployment.apps "clientservice" deleted - service "clientservice" deleted - deployment.apps "loadgen" deleted - deployment.apps "serverservice" deleted - service "serverservice" deleted
Kümeyi sildikten sonra menü bölmesinden "IAM ve Yönetici" > "Ayarlar"ı, ardından "KAPALI"yı tıklayın. düğmesini tıklayın.
Ardından iletişim kutusundaki forma Proje Kimliği'ni (Proje Adı'nı değil) girin ve kapatmayı onaylayın.