Ansluter Go Profilering Med Spårning · Felix Geisendörfer

Ansluter Go Profilering Med Spårning · Felix Geisendörfer


Ansluter Go Profilering Med Spårning · Felix Geisendörfer

Publicerad:

Idag skulle jag vilja dela med mig av några tankar om några nya profileringsfunktioner som vi nyligen levererade hos Datadog. Jag ska förklara vad de gör, hur de fungerar och vilka Go 1.18-bidrag som behövdes för att saker och ting skulle fungera bra.

Feature Showcase

Låt oss börja med slutresultatet. Föreställ dig att du har ett spår på 100 ms där 10 ms spenderas på en databasfråga, men 90 ms förblir oförklarade.

När detta händer behöver du vanligtvis studera din kod för ledtrådar. Har du glömt några spårningsinstrument? Dags att lägga till det, distribuera om och vänta. Eller kanske du behöver optimera din Go-kod? Om ja, hur?

Detta arbetsflöde är hanterbart, men det visar sig att det finns ett bättre sätt – vi kan använda profileringsdata för att fylla i luckorna. Och det är precis vad vår nya Code Hotspots-funktion gör. Som du kan se nedan använde vår begäran 90ms On-CPU-tid. Detta är en stark signal som låter oss utesluta off-CPU-aktivitet som oinstrumenterade servicesamtal, mutex-konflikter, kanalväntningar, sovande etc.

Ännu bättre, när vi klickar på knappen “Visa profil”, kan vi se denna On-CPU-tid som ett flamdiagram per begäran. Här kan vi se att vår tid ägnades åt JSON-kodning.

Och eftersom våra HTTP-hanterarfunktioner inte visas i stackspåren, kan vi också indirekt dra slutsatsen att detta arbete gjordes i en bakgrundsgoroutin som skapades av den goroutine som hanterade begäran.

Förutom att bryta ned spårningsinformation med hjälp av profilering kan vi också göra tvärtom och bryta ner en profils CPU-tid efter slutpunkt som visas nedan. Kryssrutorna kan användas för att filtrera profilen efter slutpunkt.

Och för att göra det lättare att förstå förändringar över tid, t.ex. efter en implementering, kan vi rita upp dessa data.

Hur det fungerar

Funktionerna är byggda ovanpå en befintlig Go-funktion som kallas pprof-etiketter som gör att vi kan koppla godtyckliga nyckel/värdepar till den för närvarande pågående goroutinen. Dessa etiketter ärvas automatiskt när en ny goroutin skapas, så de når in i alla hörn av din kod. Av avgörande betydelse är dessa etiketter också integrerade i CPU-profilern, så att de automatiskt hamnar i de CPU-profiler som den producerar.

Så för att implementera den här funktionen modifierade vi spårningskoden i vårt dd-trace-go-bibliotek för att automatiskt tillämpa etiketter som t.ex. span id och endpoint när ett nytt spann skapas. Dessutom tar vi bort etiketterna när spännet är klart. Ett förenklat exempel på denna implementering kan ses nedan:

func StartSpan(ctx context.Context, endpoint string) *span {
	span := &span{id: rand.Uint64(), restoreCtx: ctx}
	labels := pprof.Labels(
		"span_id", fmt.Sprintf("%d", span.id),
		"endpoint", endpoint,
	)
	pprof.SetGoroutineLabels(pprof.WithLabels(ctx, labels))
	return span
}

type span struct {
	id         uint64
	restoreCtx context.Context
}

func (s *span) Finish() {
	pprof.SetGoroutineLabels(s.restoreCtx)
}

Vår faktiska implementering är lite mer komplex och minskar även risken för att läcka PII (Personally Identifiable Information). Den täcker automatiskt HTTP- och gRPC-omslagen i vårt bidragspaket, såväl som alla anpassade spår som din applikation kan implementera.

När vår backend väl tar emot spårnings- och profileringsinformationen kan vi utföra de sökningar som behövs för att driva funktionerna som visades upp tidigare i det här inlägget.

Profileringsförbättringar i Go 1.18

Som en del av implementeringen av dessa nya funktioner gjorde vi en hel del tester, inklusive enhetstester, mikrobenchmarks, makrobenchmarks och mer. Som väntat dök detta upp problem i vår kod och gjorde det möjligt för oss att snabbt fixa dem.

Något mindre förväntat upptäckte vi också flera problem i Go-körningstiden som påverkade pprof-etiketternas noggrannhet, såväl som CPU-profilering i allmänhet. Den goda nyheten är att med hjälp av communityn, Go-underhållarna och bidrag från vår sida – alla dessa problem har åtgärdats i den kommande Go 1.18-versionen.

Om du är intresserad av alla detaljer om detta, kolla in det kompletterande inlägget: Profiling Improvements in Go 1.18.

Med det sagt, om du inte använder mycket cgo borde de nya funktionerna redan fungera utmärkt för dig i Go 1.17.

Feedback önskas

Jag letar just nu efter personer som är intresserade av att ta de här nya funktionerna en sväng för att få feedback.

Det spelar ingen roll om du är en befintlig eller potentiell kund, skicka bara ett mejl till mig så kan vi ställa in en 30 min zoom. För att söta affären svarar jag också gärna på allmänna Go-profileringsfrågor längs vägen :).

Bilaga: Komma igång

Om du vill komma igång snabbt kan du helt enkelt kopiera koden nedan till din ansökan.

