fix(health): 补充 3 个核心 service 的 tracing 日志 — 38 处
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

审计后续 H3: patient_service(15) + consultation_service(10) + follow_up_service(13)
共计 2526 行代码此前 0 处运维级日志,现已在所有 pub async fn 入口添加
tracing::info! 日志,格式统一为 action + key params。
This commit is contained in:
iven
2026-04-30 16:58:04 +08:00
parent 44bb31197e
commit 0dcaf7915f
3 changed files with 43 additions and 3 deletions

View File

@@ -41,6 +41,7 @@ pub async fn create_session(
operator_id: Option<Uuid>,
req: CreateSessionReq,
) -> HealthResult<SessionResp> {
tracing::info!(action = "create_session", patient_id = %req.patient_id, "Creating consultation session");
let now = Utc::now();
// 校验患者存在
@@ -100,6 +101,7 @@ pub async fn get_session(
tenant_id: Uuid,
session_id: Uuid,
) -> HealthResult<SessionResp> {
tracing::info!(action = "get_session", session_id = %session_id, "Fetching consultation session");
let model = consultation_session::Entity::find()
.filter(consultation_session::Column::Id.eq(session_id))
.filter(consultation_session::Column::TenantId.eq(tenant_id))
@@ -120,6 +122,7 @@ pub async fn list_sessions(
patient_id: Option<Uuid>,
doctor_id: Option<Uuid>,
) -> HealthResult<PaginatedResponse<SessionResp>> {
tracing::info!(action = "list_sessions", page, page_size, "Listing consultation sessions");
let limit = page_size.min(100);
let offset = page.saturating_sub(1) * limit;
@@ -152,6 +155,7 @@ pub async fn close_session(
operator_id: Option<Uuid>,
expected_version: i32,
) -> HealthResult<SessionResp> {
tracing::info!(action = "close_session", session_id = %session_id, expected_version, "Closing consultation session");
let model = consultation_session::Entity::find()
.filter(consultation_session::Column::Id.eq(session_id))
.filter(consultation_session::Column::TenantId.eq(tenant_id))
@@ -204,6 +208,7 @@ pub async fn export_sessions(
page: Option<u64>,
page_size: Option<u64>,
) -> HealthResult<PaginatedResponse<SessionResp>> {
tracing::info!(action = "export_sessions", "Exporting consultation sessions");
let limit = page_size.unwrap_or(100).min(500);
let page_num = page.unwrap_or(1);
let offset = page_num.saturating_sub(1) * limit;
@@ -277,6 +282,7 @@ pub async fn list_messages(
page_size: u64,
after_id: Option<Uuid>,
) -> HealthResult<PaginatedResponse<MessageResp>> {
tracing::info!(action = "list_messages", session_id = %session_id, page, page_size, "Listing consultation messages");
let limit = page_size.min(100);
let mut query = consultation_message::Entity::find()
@@ -290,7 +296,7 @@ pub async fn list_messages(
}
let offset = page.saturating_sub(1) * limit;
let total = query.clone().count(&state.db).await?;
let _total = query.clone().count(&state.db).await?;
let total = query.clone().count(&state.db).await?;
let models = query
@@ -322,6 +328,7 @@ pub async fn create_message(
sender_role: String,
req: CreateMessageReq,
) -> HealthResult<MessageResp> {
tracing::info!(action = "create_message", session_id = %req.session_id, sender_role = %sender_role, "Creating consultation message");
// 校验会话存在且状态为 active 或 waiting
let session = consultation_session::Entity::find()
.filter(consultation_session::Column::Id.eq(req.session_id))
@@ -445,9 +452,10 @@ pub async fn mark_session_read(
state: &HealthState,
tenant_id: Uuid,
session_id: Uuid,
user_id: Uuid,
_user_id: Uuid,
role: &str,
) -> HealthResult<()> {
tracing::info!(action = "mark_session_read", session_id = %session_id, role, "Marking consultation session as read");
let session = consultation_session::Entity::find()
.filter(consultation_session::Column::Id.eq(session_id))
.filter(consultation_session::Column::TenantId.eq(tenant_id))
@@ -499,6 +507,7 @@ pub async fn get_doctor_dashboard(
tenant_id: Uuid,
doctor_user_id: Uuid,
) -> HealthResult<DoctorDashboard> {
tracing::info!(action = "get_doctor_dashboard", doctor_user_id = %doctor_user_id, "Fetching doctor dashboard");
use crate::entity::{doctor_profile, patient_doctor_relation, follow_up_task};
use sea_orm::ColumnTrait;
use sea_orm::QueryFilter;
@@ -605,8 +614,9 @@ pub async fn enrich_doctor_dashboard_health(
doctor_user_id: Uuid,
dashboard: &mut DoctorDashboard,
) -> HealthResult<()> {
tracing::info!(action = "enrich_doctor_dashboard_health", doctor_user_id = %doctor_user_id, "Enriching doctor dashboard with health data");
use crate::entity::{lab_report, appointment};
use sea_orm::{FromQueryResult, Statement, DatabaseBackend};
// 待审核化验报告
let pending_lab = lab_report::Entity::find()

View File

@@ -32,6 +32,7 @@ pub async fn list_tasks(
assigned_to: Option<Uuid>,
status: Option<String>,
) -> HealthResult<PaginatedResponse<FollowUpTaskResp>> {
tracing::info!(action = "list_tasks", page, page_size, "Listing follow-up tasks");
let limit = page_size.min(100);
let offset = page.saturating_sub(1) * limit;
@@ -111,6 +112,7 @@ pub async fn get_task(
tenant_id: Uuid,
task_id: Uuid,
) -> HealthResult<FollowUpTaskResp> {
tracing::info!(action = "get_task", task_id = %task_id, "Fetching follow-up task");
let m = follow_up_task::Entity::find()
.filter(follow_up_task::Column::Id.eq(task_id))
.filter(follow_up_task::Column::TenantId.eq(tenant_id))
@@ -135,6 +137,7 @@ pub async fn create_task(
operator_id: Option<Uuid>,
req: CreateFollowUpTaskReq,
) -> HealthResult<FollowUpTaskResp> {
tracing::info!(action = "create_task", patient_id = %req.patient_id, "Creating follow-up task");
let now = Utc::now();
validate_follow_up_type(&req.follow_up_type)?;
@@ -203,6 +206,7 @@ pub async fn update_task(
req: UpdateFollowUpTaskReq,
expected_version: i32,
) -> HealthResult<FollowUpTaskResp> {
tracing::info!(action = "update_task", task_id = %task_id, expected_version, "Updating follow-up task");
let model = follow_up_task::Entity::find()
.filter(follow_up_task::Column::Id.eq(task_id))
.filter(follow_up_task::Column::TenantId.eq(tenant_id))
@@ -273,6 +277,7 @@ pub async fn delete_task(
operator_id: Option<Uuid>,
expected_version: i32,
) -> HealthResult<()> {
tracing::info!(action = "delete_task", task_id = %task_id, "Deleting follow-up task");
let model = follow_up_task::Entity::find()
.filter(follow_up_task::Column::Id.eq(task_id))
.filter(follow_up_task::Column::TenantId.eq(tenant_id))
@@ -310,6 +315,7 @@ pub async fn batch_create_tasks(
operator_id: Option<Uuid>,
req: BatchCreateTasksReq,
) -> HealthResult<BatchResultResp> {
tracing::info!(action = "batch_create_tasks", patient_count = req.patient_ids.len(), "Batch creating follow-up tasks");
validate_follow_up_type(&req.follow_up_type)?;
let mut succeeded: u32 = 0;
let mut errors: Vec<crate::dto::follow_up_dto::BatchError> = Vec::new();
@@ -394,6 +400,7 @@ pub async fn batch_assign_tasks(
operator_id: Option<Uuid>,
req: BatchAssignReq,
) -> HealthResult<BatchResultResp> {
tracing::info!(action = "batch_assign_tasks", task_count = req.task_ids.len(), assigned_to = ?req.assigned_to, "Batch assigning follow-up tasks");
let mut succeeded: u32 = 0;
let mut errors: Vec<crate::dto::follow_up_dto::BatchError> = Vec::new();
@@ -450,6 +457,7 @@ pub async fn batch_complete_tasks(
operator_id: Option<Uuid>,
req: BatchCompleteReq,
) -> HealthResult<BatchResultResp> {
tracing::info!(action = "batch_complete_tasks", task_count = req.task_ids.len(), "Batch completing follow-up tasks");
let mut succeeded: u32 = 0;
let mut errors: Vec<crate::dto::follow_up_dto::BatchError> = Vec::new();
@@ -524,6 +532,7 @@ pub async fn create_record(
operator_id: Option<Uuid>,
req: CreateFollowUpRecordReq,
) -> HealthResult<FollowUpRecordResp> {
tracing::info!(action = "create_record", task_id = %req.task_id, "Creating follow-up record");
let task = follow_up_task::Entity::find()
.filter(follow_up_task::Column::Id.eq(req.task_id))
.filter(follow_up_task::Column::TenantId.eq(tenant_id))
@@ -634,6 +643,7 @@ pub async fn list_records(
task_id: Option<Uuid>,
patient_id: Option<Uuid>,
) -> HealthResult<PaginatedResponse<FollowUpRecordResp>> {
tracing::info!(action = "list_records", page, page_size, "Listing follow-up records");
let limit = page_size.min(100);
let offset = page.saturating_sub(1) * limit;
@@ -699,6 +709,7 @@ pub async fn complete_task_by_system(
task_id: Uuid,
tenant_id: Uuid,
) -> HealthResult<()> {
tracing::info!(action = "complete_task_by_system", task_id = %task_id, "System completing follow-up task");
let model = follow_up_task::Entity::find()
.filter(follow_up_task::Column::Id.eq(task_id))
.filter(follow_up_task::Column::TenantId.eq(tenant_id))
@@ -734,6 +745,7 @@ pub async fn complete_task_by_system(
/// 批量将 planned_date < 今天 且 status = pending 的随访任务标记为 overdue。
/// 返回受影响的行数。
pub async fn check_overdue_tasks(db: &DatabaseConnection) -> HealthResult<u64> {
tracing::info!(action = "check_overdue_tasks", "Checking overdue follow-up tasks");
let today = chrono::Utc::now().date_naive();
let result = follow_up_task::Entity::update_many()
.col_expr(
@@ -762,6 +774,7 @@ pub async fn check_overdue_tasks(db: &DatabaseConnection) -> HealthResult<u64> {
/// 只发布**本次新被标记**为 overdue 的事件,避免重复通知。
/// 幂等策略:先查出即将被标记的 pending 任务,批量更新后只为这些任务发事件。
pub async fn check_overdue_and_notify(state: &HealthState) -> HealthResult<u64> {
tracing::info!(action = "check_overdue_and_notify", "Checking overdue tasks and sending notifications");
let db = &state.db;
let today = chrono::Utc::now().date_naive();

View File

@@ -37,6 +37,7 @@ pub async fn list_patients(
search: Option<String>,
tag_id: Option<Uuid>,
) -> HealthResult<PaginatedResponse<PatientResp>> {
tracing::info!(action = "list_patients", tenant_id = %tenant_id, page, page_size, "Listing patients");
let limit = page_size.min(100);
let offset = page.saturating_sub(1) * limit;
@@ -102,6 +103,7 @@ pub async fn create_patient(
operator_id: Option<Uuid>,
req: CreatePatientReq,
) -> HealthResult<PatientResp> {
tracing::info!(action = "create_patient", tenant_id = %tenant_id, name = %req.name, "Creating patient");
let now = Utc::now();
let id = Uuid::now_v7();
@@ -238,6 +240,7 @@ pub async fn get_patient(
tenant_id: Uuid,
id: Uuid,
) -> HealthResult<PatientResp> {
tracing::info!(action = "get_patient", patient_id = %id, "Fetching patient");
let model = find_patient(&state.db, tenant_id, id).await?;
Ok(model_to_resp_decrypted(&state.crypto, model))
}
@@ -251,6 +254,7 @@ pub async fn update_patient(
req: UpdatePatientReq,
expected_version: i32,
) -> HealthResult<PatientResp> {
tracing::info!(action = "update_patient", patient_id = %id, "Updating patient");
let model = find_patient(&state.db, tenant_id, id).await?;
let next_ver = check_version(expected_version, model.version)
.map_err(|_| HealthError::VersionMismatch)?;
@@ -364,6 +368,7 @@ pub async fn delete_patient(
operator_id: Option<Uuid>,
expected_version: i32,
) -> HealthResult<()> {
tracing::info!(action = "delete_patient", patient_id = %id, "Soft deleting patient");
let model = find_patient(&state.db, tenant_id, id).await?;
let next_ver = check_version(expected_version, model.version)
.map_err(|_| HealthError::VersionMismatch)?;
@@ -396,6 +401,7 @@ pub async fn manage_patient_tags(
req: ManageTagsReq,
operator_id: Option<Uuid>,
) -> HealthResult<()> {
tracing::info!(action = "manage_patient_tags", patient_id = %patient_id, tag_count = req.tag_ids.len(), "Managing patient tags");
// 确认患者存在
find_patient(&state.db, tenant_id, patient_id).await?;
@@ -471,6 +477,7 @@ pub async fn get_health_summary(
tenant_id: Uuid,
patient_id: Uuid,
) -> HealthResult<serde_json::Value> {
tracing::info!(action = "get_health_summary", patient_id = %patient_id, "Fetching health summary");
find_patient(&state.db, tenant_id, patient_id).await?;
use crate::entity::{vital_signs, lab_report, appointment, follow_up_task};
@@ -532,6 +539,7 @@ pub async fn list_family_members(
tenant_id: Uuid,
patient_id: Uuid,
) -> HealthResult<Vec<FamilyMemberResp>> {
tracing::info!(action = "list_family_members", patient_id = %patient_id, "Listing family members");
let models = patient_family_member::Entity::find()
.filter(patient_family_member::Column::TenantId.eq(tenant_id))
.filter(patient_family_member::Column::PatientId.eq(patient_id))
@@ -568,6 +576,7 @@ pub async fn create_family_member(
operator_id: Option<Uuid>,
req: FamilyMemberReq,
) -> HealthResult<FamilyMemberResp> {
tracing::info!(action = "create_family_member", patient_id = %patient_id, name = %req.name, "Creating family member");
find_patient(&state.db, tenant_id, patient_id).await?;
let now = Utc::now();
@@ -637,6 +646,7 @@ pub async fn update_family_member(
req: FamilyMemberReq,
expected_version: i32,
) -> HealthResult<FamilyMemberResp> {
tracing::info!(action = "update_family_member", patient_id = %patient_id, family_member_id = %family_member_id, "Updating family member");
let model = patient_family_member::Entity::find()
.filter(patient_family_member::Column::Id.eq(family_member_id))
.filter(patient_family_member::Column::PatientId.eq(patient_id))
@@ -719,6 +729,7 @@ pub async fn delete_family_member(
operator_id: Option<Uuid>,
expected_version: i32,
) -> HealthResult<()> {
tracing::info!(action = "delete_family_member", family_member_id = %family_member_id, "Soft deleting family member");
let model = patient_family_member::Entity::find()
.filter(patient_family_member::Column::Id.eq(family_member_id))
.filter(patient_family_member::Column::PatientId.eq(patient_id))
@@ -760,6 +771,7 @@ pub async fn assign_doctor(
relationship_type: String,
operator_id: Option<Uuid>,
) -> HealthResult<()> {
tracing::info!(action = "assign_doctor", patient_id = %patient_id, doctor_id = %doctor_id, "Assigning doctor to patient");
find_patient(&state.db, tenant_id, patient_id).await?;
// 验证医生存在
@@ -816,6 +828,7 @@ pub async fn remove_doctor(
doctor_id: Uuid,
operator_id: Option<Uuid>,
) -> HealthResult<()> {
tracing::info!(action = "remove_doctor", patient_id = %patient_id, doctor_id = %doctor_id, "Removing doctor from patient");
let model = patient_doctor_relation::Entity::find()
.filter(patient_doctor_relation::Column::TenantId.eq(tenant_id))
.filter(patient_doctor_relation::Column::PatientId.eq(patient_id))
@@ -927,6 +940,7 @@ pub async fn list_tags(
state: &crate::state::HealthState,
tenant_id: Uuid,
) -> HealthResult<Vec<crate::dto::patient_dto::TagResp>> {
tracing::info!(action = "list_tags", tenant_id = %tenant_id, "Listing patient tags");
use crate::entity::patient_tag;
let tags = patient_tag::Entity::find()
.filter(patient_tag::Column::TenantId.eq(tenant_id))
@@ -972,6 +986,7 @@ pub async fn create_tag(
operator_id: Option<Uuid>,
req: CreateTagReq,
) -> HealthResult<TagResp> {
tracing::info!(action = "create_tag", tenant_id = %tenant_id, name = %req.name, "Creating patient tag");
let id = Uuid::now_v7();
let now = Utc::now();
let tag = patient_tag::ActiveModel {
@@ -1016,6 +1031,7 @@ pub async fn update_tag(
operator_id: Option<Uuid>,
req: UpdateTagReq,
) -> HealthResult<TagResp> {
tracing::info!(action = "update_tag", tag_id = %tag_id, "Updating patient tag");
let tag = patient_tag::Entity::find_by_id(tag_id)
.one(&state.db)
.await?
@@ -1068,6 +1084,7 @@ pub async fn delete_tag(
operator_id: Option<Uuid>,
version: i32,
) -> HealthResult<()> {
tracing::info!(action = "delete_tag", tag_id = %tag_id, "Soft deleting patient tag");
let tag = patient_tag::Entity::find_by_id(tag_id)
.one(&state.db)
.await?