المراقبة في Go: التتبع، المقاييس والسجلات للمحترفين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

تطبيقك يعمل، لكن هل أنت متأكد أنك تعرف ما بداخله؟

\n\n

تخيل: لقد قمت بتشغيل خدمة مصغرة بلغة Go في بيئة الإنتاج. إنها لا تتعطل، ولا تنتج أخطاء 500، لكن المستخدمين يشكون من أن الصفحة تتحمّل "ببطء نوعًا ما". تذهب إلى المراقبة — استخدام وحدة المعالجة المركزية 30%، الذاكرة طبيعية. ماذا تفعل؟ بدون المراقبة في Go أنت كقبطان سفينة بدون خريطة وبوصلة.

\n\n

المراقبة (Observability) ليست مجرد "سجلات". إنها ثلاث ركائز: التتبع، المقاييس والسجلات. معًا يمنحونك قوة خارقة: فهم ما يحدث في النظام، حتى لو لم تكن تتوقع مشكلة. في هذه المقالة سنشرح كل جانب من هذه الجوانب مع أمثلة على الكود بلغة Go. لن تقرأ النظرية فقط — بل ستحصل على وصفات جاهزة يمكنك تطبيقها اليوم.

\n\n

لماذا Go هي اللغة المثالية للمراقبة؟

\n\n

تم إنشاء Go لأنظمة الخلفية حيث الأداء والموثوقية مهمان. المكتبة القياسية (net/http، database/sql) قادرة بالفعل على تقديم المقاييس ودعم السياقات للتتبع. والنظام البيئي OpenTelemetry Go و Prometheus Go يجعل تطبيق المراقبة بسيطًا وأنيقًا.

\n\n

لكن الشيء الرئيسي — في Go لا يوجد "سحر". أنت تكتب كودًا يمكن قياسه وتتبعه وتسجيله دون ألم. دعونا نرى كيف يتم ذلك.

\n\n

التتبع في Go: OpenTelemetry في العمل

\n\n

التتبع (Tracing) هو قصة طلب واحد من دخوله إلى النظام حتى خروجه. يظهر كم من الوقت استغرق كل خطوة: طلب إلى قاعدة البيانات، استدعاء API خارجي، معالجة البيانات. في Go، يُبنى التتبع على السياقات (context.Context).

\n\n

إعداد OpenTelemetry SDK

\n\n

لنقم بتثبيت الحزم:

\n
go get go.opentelemetry.io/otel \\\n  go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp \\\n  go.opentelemetry.io/otel/sdk/trace
\n\n

الآن لنقم بتهيئة المتتبع:

\n\n
package main\n\nimport (\n    "context"\n    "log"\n    "go.opentelemetry.io/otel"\n    "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"\n    "go.opentelemetry.io/otel/sdk/trace"\n)\n\nfunc initTracer() {\n    exporter, err := otlptracehttp.New(context.Background())\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    tp := trace.NewTracerProvider(\n        trace.WithBatcher(exporter),\n        trace.WithSampler(trace.AlwaysSample()),\n    )\n    otel.SetTracerProvider(tp)\n}
\n\n

إنشاء سبان (span) في معالج HTTP

\n\n

هذا ما يبدو عليه التتبع في الكود الحقيقي:

\n\n
func userHandler(w http.ResponseWriter, r *http.Request) {\n    tracer := otel.Tracer("user-service")\n    ctx, span := tracer.Start(r.Context(), "getUser")\n    defer span.End()\n\n    // محاكاة طلب إلى قاعدة البيانات\n    user, err := getUserFromDB(ctx, r.URL.Query().Get("id"))\n    if err != nil {\n        span.RecordError(err)\n        span.SetStatus(codes.Error, err.Error())\n        http.Error(w, err.Error(), 500)\n        return\n    }\n\n    span.SetAttributes(\n        attribute.String("user.id", user.ID),\n        attribute.Int64("user.age", int64(user.Age)),\n    )\n\n    // سبان متداخل لاستدعاء خارجي\n    _, childSpan := tracer.Start(ctx, "callAnalyticsAPI")\n    defer childSpan.End()\n\n    callAnalyticsAPI(user)\n    \n    w.Write([]byte("OK"))\n}
\n\n

كل سبان يحتوي على اسم، وقت البدء والانتهاء، سمات وحالة. في Jaeger أو Grafana Tempo سترى خريطة كاملة للطلب.

\n\n

نصيحة عملية

\n

لا تنسَ تمرير السياق عبر التطبيق بأكمله. في Go يتم ذلك تلقائيًا إذا كنت تستخدم context.Context في تواقيع الدوال. OpenTelemetry Go سيلتقط السياق تلقائيًا من طلب HTTP إذا كنت تستخدم middleware.

\n\n

المقاييس: Prometheus والتصدير في Go

\n\n

المقاييس هي أرقام تخبر عن حالة النظام: RPS، زمن الاستجابة، عدد الأخطاء، استخدا

المدونات

توصيات الكتب