Dessutom kan du kolla in denna fullt fungerande dd-trace-go-demo-applikation som visar en integration inklusive HTTP och PostgreSQL.

package main

import (
	"time"

	"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
	"gopkg.in/DataDog/dd-trace-go.v1/profiler"
)

func main() {
	const (
		env     = "dev"
		service = "example"
		version = "0.1"
	)

	tracer.Start(
		tracer.WithEnv(env),
		tracer.WithService(service),
		tracer.WithServiceVersion(version),
		tracer.WithProfilerCodeHotspots(true),
		tracer.WithProfilerEndpoints(true),
	)
	defer tracer.Stop()

	err := profiler.Start(
		profiler.WithService(service),
		profiler.WithEnv(env),
		profiler.WithVersion(version),

		// Enables CPU profiling 100% of the time to capture hotspot information
		// for all spans. Default is 25% right now, but this might change in the
		// next dd-trace-go release.
		profiler.CPUDuration(60*time.Second),
		profiler.WithPeriod(60*time.Second),
	)
	if err != nil {
		panic(err)
	}
	defer profiler.Stop()

	// 
}

Tack till min kollega Nick Ripley för att han recenserade det här inlägget.

— Felix Geisendörfer


Prenumerera på denna blogg via RSS eller E-post eller få små uppdateringar från mig via Kvittra.





Source link

Postagens Similares

  • Тихі поєдинки — Побудова рішення, частина 2 || Математика ∩ Програмування

    Попередні публікації в цій серії: Тихі поєдинки та старий папір Restrepo. Тихі поєдинки — Розбір конструкції. Тихі поєдинки — Побудова рішення, частина 1 Відколи це було три роки з останнього допису в цій серії, і причина затримки полягає в тому, що я повністю застряг на реалізації. Я публікую цю чернетку статті як частковий прогрес, поки…

  • Перестаньте объяснять, что это такое

    📅 05 ноября 2025 г. | ⏱️ ~1 минута чтения Вы когда-нибудь искали решение технической проблемы только для того, чтобы получить эссе на 1000 слов о том, в чем дело? Да, я тоже. Вы знаете упражнение. Ты Google «как исправить конфликт Git»и каждый результат занимает пять абзацев, объясняющих, что такое Git. Приятель, я здесь, потому…

  • sphinxcontrib-sqltable 2.1.0 – SQLAlchemy 2.0 支持 · Doug Hellmann

    2024 年 5 月 5 日 sphinxcontrib-sqltable 是一个 Sphinx 扩展,允许作者在源文档中嵌入 SQL 语句并在呈现的文档中生成表格输出。 项目详情 2.1.0 是 PyPI 2.1.0 有什么新功能? 更新包装以使用 pyproject.toml 更新 sqltable.py 以支持 SQLAlchemy 2.0(Gabriel Gaona 贡献) 固定 SQLAlchemy>=2.0 以防止因查询执行接口的更改而向后不兼容。 (加布里埃尔·高纳供稿) 修复python版本支持列表 修复 bitbucket 的过时链接(kbaikov 贡献) 根据 sphinx 的调用方式查找示例架构文件 将 rtd.org 的示例数据库移至 /tmp Source link

  • Насправді структуроване журналювання (січень 2025 р.)

    Я був дуже схвильований, коли побачив епізод Кела Ньюпорта на Structured Journaling, але я був розчарований рекомендаціями: Щодня: фіксуйте все, що вам подобається/бачите/думаєте/відчуєте, на молескейн, який ви носите з собою Щомісяця: дистиль з молескеїну Щороку (жовтень) обдумуйте вивчене та будуйте нові особисті наративи/цілі Це не зовсім та структура, яку я хочу у своєму житті. Ведення…

  • டிம் ஆப்பிள் மீது டிரம்ப்

    அமெரிக்காவின் ஜனாதிபதி, இன்று காலை தனது வலைப்பதிவில் (அனைத்து மூலதனம், நிறுத்தற்குறிகள் மற்றும் விடுபட்ட/தவறான சொற்கள் வினைச்சொல்): நான் எப்பொழுதும் டிம் குக்கின் பெரிய ரசிகனாக இருந்தேன், அதே போல் ஸ்டீவ் ஜாப்ஸ், ஆனால் ஸ்டீவ், பிளானட் எர்த்தில் இருந்து மிகவும் இளமையாக எடுக்கப்படாமல், டிம்மிற்குப் பதிலாக நிறுவனத்தை நடத்தாமல் இருந்திருந்தால், அந்த நிறுவனம் சிறப்பாகச் செயல்பட்டிருக்கும், ஆனால் டிம் கீழ் இருந்ததைப் போல் எங்கும் இல்லை. என்னைப் பொறுத்தவரை இது எனது முதல் பதவிக்காலத்தின் தொடக்கத்தில்…

  • पृथ्वीवरील सर्वात सुंदर जागा

    दक्षिण आफ्रिकेत एक अशी जागा आहे जिथे एक मोठी नदी असंख्य वाहिन्यांमध्ये विभागली जाते, एक मोठी आणि अनेक लहान. हे असे करते कारण नदीच्या खोऱ्यात जवळजवळ कोणताही गाळ नाही, फक्त खडक आहे, जसे की दक्षिण आफ्रिकेच्या बऱ्याच भागांमध्ये आहे, म्हणून जेव्हा नदीला पूर येतो तेव्हा पाणी सर्वत्र पसरते आणि मऊ चिखलयुक्त पूर मैदाने असलेल्या नद्यांप्रमाणे…

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *