| Crates.io | gcp-rust-tools |
| lib.rs | gcp-rust-tools |
| version | 0.2.4 |
| created_at | 2026-01-15 22:54:19.833992+00 |
| updated_at | 2026-01-24 07:57:48.928161+00 |
| description | Comprehensive Google Cloud Platform tools for Rust: Observability (Logs, Metrics, Traces) and PubSub |
| homepage | |
| repository | https://github.com/santiamoretti/gcp-rust-tools |
| max_upload_size | |
| id | 2047307 |
| size | 134,461 |
A comprehensive Rust toolset for Google Cloud Platform, combining simplified Observability (Logs, Metrics, Traces) with robust Pub/Sub wrappers.
This crate was developed by Santiago Amoretti in the context of the development of Genevabm(https://genevabm.com).
Add this to your Cargo.toml:
[dependencies]
gcp-rust-tools = "0.2.4"
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.agentroles/pubsub.publisher (for publishing)roles/pubsub.subscriber (for pulling/streaming subscriptions)gcloud 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_rust_tools::{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)
// Credentials are resolved internally from GOOGLE_APPLICATION_CREDENTIALS.
// Project id can be provided, or inferred via GOOGLE_CLOUD_PROJECT / gcloud.
let client = ObservabilityClient::new(
Some("your-project-id".to_string()),
None,
).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_rust_tools::{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),
}
This crate includes a small convenience wrapper over the official google-cloud-pubsub client.
topics are expanded to: projects/{project_id}/topics/{name}-{instance_id}subs are expanded to: projects/{project_id}/subscriptions/{name}use gcp_rust_tools::pubsub::create_pubsub_client;
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let topics: Arc<[&'static str]> = Arc::from(["events"]);
let subs: Arc<[&'static str]> = Arc::from(["events-sub"]);
// Credentials are resolved from GOOGLE_APPLICATION_CREDENTIALS.
// Project id is resolved from (in order): provided value, GOOGLE_CLOUD_PROJECT,
// or `gcloud config get-value project`.
let pubsub = create_pubsub_client(None, "dev", topics, subs).await?;
pubsub
.publish_fire_and_forget(
"events",
serde_json::json!({"hello": "world"}),
None,
)
.await;
Ok(())
}
Notes:
publish_fire_and_forget intentionally does not surface publish errors; it spawns a task and logs failures via log.On a typical development machine:
[dependencies]
gcp-rust-tools = { version = "0.2.4", 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.