टेलीमेट्री
ADK-Rust, adk-telemetry crate के माध्यम से उत्पादन-ग्रेड अवलोकन क्षमता प्रदान करता है, जो tracing इकोसिस्टम और OpenTelemetry का उपयोग करके संरचित लॉगिंग और डिस्ट्रीब्यूटेड ट्रेसिंग को एकीकृत करता है।
अवलोकन
टेलीमेट्री सिस्टम सक्षम बनाता है:
- Structured Logging: समृद्ध, प्रासंगिक जानकारी के साथ क्वेरी योग्य लॉग
- Distributed Tracing: agent पदानुक्रम और सेवा सीमाओं में अनुरोधों को ट्रैक करें
- OpenTelemetry Integration: ट्रेस को अवलोकन बैकएंड (जैसे Jaeger, Datadog, Honeycomb) में निर्यात करें
- Automatic Context Propagation: सभी ऑपरेशनों में Session, user और invocation IDs का स्वचालित संदर्भ प्रसार
- Pre-configured Spans: सामान्य 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 कलेक्टर एंडपॉइंट पर निर्यात करता है।
लॉग स्तर
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
यदि RUST_LOG सेट नहीं है, तो टेलीमेट्री सिस्टम डिफ़ॉल्ट रूप से info स्तर पर होता है।
लॉगिंग मैक्रो
लॉगिंग के लिए मानक tracing मैक्रो का उपयोग करें:
use adk_telemetry::{trace, debug, info, warn, error};
// सूचनात्मक लॉगिंग
info!("Agent started successfully");
// फ़ील्ड के साथ संरचित लॉगिंग
info!(
agent.name = "my_agent",
session.id = "sess-123",
"Processing user request"
);
// डीबग लॉगिंग
debug!(user_input = ?input, "Received input");
// चेतावनी और त्रुटि लॉगिंग
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
}
// "user_id" और "message" फ़ील्ड के साथ "process_request" नामक एक स्पैन बनाता है।
संवेदनशील पैरामीटर छोड़ें
ट्रेस से संवेदनशील डेटा को बाहर रखें:
use adk_telemetry::instrument;
#[instrument(skip(api_key))]
async fn call_external_api(api_key: &str, query: &str) {
// api_key ट्रेस में दिखाई नहीं देगा
}
कस्टम स्पैन नाम
use adk_telemetry::instrument;
#[instrument(name = "external_api_call")]
async fn fetch_data(url: &str) {
// स्पैन का नाम "fetch_data" के बजाय "external_api_call" होगा
}
पूर्व-कॉन्फ़िगर किए गए स्पैन
ADK-Telemetry सामान्य ऑपरेशनों के लिए सहायक फ़ंक्शन प्रदान करता है:
एजेंट निष्पादन स्पैन
use adk_telemetry::agent_run_span;
let span = agent_run_span("my_agent", "inv-123");
let _enter = span.enter();
// एजेंट निष्पादन कोड यहाँ
// इस स्कोप के भीतर के सभी लॉग स्पैन संदर्भ को इनहेरिट करते हैं
मॉडल कॉल स्पैन
use adk_telemetry::model_call_span;
let span = model_call_span("gemini-2.0-flash");
let _enter = span.enter();
// मॉडल API कॉल यहाँ
टूल निष्पादन स्पैन
use adk_telemetry::tool_execute_span;
let span = tool_execute_span("weather_tool");
let _enter = span.enter();
// टूल निष्पादन कोड यहाँ
कॉलबैक स्पैन
use adk_telemetry::callback_span;
let span = callback_span("before_model");
let _enter = span.enter();
// कॉलबैक लॉजिक यहाँ
संदर्भ विशेषताएँ जोड़ना
वर्तमान स्पैन में उपयोगकर्ता और सत्र संदर्भ जोड़ें:
use adk_telemetry::add_context_attributes;
add_context_attributes("user-456", "sess-789");
मैनुअल स्पैन निर्माण
कस्टम इंस्ट्रूमेंटेशन के लिए, स्पैन मैन्युअल रूप से बनाएँ:
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");
// ऑपरेशन कोड यहाँ
स्पैन विशेषताएँ
गतिशील रूप से विशेषताएँ जोड़ें:
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;
// लोकल जेगर (डिफ़ॉल्ट OTLP पोर्ट)
init_with_otlp("my-service", "http://localhost:4317")?;
// क्लाउड प्रदाता एंडपॉइंट
init_with_otlp("my-service", "https://otlp.example.com:4317")?;
एक लोकल कलेक्टर चलाना
डेवलपमेंट के लिए, OTLP सपोर्ट के साथ जेगर चलाएँ:
docker run -d --name jaeger \
-p 4317:4317 \
-p 16686:16686 \
jaegertracing/all-in-one:latest
# ट्रेस http://localhost:16686 पर देखें
ट्रेस विज़ुअलाइज़ेशन
एक बार कॉन्फ़िगर हो जाने पर, ट्रेस आपके ऑब्जर्वेबिलिटी बैकएंड में दिखाई देते हैं, जिसमें निम्न शामिल हैं:
- एजेंट निष्पादन पदानुक्रम
- मॉडल कॉल विलंबताएँ
- टूल निष्पादन का समय
- त्रुटि प्रसार
- संदर्भ प्रवाह (उपयोगकर्ता ID, सत्र ID, आदि)
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 के ऑपरेशंस स्वचालित रूप से संरचित लॉग और ट्रेस उत्सर्जित करेंगे।
टूल्स में कस्टम टेलीमेट्री
कस्टम टूल्स में टेलीमेट्री जोड़ें:
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,
);
कॉलबैक में कस्टम टेलीमेट्री
कॉलबैक में ऑब्जर्वेबिलिटी जोड़ें:
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
एसिंक स्पैन
उचित स्पैन संदर्भ सुनिश्चित करने के लिए हमेशा एसिंक फ़ंक्शन पर #[instrument] का उपयोग करें:
use adk_telemetry::instrument;
// ✅ सही - await पॉइंट्स पर स्पैन संदर्भ संरक्षित रहता है
#[instrument]
async fn async_operation() {
tokio::time::sleep(Duration::from_secs(1)).await;
}
// ❌ गलत - मैनुअल स्पैन संदर्भ खो सकता है
async fn manual_span_operation() {
let span = tracing::info_span!("operation");
let _enter = span.enter();
tokio::time::sleep(Duration::from_secs(1)).await;
// await के बाद संदर्भ खो सकता है
}
प्रोडक्शन में लॉग स्तर
ओवरहेड कम करने के लिए प्रोडक्शन में info या warn स्तर का उपयोग करें:
export RUST_LOG=warn,my_app=info
समस्या निवारण
कोई लॉग दिखाई नहीं दे रहा
- जाँचें कि
RUST_LOGवातावरण चर सेट है - सुनिश्चित करें कि किसी भी लॉगिंग से पहले
init_telemetry()को कॉल किया गया है - सत्यापित करें कि टेलीमेट्री केवल एक बार इनिशियलाइज़ की गई है (आंतरिक रूप से
Onceका उपयोग करता है)
ट्रेस एक्सपोर्ट नहीं किए गए
- सत्यापित करें कि OTLP एंडपॉइंट पहुंच योग्य है
- जाँचें कि कलेक्टर चल रहा है और कनेक्शन स्वीकार कर रहा है
- लंबित स्पैन को फ़्लश करने के लिए एप्लिकेशन से बाहर निकलने से पहले
shutdown_telemetry()को कॉल करें - नेटवर्क/फ़ायरवॉल समस्याओं की जाँच करें
स्पैन में संदर्भ गायब है
- async फ़ंक्शन पर
#[instrument]का उपयोग करें - सुनिश्चित करें कि स्पैन
let _enter = span.enter()के साथ दर्ज किए गए हैं - ऑपरेशन की अवधि के लिए
_enterगार्ड को स्कोप में रखें
सर्वोत्तम अभ्यास
- जल्दी इनिशियलाइज़ करें:
main()के शुरू मेंinit_telemetry()को कॉल करें - संरचित फ़ील्ड का उपयोग करें: स्ट्रिंग इंटरपोलेशन के बजाय कुंजी-मूल्य युग्मों के साथ संदर्भ जोड़ें
- Async फ़ंक्शन को इंस्ट्रूमेंट करें: async फ़ंक्शन पर हमेशा
#[instrument]का उपयोग करें - बाहर निकलने पर फ़्लश करें: एप्लिकेशन समाप्ति से पहले
shutdown_telemetry()को कॉल करें - उपयुक्त लॉग स्तर: महत्वपूर्ण घटनाओं के लिए
infoका उपयोग करें, विवरण के लिएdebugका उपयोग करें - संवेदनशील डेटा से बचें:
#[instrument(skip(...))]के साथ संवेदनशील पैरामीटर छोड़ें - सुसंगत नामकरण: सुसंगत फ़ील्ड नामों का उपयोग करें (जैसे,
user.id,session.id)
संबंधित
- Callbacks - कॉलबैक में टेलीमेट्री जोड़ें
- Tools - कस्टम टूल को इंस्ट्रूमेंट करें
- Deployment - प्रोडक्शन टेलीमेट्री सेटअप
पिछला: ← Events | अगला: Launcher →