feat(telemetry): integrate OpenTelemetry observability stack with health metrics

- Add OpenTelemetry SDK, OTLP exporter, Prometheus integration
- Implement connection tracking with active/total/disconnection metrics
- Add health endpoint with uptime and connection counts
- Integrate tracing spans for socket events and engine messages
- Add metrics collection for event handling duration
- Update health endpoint to include live runtime state
- Add graceful telemetry shutdown in main function
- Implement engine session active metrics tracking
- Add namespace-specific attributes to connection metrics
- Introduce message edit history retrieval endpoint
- Add scheduled message CRUD operations and dispatcher
- Update Socket.IO event registration with observability
- Refactor component update to remove dead code allowance
- Add comprehensive environment variables documentation
- Implement detailed development guidelines in AGENTS.md
This commit is contained in:
zhenyi
2026-06-11 13:53:29 +08:00
parent 40241e5db3
commit 0dbac480ae
22 changed files with 3116 additions and 64 deletions
+38 -1
View File
@@ -296,6 +296,43 @@ impl MessageService {
Ok(())
}
/// Handle `message:edit_history` — retrieve the edit history for a message.
pub async fn get_edit_history(
&self,
socket: Arc<Socket>,
data: &serde_json::Value,
) -> ImksResult<()> {
let user_id = self.user_id(&socket)?;
let payload = Self::first_payload(data)?;
let message_id: Uuid = Self::parse_field(payload, "message_id")?;
let message = self
.repo
.get(message_id)
.await?
.ok_or_else(|| ImksError::NotFound(format!("message {message_id}")))?;
let channel_id_str = message.channel_id.to_string();
let user_id_str = user_id.to_string();
self.ensure_readable(&channel_id_str, &user_id_str).await?;
let history = self.repo.get_edit_history(message_id).await?;
let summary = self.repo.get_edit_summary(message_id).await?;
let _ = socket.emit(
"message:edit_history",
serde_json::json!({
"message_id": message_id.to_string(),
"edits": history,
"edit_count": summary.edit_count,
"last_edited_at": summary.last_edited_at,
"last_edited_by": summary.last_edited_by,
}),
);
Ok(())
}
// Permission validation helpers
/// Full write-access gate: resolve channel + readability + membership + SEND_MESSAGE.
@@ -481,7 +518,7 @@ impl MessageService {
}
}
fn validate_body_size(&self, body: &str) -> ImksResult<()> {
pub(crate) fn validate_body_size(&self, body: &str) -> ImksResult<()> {
if body.len() > self.max_body_size {
return Err(ImksError::InvalidInput(format!(
"Message body exceeds max size of {} bytes (got {})",