| Crates.io | gcp-observability-rs |
| lib.rs | gcp-observability-rs |
| version | 0.1.3 |
| created_at | 2025-11-09 10:33:57.600378+00 |
| updated_at | 2026-01-10 21:26:53.727604+00 |
| description | Lightweight Google Cloud Platform observability client using gcloud CLI |
| homepage | |
| repository | https://github.com/santiamoretti/gcp-observability-rs |
| max_upload_size | |
| id | 1923969 |
| size | 72,941 |
A lightweight, high-performance Google Cloud Platform observability library for Rust applications. Provides easy-to-use APIs for Cloud Logging, Cloud Monitoring, and Cloud Trace with a background worker for non-blocking operations.
This crate was devoloped by Santiago Amoretti in the context of the devlopment of Genevabm(https://genevabm.com) after facing multiple issue mainly caused by Googles inhability to provide good crates and APIS to interact with its services.
We are used to this idea of using crates to do work that, under the hood, just concist of the most simple way of communication beetween services: A plain HTTP hit. When this happens, i would argue its much better to generate your own structure than to use existing ones. Thats what i did. I figured out the JSON structures, interacted with GCP from the command line and created a single threaded model which is taylor made for microservices.
You can use what i did. You could also modify it to extend its behaviour. Maybe, youll just benefit from the idea of knowing that most of this APIS are high level and intricated for no reason, which makes a good argument for creating your own stuff.
Add this to your Cargo.toml:
[dependencies]
gcp-observability-rs = "0.1.3"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
Google Cloud Project with APIs enabled:
Service Account JSON with roles:
roles/logging.logWriterroles/monitoring.metricWriterroles/cloudtrace.agentgcloud CLI (automatically installed if missing)
The library uses a channel-based architecture for optimal performance:
βββββββββββββββ βββββββββββ ββββββββββββββββ
β Your App ββββββββββΆβ Channel ββββββββββΆβ Worker Threadβ
β (main) β queue β (1027) β process β (async ops) β
βββββββββββββββ βββββββββββ ββββββββββββββββ
β
βΌ
ββββββββββββββββ
β GCP APIs β
ββββββββββββββββ
use gcp_observability_rs::{ObservabilityClient, LogEntry, MetricData, TraceSpan};
use std::collections::HashMap;
use std::time::{SystemTime, Duration};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize client (performs authentication)
let client = ObservabilityClient::new(
"your-project-id".to_string(),
"/path/to/service-account.json".to_string(),
).await?;
// Fire-and-forget logging (returns immediately)
client.send_log(LogEntry::new("INFO", "App started"))?;
// With service name
client.send_log(
LogEntry::new("ERROR", "DB connection failed")
.with_service_name("api-server")
)?;
// Send metrics with labels
let mut labels = HashMap::new();
labels.insert("environment".to_string(), "production".to_string());
client.send_metric(
MetricData::new(
"custom.googleapis.com/requests_total",
42.0,
"INT64",
"GAUGE"
).with_labels(labels)
)?;
// Create distributed traces
let trace_id = ObservabilityClient::generate_trace_id();
let span_id = ObservabilityClient::generate_span_id();
client.send_trace(
TraceSpan::new(
trace_id,
span_id,
"HTTP Request",
SystemTime::now(),
Duration::from_millis(150)
)
)?;
Ok(())
}
When you need confirmation that an operation succeeded:
// Wait for operation to complete
client.send_log_async(LogEntry::new("INFO", "Critical log")).await?;
client.send_metric_async(MetricData::new("metric", 1.0, "INT64", "GAUGE")).await?;
client.send_trace_async(TraceSpan::new(...)).await?;
use gcp_observability_rs::{gcp_info, gcp_warn, gcp_error};
gcp_info!(client, "User {} logged in", user_id)?;
gcp_warn!(client, "High memory usage: {}%", usage)?;
gcp_error!(client, "Failed to process: {}", error)?;
new(project_id, service_account_path) β Result<Self, ObservabilityError>
send_log(log_entry: LogEntry) β Result<(), ObservabilityError>send_metric(metric_data: MetricData) β Result<(), ObservabilityError>send_trace(trace_span: TraceSpan) β Result<(), ObservabilityError>send_log_async(log_entry: LogEntry) β Future<Result<(), ObservabilityError>>send_metric_async(metric_data: MetricData) β Future<Result<(), ObservabilityError>>send_trace_async(trace_span: TraceSpan) β Future<Result<(), ObservabilityError>>generate_trace_id() β String - Generate a 32-character hex trace IDgenerate_span_id() β String - Generate a 16-character hex span IDLogEntry::new(severity: impl Into<String>, message: impl Into<String>)
.with_service_name(name: impl Into<String>)
MetricData::new(
metric_type: impl Into<String>,
value: f64,
value_type: impl Into<String>, // "INT64" | "DOUBLE"
metric_kind: impl Into<String> // "GAUGE" | "CUMULATIVE"
)
.with_labels(labels: HashMap<String, String>)
TraceSpan::new(
trace_id: impl Into<String>,
span_id: impl Into<String>,
display_name: impl Into<String>,
start_time: SystemTime,
duration: Duration
)
.with_parent_span_id(parent_span_id: impl Into<String>)
gcp_info!(client, "message") - Send an INFO log (fire-and-forget)gcp_warn!(client, "message") - Send a WARNING log (fire-and-forget)gcp_error!(client, "message") - Send an ERROR log (fire-and-forget)gcp_log!(client, "LEVEL", "message") - Send a log with custom severityThe library provides comprehensive error handling:
AuthenticationError - Failed to authenticate with gcloudApiError - Google Cloud API request failedSetupError - Failed to setup/install gcloud CLIShutdown - Special internal error for worker shutdownThe library automatically handles token expiration:
Background operations fail silently to avoid disrupting your application. If you need error feedback, use the async methods:
match client.send_log_async(LogEntry::new("INFO", "Important")).await {
Ok(()) => println!("Log sent successfully"),
Err(e) => eprintln!("Failed to send log: {}", e),
}
On a typical development machine:
[dependencies]
gcp-observability-rs = { version = "0.1.0", features = ["logging", "monitoring"] }
Available features:
logging - Cloud Logging functionalitymonitoring - Cloud Monitoring functionalitytracing - Cloud Trace functionalitydefault - Includes all featuresRun the example:
# Set your project ID and service account path
export GCP_PROJECT_ID="your-project-id"
export GCP_SERVICE_ACCOUNT="/path/to/service-account.json"
cargo run --example basic_usage
This library uses a unique approach that balances simplicity with performance:
The single-threaded worker model provides natural rate limiting:
# Verify gcloud is installed
gcloud version
# Verify service account works
gcloud auth activate-service-account --key-file=/path/to/key.json
gcloud auth list
Enable required APIs in your GCP project:
gcloud services enable logging.googleapis.com
gcloud services enable monitoring.googleapis.com
gcloud services enable cloudtrace.googleapis.com
Ensure your service account has the required roles:
roles/logging.logWriterroles/monitoring.metricWriterroles/cloudtrace.agentLicensed under the Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0).
Contributions are welcome! Please feel free to submit a Pull Request.