Add DB spans to the various queries
This commit is contained in:
18
src/otel.rs
18
src/otel.rs
@@ -3,6 +3,7 @@ use actix_web::HttpRequest;
|
||||
use opentelemetry::global::BoxedTracer;
|
||||
use opentelemetry::{global, Context, KeyValue};
|
||||
use opentelemetry::propagation::TextMapPropagator;
|
||||
use opentelemetry::trace::Tracer;
|
||||
use opentelemetry_appender_log::OpenTelemetryLogBridge;
|
||||
use opentelemetry_otlp::WithExportConfig;
|
||||
use opentelemetry_sdk::logs::{BatchLogProcessor, SdkLoggerProvider};
|
||||
@@ -13,6 +14,7 @@ pub fn global_tracer() -> BoxedTracer {
|
||||
global::tracer("image-server")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn init_tracing() {
|
||||
let resources = Resource::builder()
|
||||
.with_attributes([
|
||||
@@ -35,6 +37,7 @@ pub fn init_tracing() {
|
||||
global::set_tracer_provider(tracer_provider);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn init_logs() {
|
||||
let otlp_exporter = opentelemetry_otlp::LogExporter::builder()
|
||||
.with_tonic()
|
||||
@@ -47,7 +50,7 @@ pub fn init_logs() {
|
||||
let resources = Resource::builder()
|
||||
.with_attributes([
|
||||
KeyValue::new("service.name", "image-server"),
|
||||
KeyValue::new("service.version", "1.0"),
|
||||
KeyValue::new("service.version", env!("CARGO_PKG_VERSION")),
|
||||
])
|
||||
.build();
|
||||
|
||||
@@ -78,3 +81,16 @@ pub fn extract_context_from_request(req: &HttpRequest) -> Context {
|
||||
let propagator = TraceContextPropagator::new();
|
||||
propagator.extract(&HeaderExtractor(req.headers()))
|
||||
}
|
||||
|
||||
pub fn trace_db_call<F, O>(operation: &str, query_type: &str, func: F) -> anyhow::Result<O>
|
||||
where F: FnOnce() -> anyhow::Result<O> {
|
||||
let tracer = global::tracer("db");
|
||||
let _span = tracer
|
||||
.span_builder(format!("db.{}.{}", operation, query_type))
|
||||
.with_attributes(vec![
|
||||
KeyValue::new("db.operation", operation.to_string().clone()),
|
||||
KeyValue::new("db.query_type", query_type.to_string().clone()),
|
||||
]).start(&tracer);
|
||||
|
||||
func()
|
||||
}
|
||||
15
src/tags.rs
15
src/tags.rs
@@ -1,4 +1,5 @@
|
||||
use crate::data::GetTagsRequest;
|
||||
use crate::otel::trace_db_call;
|
||||
use crate::{connect, data::AddTagRequest, error::IntoHttpError, schema, Claims, ThumbnailRequest};
|
||||
use actix_web::dev::{ServiceFactory, ServiceRequest};
|
||||
use actix_web::{web, App, HttpResponse, Responder};
|
||||
@@ -231,6 +232,7 @@ impl TagDao for SqliteTagDao {
|
||||
fn get_all_tags(&mut self, path: Option<String>) -> anyhow::Result<Vec<(i64, Tag)>> {
|
||||
// select name, count(*) from tags join tagged_photo ON tags.id = tagged_photo.tag_id GROUP BY tags.name ORDER BY COUNT(*);
|
||||
|
||||
trace_db_call("query", "get_all_tags", || {
|
||||
let path = path.map(|p| p + "%").unwrap_or("%".to_string());
|
||||
let (id, name, created_time) = tags::all_columns;
|
||||
tags::table
|
||||
@@ -255,9 +257,11 @@ impl TagDao for SqliteTagDao {
|
||||
.collect()
|
||||
})
|
||||
.with_context(|| "Unable to get all tags")
|
||||
})
|
||||
}
|
||||
|
||||
fn get_tags_for_path(&mut self, path: &str) -> anyhow::Result<Vec<Tag>> {
|
||||
trace_db_call("query", "get_tags_for_path", || {
|
||||
trace!("Getting Tags for path: {:?}", path);
|
||||
tags::table
|
||||
.left_join(tagged_photo::table)
|
||||
@@ -265,9 +269,11 @@ impl TagDao for SqliteTagDao {
|
||||
.select((tags::id, tags::name, tags::created_time))
|
||||
.get_results::<Tag>(self.connection.borrow_mut())
|
||||
.with_context(|| "Unable to get tags from Sqlite")
|
||||
})
|
||||
}
|
||||
|
||||
fn create_tag(&mut self, name: &str) -> anyhow::Result<Tag> {
|
||||
trace_db_call("insert", "create_tag", || {
|
||||
diesel::insert_into(tags::table)
|
||||
.values(InsertTag {
|
||||
name: name.to_string(),
|
||||
@@ -294,9 +300,11 @@ impl TagDao for SqliteTagDao {
|
||||
format!("Unable to get tagged photo with id: {:?} from Sqlite", id)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn remove_tag(&mut self, tag_name: &str, path: &str) -> anyhow::Result<Option<()>> {
|
||||
trace_db_call("delete", "remove_tag", || {
|
||||
tags::table
|
||||
.filter(tags::name.eq(tag_name))
|
||||
.get_result::<Tag>(self.connection.borrow_mut())
|
||||
@@ -317,9 +325,11 @@ impl TagDao for SqliteTagDao {
|
||||
Ok(None)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn tag_file(&mut self, path: &str, tag_id: i32) -> anyhow::Result<TaggedPhoto> {
|
||||
trace_db_call("insert", "tag_file", || {
|
||||
diesel::insert_into(tagged_photo::table)
|
||||
.values(InsertTaggedPhoto {
|
||||
tag_id,
|
||||
@@ -348,6 +358,7 @@ impl TagDao for SqliteTagDao {
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn get_files_with_all_tag_ids(
|
||||
@@ -355,6 +366,7 @@ impl TagDao for SqliteTagDao {
|
||||
tag_ids: Vec<i32>,
|
||||
exclude_tag_ids: Vec<i32>,
|
||||
) -> anyhow::Result<Vec<FileWithTagCount>> {
|
||||
trace_db_call("query", "get_files_with_all_tags", || {
|
||||
use diesel::dsl::*;
|
||||
|
||||
let exclude_subquery = tagged_photo::table
|
||||
@@ -382,6 +394,7 @@ impl TagDao for SqliteTagDao {
|
||||
.collect()
|
||||
})
|
||||
.with_context(|| format!("Unable to get Tagged photos with ids: {:?}", tag_ids))
|
||||
})
|
||||
}
|
||||
|
||||
fn get_files_with_any_tag_ids(
|
||||
@@ -389,6 +402,7 @@ impl TagDao for SqliteTagDao {
|
||||
tag_ids: Vec<i32>,
|
||||
exclude_tag_ids: Vec<i32>,
|
||||
) -> anyhow::Result<Vec<FileWithTagCount>> {
|
||||
trace_db_call("query", "get_files_with_any_tags", || {
|
||||
use diesel::dsl::*;
|
||||
|
||||
let tag_ids_str = tag_ids
|
||||
@@ -427,6 +441,7 @@ WITH filtered_photos AS (
|
||||
// Execute the query:
|
||||
let results = query.load::<FileWithTagCount>(&mut self.connection)?;
|
||||
Ok(results)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user