Additional Otel logging and spans
This commit is contained in:
23
src/files.rs
23
src/files.rs
@@ -15,7 +15,8 @@ use actix_web::{
|
|||||||
HttpResponse,
|
HttpResponse,
|
||||||
};
|
};
|
||||||
use log::{debug, error, info, trace};
|
use log::{debug, error, info, trace};
|
||||||
|
use opentelemetry::KeyValue;
|
||||||
|
use opentelemetry::trace::{Span, Status, Tracer};
|
||||||
use crate::data::{Claims, FilesRequest, FilterMode, PhotosResponse, SortType};
|
use crate::data::{Claims, FilesRequest, FilterMode, PhotosResponse, SortType};
|
||||||
use crate::{create_thumbnails, AppState};
|
use crate::{create_thumbnails, AppState};
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ use path_absolutize::*;
|
|||||||
use rand::prelude::SliceRandom;
|
use rand::prelude::SliceRandom;
|
||||||
use rand::thread_rng;
|
use rand::thread_rng;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use crate::otel::global_tracer;
|
||||||
|
|
||||||
pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
||||||
_: Claims,
|
_: Claims,
|
||||||
@@ -37,6 +39,10 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
|||||||
) -> HttpResponse {
|
) -> HttpResponse {
|
||||||
let search_path = &req.path;
|
let search_path = &req.path;
|
||||||
|
|
||||||
|
let tracer = global_tracer();
|
||||||
|
let mut span = tracer.start("list_photos");
|
||||||
|
span.set_attribute(KeyValue::new("path", search_path.to_string()));
|
||||||
|
|
||||||
let search_recursively = req.recursive.unwrap_or(false);
|
let search_recursively = req.recursive.unwrap_or(false);
|
||||||
if let Some(tag_ids) = &req.tag_ids {
|
if let Some(tag_ids) = &req.tag_ids {
|
||||||
if search_recursively {
|
if search_recursively {
|
||||||
@@ -99,6 +105,8 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
|||||||
tagged_files.len(),
|
tagged_files.len(),
|
||||||
tagged_files
|
tagged_files
|
||||||
);
|
);
|
||||||
|
span.set_attribute(KeyValue::new("file_count", tagged_files.len().to_string()));
|
||||||
|
span.set_status(Status::Ok);
|
||||||
|
|
||||||
HttpResponse::Ok().json(PhotosResponse {
|
HttpResponse::Ok().json(PhotosResponse {
|
||||||
photos: tagged_files,
|
photos: tagged_files,
|
||||||
@@ -190,12 +198,16 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
|||||||
.map(|f| f.to_str().unwrap().to_string())
|
.map(|f| f.to_str().unwrap().to_string())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
|
span.set_attribute(KeyValue::new("file_count", files.len().to_string()));
|
||||||
|
span.set_status(Status::Ok);
|
||||||
|
|
||||||
HttpResponse::Ok().json(PhotosResponse {
|
HttpResponse::Ok().json(PhotosResponse {
|
||||||
photos: response_files,
|
photos: response_files,
|
||||||
dirs,
|
dirs,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
error!("Bad photos request: {}", req.path);
|
error!("Bad photos request: {}", req.path);
|
||||||
|
span.set_status(Status::error("Invalid path"));
|
||||||
HttpResponse::BadRequest().finish()
|
HttpResponse::BadRequest().finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,12 +236,18 @@ fn sort(mut files: Vec<FileWithTagCount>, sort_type: SortType) -> Vec<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_files(dir: &Path) -> io::Result<Vec<PathBuf>> {
|
pub fn list_files(dir: &Path) -> io::Result<Vec<PathBuf>> {
|
||||||
|
let tracer = global_tracer();
|
||||||
|
let mut span = tracer.start("list_files");
|
||||||
|
let dir_name_string = dir.to_str().unwrap_or_default().to_string();
|
||||||
|
span.set_attribute(KeyValue::new("dir", dir_name_string));
|
||||||
|
|
||||||
let files = read_dir(dir)?
|
let files = read_dir(dir)?
|
||||||
.filter_map(|res| res.ok())
|
.filter_map(|res| res.ok())
|
||||||
.filter(|entry| is_image_or_video(&entry.path()) || entry.file_type().unwrap().is_dir())
|
.filter(|entry| is_image_or_video(&entry.path()) || entry.file_type().unwrap().is_dir())
|
||||||
.map(|entry| entry.path())
|
.map(|entry| entry.path())
|
||||||
.collect::<Vec<PathBuf>>();
|
.collect::<Vec<PathBuf>>();
|
||||||
|
|
||||||
|
span.set_attribute(KeyValue::new("file_count", files.len().to_string()));
|
||||||
Ok(files)
|
Ok(files)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,6 +390,7 @@ impl FileSystemAccess for RealFileSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn move_file<P: AsRef<Path>>(&self, from: P, destination: P) -> anyhow::Result<()> {
|
fn move_file<P: AsRef<Path>>(&self, from: P, destination: P) -> anyhow::Result<()> {
|
||||||
|
info!("Moving file: '{:?}' -> '{:?}'", from.as_ref(), destination.as_ref());
|
||||||
let name = from
|
let name = from
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.file_name()
|
.file_name()
|
||||||
@@ -393,6 +412,8 @@ impl Handler<RefreshThumbnailsMessage> for StreamActor {
|
|||||||
type Result = ();
|
type Result = ();
|
||||||
|
|
||||||
fn handle(&mut self, _msg: RefreshThumbnailsMessage, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, _msg: RefreshThumbnailsMessage, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let tracer = global_tracer();
|
||||||
|
let _ = tracer.start("RefreshThumbnailsMessage");
|
||||||
info!("Refreshing thumbnails after upload");
|
info!("Refreshing thumbnails after upload");
|
||||||
create_thumbnails()
|
create_thumbnails()
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/main.rs
16
src/main.rs
@@ -83,6 +83,9 @@ async fn get_image(
|
|||||||
req: web::Query<ThumbnailRequest>,
|
req: web::Query<ThumbnailRequest>,
|
||||||
app_state: Data<AppState>,
|
app_state: Data<AppState>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
|
let tracer = global_tracer();
|
||||||
|
let mut span = tracer.start("get_image");
|
||||||
|
|
||||||
if let Some(path) = is_valid_full_path(&app_state.base_path, &req.path, false) {
|
if let Some(path) = is_valid_full_path(&app_state.base_path, &req.path, false) {
|
||||||
let image_size = req.size.unwrap_or(PhotoSize::Full);
|
let image_size = req.size.unwrap_or(PhotoSize::Full);
|
||||||
if image_size == PhotoSize::Thumb {
|
if image_size == PhotoSize::Thumb {
|
||||||
@@ -95,16 +98,21 @@ async fn get_image(
|
|||||||
|
|
||||||
trace!("Thumbnail path: {:?}", thumb_path);
|
trace!("Thumbnail path: {:?}", thumb_path);
|
||||||
if let Ok(file) = NamedFile::open(&thumb_path) {
|
if let Ok(file) = NamedFile::open(&thumb_path) {
|
||||||
|
span.set_status(Status::Ok);
|
||||||
file.into_response(&request)
|
file.into_response(&request)
|
||||||
} else {
|
} else {
|
||||||
|
span.set_status(Status::error("Not found"));
|
||||||
HttpResponse::NotFound().finish()
|
HttpResponse::NotFound().finish()
|
||||||
}
|
}
|
||||||
} else if let Ok(file) = NamedFile::open(path) {
|
} else if let Ok(file) = NamedFile::open(path) {
|
||||||
|
span.set_status(Status::Ok);
|
||||||
file.into_response(&request)
|
file.into_response(&request)
|
||||||
} else {
|
} else {
|
||||||
|
span.set_status(Status::error("Not found"));
|
||||||
HttpResponse::NotFound().finish()
|
HttpResponse::NotFound().finish()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
span.set_status(Status::error("Bad photos request"));
|
||||||
error!("Bad photos request: {}", req.path);
|
error!("Bad photos request: {}", req.path);
|
||||||
HttpResponse::BadRequest().finish()
|
HttpResponse::BadRequest().finish()
|
||||||
}
|
}
|
||||||
@@ -309,7 +317,7 @@ async fn get_video_part(
|
|||||||
path: web::Path<ThumbnailRequest>,
|
path: web::Path<ThumbnailRequest>,
|
||||||
app_state: Data<AppState>,
|
app_state: Data<AppState>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
let tracer = global::tracer("image-server");
|
let tracer = global_tracer();
|
||||||
let mut span = tracer.start("get_video_part");
|
let mut span = tracer.start("get_video_part");
|
||||||
|
|
||||||
let part = &path.path;
|
let part = &path.path;
|
||||||
@@ -381,15 +389,15 @@ async fn put_add_favorite(
|
|||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(Err(e)) if e.kind == DbErrorKind::AlreadyExists => {
|
Ok(Err(e)) if e.kind == DbErrorKind::AlreadyExists => {
|
||||||
debug!("Favorite: {} exists for user: {}", &body.path, user_id);
|
warn!("Favorite: {} exists for user: {}", &body.path, user_id);
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
}
|
}
|
||||||
Ok(Err(e)) => {
|
Ok(Err(e)) => {
|
||||||
info!("{:?} {}. for user: {}", e, body.path, user_id);
|
error!("{:?} {}. for user: {}", e, body.path, user_id);
|
||||||
HttpResponse::BadRequest()
|
HttpResponse::BadRequest()
|
||||||
}
|
}
|
||||||
Ok(Ok(_)) => {
|
Ok(Ok(_)) => {
|
||||||
debug!("Adding favorite \"{}\" for userid: {}", body.path, user_id);
|
info!("Adding favorite \"{}\" for userid: {}", body.path, user_id);
|
||||||
HttpResponse::Created()
|
HttpResponse::Created()
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ pub fn init_tracing() {
|
|||||||
let resources = Resource::builder()
|
let resources = Resource::builder()
|
||||||
.with_attributes([
|
.with_attributes([
|
||||||
KeyValue::new("service.name", "image-server"),
|
KeyValue::new("service.name", "image-server"),
|
||||||
//TODO: Get this from somewhere
|
KeyValue::new("service.version", env!("CARGO_PKG_VERSION")),
|
||||||
KeyValue::new("service.version", "1.0"),
|
|
||||||
])
|
])
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user