القياس عن بعد
ADK-Rust يوفر قابلية ملاحظة على مستوى الإنتاج من خلال adk-telemetry crate، الذي يدمج التسجيل المنظم والتتبع الموزع باستخدام tracing النظام البيئي و OpenTelemetry.
نظرة عامة
يتيح نظام القياس عن بعد ما يلي:
- التسجيل المنظم: سجلات غنية وقابلة للاستعلام بمعلومات سياقية
- التتبع الموزع: تتبع الطلبات عبر التسلسلات الهرمية للوكلاء وحدود الخدمة
- تكامل OpenTelemetry: تصدير التتبعات إلى الواجهات الخلفية للمراقبة (Jaeger, Datadog, Honeycomb، إلخ.)
- نشر السياق التلقائي: تتدفق معرفات الجلسة والمستخدم والاستدعاء عبر جميع العمليات
- النطاقات المكونة مسبقًا: وظائف مساعدة لعمليات ADK الشائعة
بدء سريع
تسجيل الدخول الأساسي للوحدة الطرفية
للتطوير وعمليات النشر البسيطة، قم بتهيئة تسجيل الدخول للوحدة الطرفية:
use adk_telemetry::init_telemetry;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize telemetry with your service name
init_telemetry("my-agent-service")?;
// Your agent code here
Ok(())
}
يقوم هذا بتكوين التسجيل المنظم إلى stdout بإعدادات افتراضية معقولة.
تصدير OpenTelemetry
لعمليات النشر الإنتاجية مع التتبع الموزع:
use adk_telemetry::init_with_otlp;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize with OTLP exporter
init_with_otlp("my-agent-service", "http://localhost:4317")?;
// Your agent code here
// Flush traces before exit
adk_telemetry::shutdown_telemetry();
Ok(())
}
يقوم هذا بتصدير التتبعات والمقاييس إلى نقطة نهاية مجمع OpenTelemetry.
طبقة قابلة للتركيب (متقدم)
إذا كان لديك بالفعل مشترك tracing مكون، استخدم build_otlp_layer للحصول على طبقة قابلة للتركيب بدلاً من تهيئة مشترك عام:
use adk_telemetry::build_otlp_layer;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
let otlp_layer = build_otlp_layer("my-agent", "http://localhost:4317")?;
tracing_subscriber::registry()
.with(otlp_layer)
.with(tracing_subscriber::fmt::layer())
.init();
مستويات السجل
تحكم في تفاصيل التسجيل باستخدام متغير البيئة RUST_LOG:
| المستوى | الوصف | حالة الاستخدام |
|---|---|---|
error | الأخطاء فقط | الإنتاج (الحد الأدنى) |
warn | التحذيرات والأخطاء | الإنتاج (الافتراضي) |
info | الرسائل المعلوماتية | التطوير، التدريج |
debug | معلومات تصحيح الأخطاء التفصيلية | التطوير المحلي |
trace | تتبع مفصل للغاية | تصحيح الأخطاء العميق |
تحديد مستويات السجل
# Set global log level
export RUST_LOG=info
# Set per-module log levels
export RUST_LOG=adk_agent=debug,adk_model=info
# Combine global and module-specific levels
export RUST_LOG=warn,adk_agent=debug
يستخدم نظام القياس عن بعد المستوى info افتراضيًا إذا لم يتم تعيين RUST_LOG.
وحدات الماكرو للتسجيل
استخدم وحدات الماكرو tracing القياسية للتسجيل:
use adk_telemetry::{trace, debug, info, warn, error};
// Informational logging
info!("Agent started successfully");
// Structured logging with fields
info!(
agent.name = "my_agent",
session.id = "sess-123",
"Processing user request"
);
// Debug logging
debug!(user_input = ?input, "Received input");
// Warning and error logging
warn!("Rate limit approaching");
error!(error = ?err, "Failed to call model");
الحقول المهيكلة
أضف حقولًا سياقية إلى رسائل السجل لتحسين التصفية والتحليل:
use adk_telemetry::info;
info!(
agent.name = "customer_support",
user.id = "user-456",
session.id = "sess-789",
invocation.id = "inv-abc",
"Agent execution started"
);
تصبح هذه الحقول قابلة للاستعلام في الواجهة الخلفية للمراقبة الخاصة بك.
الأجهزة
الأجهزة التلقائية
استخدم السمة #[instrument] لإنشاء نطاقات تلقائيًا للدوال:
use adk_telemetry::{instrument, info};
#[instrument]
async fn process_request(user_id: &str, message: &str) {
info!("Processing request");
// Function logic here
}
// Creates a span named "process_request" with user_id and message as fields
تخطي المعلمات الحساسة
استبعد البيانات الحساسة من التتبعات:
use adk_telemetry::instrument;
#[instrument(skip(api_key))]
async fn call_external_api(api_key: &str, query: &str) {
// api_key won't appear in traces
}
أسماء النطاقات المخصصة
use adk_telemetry::instrument;
#[instrument(name = "external_api_call")]
async fn fetch_data(url: &str) {
// Span will be named "external_api_call" instead of "fetch_data"
}
النطاقات المكونة مسبقًا
يوفر ADK-Telemetry دوال مساعدة للعمليات الشائعة:
نطاق تنفيذ Agent
use adk_telemetry::agent_run_span;
let span = agent_run_span("my_agent", "inv-123");
let _enter = span.enter();
// Agent execution code here
// All logs within this scope inherit the span context
نطاق استدعاء النموذج
use adk_telemetry::model_call_span;
let span = model_call_span("gemini-2.5-flash");
let _enter = span.enter();
// Model API call here
نطاق تنفيذ Tool
use adk_telemetry::tool_execute_span;
let span = tool_execute_span("weather_tool");
let _enter = span.enter();
// Tool execution code here
نطاق رد الاتصال
use adk_telemetry::callback_span;
let span = callback_span("before_model");
let _enter = span.enter();
// Callback logic here
إضافة سمات السياق
أضف سياق المستخدم والجلسة إلى النطاق الحالي:
use adk_telemetry::add_context_attributes;
add_context_attributes("user-456", "sess-789");
تتبع استخدام الرمز المميز LLM
تتبع استهلاك الرمز المميز عبر جميع موفري LLM باستخدام الاصطلاحات الدلالية OpenTelemetry GenAI. ينشئ llm_generate_span نطاقًا بحقول gen_ai.usage.* معلنة مسبقًا، ويقوم record_llm_usage بتعبئتها بعد وصول الاستجابة:
use adk_telemetry::{llm_generate_span, record_llm_usage, LlmUsage};
let span = llm_generate_span("openai", "gpt-5-mini", true);
let _enter = span.enter();
// After receiving the LLM response with usage metadata:
record_llm_usage(&LlmUsage {
input_tokens: 100,
output_tokens: 50,
total_tokens: 150,
cache_read_tokens: Some(80),
..Default::default()
});
تقوم جميع موفري نماذج ADK (Gemini, OpenAI, Anthropic, Ollama, Bedrock, DeepSeek, Groq, Azure AI, وجميع الموفرين المتوافقين مع OpenAI) بتسجيل استخدام الرمز المميز تلقائيًا في كل استدعاء generate_content. لا يلزم أي أجهزة يدوية — يتم تضمين التتبع في طبقة الموفر.
تتبع حقول النطاق المسجلة اصطلاحات OpenTelemetry GenAI:
| الحقل | الوصف |
|---|---|
gen_ai.usage.input_tokens | عدد رموز الموجه / الإدخال |
gen_ai.usage.output_tokens | عدد رموز الإكمال / الإخراج |
gen_ai.usage.total_tokens | إجمالي عدد الرموز |
gen_ai.usage.cache_read_tokens | الرموز المقروءة من ذاكرة التخزين المؤقت للموجه |
gen_ai.usage.cache_creation_tokens | الرموز المستخدمة لإنشاء ذاكرة التخزين المؤقت |
gen_ai.usage.thinking_tokens | رموز التفكير المتسلسل |
gen_ai.usage.audio_input_tokens | عدد رموز الإدخال الصوتية |
gen_ai.usage.audio_output_tokens | عدد رموز الإخراج الصوتية |
يتم تسجيل الحقول الاختيارية فقط عندما يقوم المزود بالإبلاغ عنها (غير None).
إنشاء Span يدويًا
لأغراض القياس المخصص، قم بإنشاء spans يدويًا:
use adk_telemetry::{info, Span};
let span = tracing::info_span!(
"custom_operation",
operation.type = "data_processing",
operation.id = "op-123"
);
let _enter = span.enter();
info!("Performing custom operation");
// Operation code here
سمات Span
أضف السمات ديناميكيًا:
use adk_telemetry::Span;
let span = Span::current();
span.record("result.count", 42);
span.record("result.status", "success");
إعداد OpenTelemetry
نقطة نهاية OTLP
يقوم مُصدّر OTLP بإرسال التتبعات إلى نقطة نهاية المجمّع:
use adk_telemetry::init_with_otlp;
// Local Jaeger (default OTLP port)
init_with_otlp("my-service", "http://localhost:4317")?;
// Cloud provider endpoint
init_with_otlp("my-service", "https://otlp.example.com:4317")?;
تشغيل مجمّع محلي
للتطوير، قم بتشغيل Jaeger مع دعم OTLP:
docker run -d --name jaeger \
-p 4317:4317 \
-p 16686:16686 \
jaegertracing/all-in-one:latest
# View traces at http://localhost:16686
تصور التتبع
بمجرد التكوين، تظهر التتبعات في الواجهة الخلفية للمراقبة لديك لتوضح:
- التسلسل الهرمي لتنفيذ Agent
- زمن استجابة استدعاءات Model
- توقيت تنفيذ Tool
- انتشار الأخطاء
- تدفق السياق (معرف المستخدم، معرف الجلسة، إلخ.)
التكامل مع ADK
تقوم مكونات ADK-Rust تلقائيًا بإصدار بيانات القياس عن بعد عند تهيئة نظام القياس عن بعد:
use adk_rust::prelude::*;
use adk_telemetry::init_telemetry;
use std::sync::Arc;
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
// Initialize telemetry first
init_telemetry("my-agent-app")?;
let api_key = std::env::var("GOOGLE_API_KEY")?;
let model = Arc::new(GeminiModel::new(&api_key, "gemini-2.5-flash")?);
let agent = LlmAgentBuilder::new("support_agent")
.model(model)
.instruction("You are a helpful support agent.")
.build()?;
// Use Launcher for simple execution
Launcher::new(Arc::new(agent)).run().await?;
Ok(())
}
ستقوم عمليات Agent و Model و Tool تلقائيًا بإصدار سجلات وتتبعات منظمة.
مثال توضيحي للقياس عن بعد
تحقق من اختيار ميزة القياس عن بعد محليًا:
cargo check -p adk-telemetry --no-default-features
cargo check -p adk-telemetry --no-default-features --features otlp
افتح ADK-Rust Playground المضمّن للاطلاع على أمثلة قياس عن بعد كاملة مع استدعاءات حقيقية للنماذج.
القياس عن بعد المخصص في Tools
أضف القياس عن بعد إلى الأدوات المخصصة:
use adk_rust::prelude::*;
use adk_telemetry::{info, instrument, tool_execute_span};
use serde_json::{json, Value};
#[instrument(skip(ctx))]
async fn weather_tool_impl(
ctx: Arc<dyn ToolContext>,
args: Value,
) -> Result<Value> {
let span = tool_execute_span("weather_tool");
let _enter = span.enter();
let location = args["location"].as_str().unwrap_or("unknown");
info!(location = location, "Fetching weather data");
// Tool logic here
let result = json!({
"temperature": 72,
"condition": "sunny"
});
info!(location = location, "Weather data retrieved");
Ok(result)
}
let weather_tool = FunctionTool::new(
"get_weather",
"Get current weather for a location",
json!({
"type": "object",
"properties": {
"location": {"type": "string"}
},
"required": ["location"]
}),
weather_tool_impl,
);
القياس عن بعد المخصص في Callbacks
أضف قابلية المراقبة إلى Callbacks:
use adk_rust::prelude::*;
use adk_telemetry::{info, callback_span};
use std::sync::Arc;
let agent = LlmAgentBuilder::new("observed_agent")
.model(model)
.before_callback(Box::new(|ctx| {
Box::pin(async move {
let span = callback_span("before_agent");
let _enter = span.enter();
info!(
agent.name = ctx.agent_name(),
user.id = ctx.user_id(),
session.id = ctx.session_id(),
"Agent execution starting"
);
Ok(None)
})
}))
.after_callback(Box::new(|ctx| {
Box::pin(async move {
let span = callback_span("after_agent");
let _enter = span.enter();
info!(
agent.name = ctx.agent_name(),
"Agent execution completed"
);
Ok(None)
})
}))
.build()?;
اعتبارات الأداء
أخذ العينات
بالنسبة للأنظمة عالية الإنتاجية، ضع في اعتبارك أخذ عينات التتبع:
// Note: Sampling configuration depends on your OpenTelemetry setup
// Configure sampling in your OTLP collector or backend
Async Spans
استخدم دائمًا #[instrument] على الدوال async لضمان سياق span صحيح:
use adk_telemetry::instrument;
// ✅ Correct - span context preserved across await points
#[instrument]
async fn async_operation() {
tokio::time::sleep(Duration::from_secs(1)).await;
}
// ❌ Incorrect - manual span may lose context
async fn manual_span_operation() {
let span = tracing::info_span!("operation");
let _enter = span.enter();
tokio::time::sleep(Duration::from_secs(1)).await;
// Context may be lost after await
}
مستوى السجل في الإنتاج
استخدم مستوى info أو warn في الإنتاج لتقليل الحمل الزائد:
export RUST_LOG=warn,my_app=info
استكشاف الأخطاء وإصلاحها
عدم ظهور السجلات
- تحقق من تعيين متغير البيئة
RUST_LOG - تأكد من استدعاء
init_telemetry()قبل أي تسجيل - تحقق من تهيئة القياس عن بعد مرة واحدة فقط (يستخدم
Onceداخليًا)
عدم تصدير التتبعات
- تحقق من إمكانية الوصول إلى نقطة نهاية OTLP
- تحقق من أن المجمّع يعمل ويقبل الاتصالات
- استدعِ
shutdown_telemetry()قبل خروج التطبيق لتفريغ spans المعلقة - تحقق من وجود مشكلات في الشبكة/جدار الحماية
سياق مفقود في Spans
- استخدم
#[instrument]على الدوال async - تأكد من إدخال spans باستخدام
let _enter = span.enter() - حافظ على حارس
_enterضمن النطاق طوال مدة العملية
أفضل الممارسات
- التهيئة المبكرة: استدعِ
init_telemetry()في بدايةmain() - استخدام الحقول المنظمة: أضف السياق باستخدام أزواج المفتاح-القيمة، وليس استيفاء السلسلة
- قياس الدوال Async: استخدم دائمًا
#[instrument]على الدوال async - التفريغ عند الخروج: استدعِ
shutdown_telemetry()قبل إنهاء التطبيق - مستويات السجل المناسبة: استخدم
infoللأحداث الهامة، وdebugللتفاصيل - تجنب البيانات الحساسة: تخطى المعلمات الحساسة باستخدام
#[instrument(skip(...))] - تسمية متسقة: استخدم أسماء حقول متسقة (على سبيل المثال،
user.id،session.id)
ذات صلة
- Callbacks - أضف القياس عن بعد إلى Callbacks
- Tools - قم بقياس الأدوات المخصصة
- Deployment - إعداد القياس عن بعد للإنتاج
السابق: ← الأحداث | التالي: Launcher →