diff --git a/src/api.rs b/src/api.rs index 9e307ed..3a2eb42 100644 --- a/src/api.rs +++ b/src/api.rs @@ -11,7 +11,7 @@ use serde_json::Value; use sha2::Sha256; use subtle::ConstantTimeEq; use tower_http::trace::TraceLayer; -use tracing::info; +use tracing::{info, instrument}; use crate::consts::{GITEA_EVENT_TYPE_HEADER_NAME, GITEA_SIG_HEADER_NAME, MAX_WEBHOOK_BODY_SIZE}; use crate::errors::AppError; @@ -40,10 +40,13 @@ async fn root() -> &'static str { "Hi, i'm Herald :)" } +#[instrument(skip(app_state), fields(webhook_type), err)] async fn webhook( State(app_state): State, WebhookExtract(wb): WebhookExtract, ) -> Result { + tracing::Span::current().record("webhook_type", tracing::field::debug(&wb)); + app_state .bot_tx .send(wb) @@ -62,6 +65,7 @@ where { type Rejection = AppError; + #[instrument(skip(req, state), err)] async fn from_request(req: axum::extract::Request, state: &S) -> Result { let app_state = AppState::from_ref(state); let headers = req.headers(); diff --git a/src/bot.rs b/src/bot.rs index 009d90e..c5d4a7e 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -1,12 +1,11 @@ -use serde::Deserialize; -use std::time::Duration; -use tracing::{error, info}; - use crate::{ env::EnvConfig, gitea::{GiteaAPI, WebhookType}, open_router::OpenRouterClient, }; +use serde::Deserialize; +use std::time::Duration; +use tracing::{error, info, instrument}; #[derive(Deserialize, Debug)] pub struct ReviewResult { @@ -59,10 +58,13 @@ impl Bot { self.exec(wb).await; } + info!("Bot shutting down, channel closed"); Ok(()) } + #[instrument(skip(self))] pub async fn exec(&self, webhook: WebhookType) { + tracing::Span::current().record("webhook_type", tracing::field::debug(&webhook)); let exec_result = match webhook { WebhookType::Review(review_payload) => crate::bot_actions::review::exec_review( &self.gitea_api, @@ -77,7 +79,7 @@ impl Bot { match exec_result { Ok(_) => info!("Task completed"), Err(err) => { - error!("{}", err); + error!(%err, "Task error"); sentry_anyhow::capture_anyhow(&err); } } diff --git a/src/bot_actions/review.rs b/src/bot_actions/review.rs index 8882c32..83df3fa 100644 --- a/src/bot_actions/review.rs +++ b/src/bot_actions/review.rs @@ -1,15 +1,16 @@ use futures_util::stream::TryStreamExt; use tokio::io::AsyncReadExt; use tokio_util::io::StreamReader; +use tracing::instrument; use crate::{ bot::ReviewResult, consts::{BOT_PROCESS_MSG, MAX_DIFF_SIZE, REVIEW_PROMPT}, - errors::AppError, gitea::{GiteaAPI, ReviewPayload}, open_router::OpenRouterClient, }; +#[instrument(skip(gitea_api, open_router_client, http_client, review_payload), err)] pub async fn exec_review( gitea_api: &GiteaAPI, open_router_client: &OpenRouterClient, @@ -17,6 +18,13 @@ pub async fn exec_review( model: &str, review_payload: ReviewPayload, ) -> anyhow::Result<()> { + tracing::info!( + repo = %review_payload.repository.full_name, + pr = review_payload.pull_request.number, + action = %review_payload.action, + "Starting review" + ); + let new_comment = gitea_api .comment( &BOT_PROCESS_MSG.replace("{model}", model), diff --git a/src/errors.rs b/src/errors.rs index ade1b35..d4425b5 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,5 +1,6 @@ use axum::response::IntoResponse; use reqwest::StatusCode; +use tracing::error; #[derive(thiserror::Error, Debug)] pub enum AppError { @@ -55,7 +56,7 @@ impl IntoResponse for AppError { "WebHook sig header is invalid".to_string(), ), AppError::Other(err) => { - sentry_anyhow::capture_anyhow(&err); + error!(%err, "Internal server error"); ( StatusCode::INTERNAL_SERVER_ERROR, "Internal server error".to_string(), diff --git a/src/gitea.rs b/src/gitea.rs index f70c619..e137e0a 100644 --- a/src/gitea.rs +++ b/src/gitea.rs @@ -2,11 +2,9 @@ use std::time::Duration; use serde::Deserialize; use serde_json::{Value, json}; +use tracing::instrument; -use crate::{ - bot::{ReviewItem, ReviewResult}, - errors::AppError, -}; +use crate::{bot::ReviewResult, errors::AppError}; pub struct GiteaAPI { base_url: String, @@ -30,6 +28,7 @@ impl GiteaAPI { }) } + #[instrument(skip(self), err)] pub async fn comment( &self, body: &str, @@ -57,6 +56,7 @@ impl GiteaAPI { res.json::().await.map_err(anyhow::Error::from) } + #[instrument(skip(self), err)] pub async fn edit_comment( &self, body: &str, @@ -84,6 +84,7 @@ impl GiteaAPI { Ok(()) } + #[instrument(skip(self), err)] pub async fn delete_comment(&self, full_name: &str, comment_id: u64) -> anyhow::Result<()> { let url = format!( "{}/api/v1/repos/{}/issues/comments/{}", @@ -102,6 +103,7 @@ impl GiteaAPI { Ok(()) } + #[instrument(skip(self, review_result), err)] pub async fn post_pull_request_review( &self, review_result: &ReviewResult, diff --git a/src/main.rs b/src/main.rs index 68b2ba6..50b1f07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,6 +44,15 @@ fn main() -> anyhow::Result<()> { async fn run() -> anyhow::Result<()> { let config = env::load_config()?; + + info!( + port = config.http_port, + model = %config.open_router_model, + gitea_url = %config.gitea_url, + bot_name = %config.bot_name, + "Starting Herald" + ); + let bot = Bot::new(config.clone())?; let (tx, rx) = tokio::sync::mpsc::channel::(1); diff --git a/src/open_router.rs b/src/open_router.rs index b5602d5..1a3585a 100644 --- a/src/open_router.rs +++ b/src/open_router.rs @@ -1,6 +1,7 @@ use std::time::Duration; use openrouter_rs::{Message, api::chat::ChatCompletionRequest}; +use tracing::instrument; pub struct ChatResult { pub message: String, @@ -27,6 +28,7 @@ impl OpenRouterClient { }) } + #[instrument(skip(self), err)] pub async fn chat(&self, msg: &str) -> anyhow::Result { let request = ChatCompletionRequest::builder() .model(&self.model)