Merge branch 'better-logs' into 'master'
feat: send logs into admin room See merge request famedly/conduit!6
This commit is contained in:
		
						commit
						49f6ab503a
					
				
					 10 changed files with 109 additions and 30 deletions
				
			
		|  | @ -2,6 +2,7 @@ use std::{collections::BTreeMap, convert::TryInto}; | |||
| 
 | ||||
| use super::{State, DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH}; | ||||
| use crate::{pdu::PduBuilder, utils, ConduitResult, Database, Error, Ruma}; | ||||
| use log::info; | ||||
| use ruma::{ | ||||
|     api::client::{ | ||||
|         error::ErrorKind, | ||||
|  | @ -510,6 +511,8 @@ pub async fn register_route( | |||
|         )?; | ||||
|     } | ||||
| 
 | ||||
|     info!("{} registered on this server", user_id); | ||||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(register::Response { | ||||
|  | @ -686,6 +689,8 @@ pub async fn deactivate_route( | |||
|     // Remove devices and mark account as deactivated
 | ||||
|     db.users.deactivate_account(&sender_user)?; | ||||
| 
 | ||||
|     info!("{} deactivated their account", sender_user); | ||||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(deactivate::Response { | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| use super::State; | ||||
| use crate::{server_server, ConduitResult, Database, Error, Result, Ruma}; | ||||
| use log::info; | ||||
| use ruma::{ | ||||
|     api::{ | ||||
|         client::{ | ||||
|  | @ -82,8 +83,13 @@ pub async fn set_room_visibility_route( | |||
|     db: State<'_, Database>, | ||||
|     body: Ruma<set_room_visibility::Request<'_>>, | ||||
| ) -> ConduitResult<set_room_visibility::Response> { | ||||
|     let sender_user = body.sender_user.as_ref().expect("user is authenticated"); | ||||
| 
 | ||||
|     match body.visibility { | ||||
|         room::Visibility::Public => db.rooms.set_public(&body.room_id, true)?, | ||||
|         room::Visibility::Public => { | ||||
|             db.rooms.set_public(&body.room_id, true)?; | ||||
|             info!("{} made {} public", sender_user, body.room_id); | ||||
|         } | ||||
|         room::Visibility::Private => db.rooms.set_public(&body.room_id, false)?, | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| use super::State; | ||||
| use crate::{pdu::PduBuilder, ConduitResult, Database, Error, Ruma}; | ||||
| use log::info; | ||||
| use ruma::{ | ||||
|     api::client::{ | ||||
|         error::ErrorKind, | ||||
|  | @ -323,6 +324,8 @@ pub async fn create_room_route( | |||
|         db.rooms.set_public(&room_id, true)?; | ||||
|     } | ||||
| 
 | ||||
|     info!("{} created a room", sender_user); | ||||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(create_room::Response::new(room_id).into()) | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| use super::{State, DEVICE_ID_LENGTH, TOKEN_LENGTH}; | ||||
| use crate::{utils, ConduitResult, Database, Error, Ruma}; | ||||
| use log::info; | ||||
| use ruma::{ | ||||
|     api::client::{ | ||||
|         error::ErrorKind, | ||||
|  | @ -93,6 +94,8 @@ pub async fn login_route( | |||
|         body.initial_device_display_name.clone(), | ||||
|     )?; | ||||
| 
 | ||||
|     info!("{} logged in", user_id); | ||||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(login::Response { | ||||
|  |  | |||
|  | @ -39,9 +39,7 @@ impl Database { | |||
|     /// Tries to remove the old database but ignores all errors.
 | ||||
|     pub fn try_remove(server_name: &str) -> Result<()> { | ||||
|         let mut path = ProjectDirs::from("xyz", "koesters", "conduit") | ||||
|             .ok_or(Error::BadConfig( | ||||
|                 "The OS didn't return a valid home directory path.", | ||||
|             ))? | ||||
|             .ok_or_else(|| Error::bad_config("The OS didn't return a valid home directory path."))? | ||||
|             .data_dir() | ||||
|             .to_path_buf(); | ||||
|         path.push(server_name); | ||||
|  | @ -59,15 +57,15 @@ impl Database { | |||
|             .map(|x| Ok::<_, Error>(x.to_owned())) | ||||
|             .unwrap_or_else(|_| { | ||||
|                 let path = ProjectDirs::from("xyz", "koesters", "conduit") | ||||
|                     .ok_or(Error::BadConfig( | ||||
|                         "The OS didn't return a valid home directory path.", | ||||
|                     ))? | ||||
|                     .ok_or_else(|| { | ||||
|                         Error::bad_config("The OS didn't return a valid home directory path.") | ||||
|                     })? | ||||
|                     .data_dir() | ||||
|                     .join(server_name); | ||||
| 
 | ||||
|                 Ok(path | ||||
|                     .to_str() | ||||
|                     .ok_or(Error::BadConfig("Database path contains invalid unicode."))? | ||||
|                     .ok_or_else(|| Error::bad_config("Database path contains invalid unicode."))? | ||||
|                     .to_owned()) | ||||
|             })?; | ||||
| 
 | ||||
|  | @ -79,7 +77,7 @@ impl Database { | |||
|                         .get_int("cache_capacity") | ||||
|                         .unwrap_or(1024 * 1024 * 1024), | ||||
|                 ) | ||||
|                 .map_err(|_| Error::BadConfig("Cache capacity needs to be a u64."))?, | ||||
|                 .map_err(|_| Error::bad_config("Cache capacity needs to be a u64."))?, | ||||
|             ) | ||||
|             .print_profile_on_drop(false) | ||||
|             .open()?; | ||||
|  |  | |||
|  | @ -62,12 +62,12 @@ impl Globals { | |||
|                 .unwrap_or("localhost") | ||||
|                 .to_string() | ||||
|                 .try_into() | ||||
|                 .map_err(|_| Error::BadConfig("Invalid server_name."))?, | ||||
|                 .map_err(|_| Error::bad_config("Invalid server_name."))?, | ||||
|             max_request_size: config | ||||
|                 .get_int("max_request_size") | ||||
|                 .unwrap_or(20 * 1024 * 1024) // Default to 20 MB
 | ||||
|                 .try_into() | ||||
|                 .map_err(|_| Error::BadConfig("Invalid max_request_size."))?, | ||||
|                 .map_err(|_| Error::bad_config("Invalid max_request_size."))?, | ||||
|             registration_disabled: config.get_bool("registration_disabled").unwrap_or(false), | ||||
|             encryption_disabled: config.get_bool("encryption_disabled").unwrap_or(false), | ||||
|             federation_enabled: config.get_bool("federation_enabled").unwrap_or(false), | ||||
|  |  | |||
							
								
								
									
										61
									
								
								src/error.rs
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								src/error.rs
									
									
									
									
									
								
							|  | @ -1,7 +1,14 @@ | |||
| use std::{collections::HashMap, sync::RwLock, time::Duration, time::Instant}; | ||||
| 
 | ||||
| use log::error; | ||||
| use ruma::api::client::{error::ErrorKind, r0::uiaa::UiaaInfo}; | ||||
| use ruma::{ | ||||
|     api::client::{error::ErrorKind, r0::uiaa::UiaaInfo}, | ||||
|     events::room::message, | ||||
| }; | ||||
| use thiserror::Error; | ||||
| 
 | ||||
| use crate::{database::admin::AdminCommand, Database}; | ||||
| 
 | ||||
| #[cfg(feature = "conduit_bin")] | ||||
| use { | ||||
|     crate::RumaResponse, | ||||
|  | @ -53,6 +60,11 @@ impl Error { | |||
|         error!("BadDatabase: {}", message); | ||||
|         Self::BadDatabase(message) | ||||
|     } | ||||
| 
 | ||||
|     pub fn bad_config(message: &'static str) -> Self { | ||||
|         error!("BadConfig: {}", message); | ||||
|         Self::BadConfig(message) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(feature = "conduit_bin")] | ||||
|  | @ -95,3 +107,50 @@ where | |||
|         .respond_to(r) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct ConduitLogger { | ||||
|     pub db: Database, | ||||
|     pub last_logs: RwLock<HashMap<String, Instant>>, | ||||
| } | ||||
| 
 | ||||
| impl log::Log for ConduitLogger { | ||||
|     fn enabled(&self, _metadata: &log::Metadata<'_>) -> bool { | ||||
|         true | ||||
|     } | ||||
| 
 | ||||
|     fn log(&self, record: &log::Record<'_>) { | ||||
|         let output = format!("{} - {}", record.level(), record.args()); | ||||
| 
 | ||||
|         println!("{}", output); | ||||
| 
 | ||||
|         if self.enabled(record.metadata()) | ||||
|             && record | ||||
|                 .module_path() | ||||
|                 .map_or(false, |path| path.starts_with("conduit::")) | ||||
|         { | ||||
|             if self | ||||
|                 .last_logs | ||||
|                 .read() | ||||
|                 .unwrap() | ||||
|                 .get(&output) | ||||
|                 .map_or(false, |i| i.elapsed() < Duration::from_secs(60 * 30)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if let Ok(mut_last_logs) = &mut self.last_logs.try_write() { | ||||
|                 mut_last_logs.insert(output.clone(), Instant::now()); | ||||
|             } | ||||
| 
 | ||||
|             self.db.admin.send(AdminCommand::SendTextMessage( | ||||
|                 message::TextMessageEventContent { | ||||
|                     body: output, | ||||
|                     formatted: None, | ||||
|                     relates_to: None, | ||||
|                 }, | ||||
|             )); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn flush(&self) {} | ||||
| } | ||||
|  |  | |||
							
								
								
									
										17
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/main.rs
									
									
									
									
									
								
							|  | @ -11,7 +11,8 @@ mod ruma_wrapper; | |||
| mod utils; | ||||
| 
 | ||||
| pub use database::Database; | ||||
| pub use error::{Error, Result}; | ||||
| pub use error::{ConduitLogger, Error, Result}; | ||||
| use log::LevelFilter; | ||||
| pub use pdu::PduEvent; | ||||
| pub use rocket::State; | ||||
| pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse}; | ||||
|  | @ -19,6 +20,9 @@ pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse}; | |||
| use rocket::{fairing::AdHoc, routes}; | ||||
| 
 | ||||
| fn setup_rocket() -> rocket::Rocket { | ||||
|     // Force log level off, so we can use our own logger
 | ||||
|     std::env::set_var("ROCKET_LOG", "off"); | ||||
| 
 | ||||
|     rocket::ignite() | ||||
|         .mount( | ||||
|             "/", | ||||
|  | @ -133,6 +137,12 @@ fn setup_rocket() -> rocket::Rocket { | |||
|             let data = Database::load_or_create(rocket.config().await).expect("valid config"); | ||||
| 
 | ||||
|             data.sending.start_handler(&data.globals, &data.rooms); | ||||
|             log::set_boxed_logger(Box::new(ConduitLogger { | ||||
|                 db: data.clone(), | ||||
|                 last_logs: Default::default(), | ||||
|             })) | ||||
|             .unwrap(); | ||||
|             log::set_max_level(LevelFilter::Info); | ||||
| 
 | ||||
|             Ok(rocket.manage(data)) | ||||
|         })) | ||||
|  | @ -140,10 +150,5 @@ fn setup_rocket() -> rocket::Rocket { | |||
| 
 | ||||
| #[rocket::main] | ||||
| async fn main() { | ||||
|     // Default log level
 | ||||
|     if std::env::var("ROCKET_LOG").is_err() { | ||||
|         std::env::set_var("ROCKET_LOG", "critical"); | ||||
|     } | ||||
| 
 | ||||
|     setup_rocket().launch().await.unwrap(); | ||||
| } | ||||
|  |  | |||
|  | @ -97,7 +97,7 @@ where | |||
|             handle.read_to_end(&mut body).await.unwrap(); | ||||
| 
 | ||||
|             let http_request = http_request.body(body.clone()).unwrap(); | ||||
|             log::info!("{:?}", http_request); | ||||
|             log::debug!("{:?}", http_request); | ||||
| 
 | ||||
|             match <T as Outgoing>::Incoming::try_from(http_request) { | ||||
|                 Ok(t) => Success(Ruma { | ||||
|  |  | |||
|  | @ -58,12 +58,12 @@ where | |||
|     T: Debug, | ||||
| { | ||||
|     if !globals.federation_enabled() { | ||||
|         return Err(Error::BadConfig("Federation is disabled.")); | ||||
|         return Err(Error::bad_config("Federation is disabled.")); | ||||
|     } | ||||
| 
 | ||||
|     let resolver = AsyncResolver::tokio_from_system_conf() | ||||
|         .await | ||||
|         .map_err(|_| Error::BadConfig("Failed to set up trust dns resolver with system config."))?; | ||||
|     let resolver = AsyncResolver::tokio_from_system_conf().await.map_err(|_| { | ||||
|         Error::bad_config("Failed to set up trust dns resolver with system config.") | ||||
|     })?; | ||||
| 
 | ||||
|     let mut host = None; | ||||
| 
 | ||||
|  | @ -213,7 +213,7 @@ where | |||
| #[cfg_attr(feature = "conduit_bin", get("/_matrix/federation/v1/version"))] | ||||
| pub fn get_server_version(db: State<'_, Database>) -> ConduitResult<get_server_version::Response> { | ||||
|     if !db.globals.federation_enabled() { | ||||
|         return Err(Error::BadConfig("Federation is disabled.")); | ||||
|         return Err(Error::bad_config("Federation is disabled.")); | ||||
|     } | ||||
| 
 | ||||
|     Ok(get_server_version::Response { | ||||
|  | @ -276,7 +276,7 @@ pub async fn get_public_rooms_filtered_route( | |||
|     body: Ruma<get_public_rooms_filtered::v1::Request<'_>>, | ||||
| ) -> ConduitResult<get_public_rooms_filtered::v1::Response> { | ||||
|     if !db.globals.federation_enabled() { | ||||
|         return Err(Error::BadConfig("Federation is disabled.")); | ||||
|         return Err(Error::bad_config("Federation is disabled.")); | ||||
|     } | ||||
| 
 | ||||
|     let response = client_server::get_public_rooms_filtered_helper( | ||||
|  | @ -323,7 +323,7 @@ pub async fn get_public_rooms_route( | |||
|     body: Ruma<get_public_rooms::v1::Request<'_>>, | ||||
| ) -> ConduitResult<get_public_rooms::v1::Response> { | ||||
|     if !db.globals.federation_enabled() { | ||||
|         return Err(Error::BadConfig("Federation is disabled.")); | ||||
|         return Err(Error::bad_config("Federation is disabled.")); | ||||
|     } | ||||
| 
 | ||||
|     let response = client_server::get_public_rooms_filtered_helper( | ||||
|  | @ -370,7 +370,7 @@ pub fn send_transaction_message_route<'a>( | |||
|     body: Ruma<send_transaction_message::v1::Request<'_>>, | ||||
| ) -> ConduitResult<send_transaction_message::v1::Response> { | ||||
|     if !db.globals.federation_enabled() { | ||||
|         return Err(Error::BadConfig("Federation is disabled.")); | ||||
|         return Err(Error::bad_config("Federation is disabled.")); | ||||
|     } | ||||
| 
 | ||||
|     //dbg!(&*body);
 | ||||
|  | @ -423,7 +423,7 @@ pub fn get_missing_events_route<'a>( | |||
|     body: Ruma<get_missing_events::v1::Request<'_>>, | ||||
| ) -> ConduitResult<get_missing_events::v1::Response> { | ||||
|     if !db.globals.federation_enabled() { | ||||
|         return Err(Error::BadConfig("Federation is disabled.")); | ||||
|         return Err(Error::bad_config("Federation is disabled.")); | ||||
|     } | ||||
| 
 | ||||
|     let mut queued_events = body.latest_events.clone(); | ||||
|  | @ -468,7 +468,7 @@ pub fn get_profile_information_route<'a>( | |||
|     body: Ruma<get_profile_information::v1::Request<'_>>, | ||||
| ) -> ConduitResult<get_profile_information::v1::Response> { | ||||
|     if !db.globals.federation_enabled() { | ||||
|         return Err(Error::BadConfig("Federation is disabled.")); | ||||
|         return Err(Error::bad_config("Federation is disabled.")); | ||||
|     } | ||||
| 
 | ||||
|     let mut displayname = None; | ||||
|  | @ -500,7 +500,7 @@ pub fn get_user_devices_route<'a>( | |||
|     body: Ruma<membership::v1::Request<'_>>, | ||||
| ) -> ConduitResult<get_profile_information::v1::Response> { | ||||
|     if !db.globals.federation_enabled() { | ||||
|         return Err(Error::BadConfig("Federation is disabled.")); | ||||
|         return Err(Error::bad_config("Federation is disabled.")); | ||||
|     } | ||||
| 
 | ||||
|     let mut displayname = None; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue