Merge branch 'better-logs' into 'master'
feat: send logs into admin room See merge request famedly/conduit!6next
commit
49f6ab503a
|
@ -2,6 +2,7 @@ use std::{collections::BTreeMap, convert::TryInto};
|
||||||
|
|
||||||
use super::{State, DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH};
|
use super::{State, DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH};
|
||||||
use crate::{pdu::PduBuilder, utils, ConduitResult, Database, Error, Ruma};
|
use crate::{pdu::PduBuilder, utils, ConduitResult, Database, Error, Ruma};
|
||||||
|
use log::info;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::{
|
api::client::{
|
||||||
error::ErrorKind,
|
error::ErrorKind,
|
||||||
|
@ -510,6 +511,8 @@ pub async fn register_route(
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info!("{} registered on this server", user_id);
|
||||||
|
|
||||||
db.flush().await?;
|
db.flush().await?;
|
||||||
|
|
||||||
Ok(register::Response {
|
Ok(register::Response {
|
||||||
|
@ -686,6 +689,8 @@ pub async fn deactivate_route(
|
||||||
// Remove devices and mark account as deactivated
|
// Remove devices and mark account as deactivated
|
||||||
db.users.deactivate_account(&sender_user)?;
|
db.users.deactivate_account(&sender_user)?;
|
||||||
|
|
||||||
|
info!("{} deactivated their account", sender_user);
|
||||||
|
|
||||||
db.flush().await?;
|
db.flush().await?;
|
||||||
|
|
||||||
Ok(deactivate::Response {
|
Ok(deactivate::Response {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use super::State;
|
use super::State;
|
||||||
use crate::{server_server, ConduitResult, Database, Error, Result, Ruma};
|
use crate::{server_server, ConduitResult, Database, Error, Result, Ruma};
|
||||||
|
use log::info;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::{
|
api::{
|
||||||
client::{
|
client::{
|
||||||
|
@ -82,8 +83,13 @@ pub async fn set_room_visibility_route(
|
||||||
db: State<'_, Database>,
|
db: State<'_, Database>,
|
||||||
body: Ruma<set_room_visibility::Request<'_>>,
|
body: Ruma<set_room_visibility::Request<'_>>,
|
||||||
) -> ConduitResult<set_room_visibility::Response> {
|
) -> ConduitResult<set_room_visibility::Response> {
|
||||||
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
match body.visibility {
|
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)?,
|
room::Visibility::Private => db.rooms.set_public(&body.room_id, false)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use super::State;
|
use super::State;
|
||||||
use crate::{pdu::PduBuilder, ConduitResult, Database, Error, Ruma};
|
use crate::{pdu::PduBuilder, ConduitResult, Database, Error, Ruma};
|
||||||
|
use log::info;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::{
|
api::client::{
|
||||||
error::ErrorKind,
|
error::ErrorKind,
|
||||||
|
@ -323,6 +324,8 @@ pub async fn create_room_route(
|
||||||
db.rooms.set_public(&room_id, true)?;
|
db.rooms.set_public(&room_id, true)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info!("{} created a room", sender_user);
|
||||||
|
|
||||||
db.flush().await?;
|
db.flush().await?;
|
||||||
|
|
||||||
Ok(create_room::Response::new(room_id).into())
|
Ok(create_room::Response::new(room_id).into())
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use super::{State, DEVICE_ID_LENGTH, TOKEN_LENGTH};
|
use super::{State, DEVICE_ID_LENGTH, TOKEN_LENGTH};
|
||||||
use crate::{utils, ConduitResult, Database, Error, Ruma};
|
use crate::{utils, ConduitResult, Database, Error, Ruma};
|
||||||
|
use log::info;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::{
|
api::client::{
|
||||||
error::ErrorKind,
|
error::ErrorKind,
|
||||||
|
@ -93,6 +94,8 @@ pub async fn login_route(
|
||||||
body.initial_device_display_name.clone(),
|
body.initial_device_display_name.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
info!("{} logged in", user_id);
|
||||||
|
|
||||||
db.flush().await?;
|
db.flush().await?;
|
||||||
|
|
||||||
Ok(login::Response {
|
Ok(login::Response {
|
||||||
|
|
|
@ -39,9 +39,7 @@ impl Database {
|
||||||
/// Tries to remove the old database but ignores all errors.
|
/// Tries to remove the old database but ignores all errors.
|
||||||
pub fn try_remove(server_name: &str) -> Result<()> {
|
pub fn try_remove(server_name: &str) -> Result<()> {
|
||||||
let mut path = ProjectDirs::from("xyz", "koesters", "conduit")
|
let mut path = ProjectDirs::from("xyz", "koesters", "conduit")
|
||||||
.ok_or(Error::BadConfig(
|
.ok_or_else(|| Error::bad_config("The OS didn't return a valid home directory path."))?
|
||||||
"The OS didn't return a valid home directory path.",
|
|
||||||
))?
|
|
||||||
.data_dir()
|
.data_dir()
|
||||||
.to_path_buf();
|
.to_path_buf();
|
||||||
path.push(server_name);
|
path.push(server_name);
|
||||||
|
@ -59,15 +57,15 @@ impl Database {
|
||||||
.map(|x| Ok::<_, Error>(x.to_owned()))
|
.map(|x| Ok::<_, Error>(x.to_owned()))
|
||||||
.unwrap_or_else(|_| {
|
.unwrap_or_else(|_| {
|
||||||
let path = ProjectDirs::from("xyz", "koesters", "conduit")
|
let path = ProjectDirs::from("xyz", "koesters", "conduit")
|
||||||
.ok_or(Error::BadConfig(
|
.ok_or_else(|| {
|
||||||
"The OS didn't return a valid home directory path.",
|
Error::bad_config("The OS didn't return a valid home directory path.")
|
||||||
))?
|
})?
|
||||||
.data_dir()
|
.data_dir()
|
||||||
.join(server_name);
|
.join(server_name);
|
||||||
|
|
||||||
Ok(path
|
Ok(path
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or(Error::BadConfig("Database path contains invalid unicode."))?
|
.ok_or_else(|| Error::bad_config("Database path contains invalid unicode."))?
|
||||||
.to_owned())
|
.to_owned())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -79,7 +77,7 @@ impl Database {
|
||||||
.get_int("cache_capacity")
|
.get_int("cache_capacity")
|
||||||
.unwrap_or(1024 * 1024 * 1024),
|
.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)
|
.print_profile_on_drop(false)
|
||||||
.open()?;
|
.open()?;
|
||||||
|
|
|
@ -62,12 +62,12 @@ impl Globals {
|
||||||
.unwrap_or("localhost")
|
.unwrap_or("localhost")
|
||||||
.to_string()
|
.to_string()
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| Error::BadConfig("Invalid server_name."))?,
|
.map_err(|_| Error::bad_config("Invalid server_name."))?,
|
||||||
max_request_size: config
|
max_request_size: config
|
||||||
.get_int("max_request_size")
|
.get_int("max_request_size")
|
||||||
.unwrap_or(20 * 1024 * 1024) // Default to 20 MB
|
.unwrap_or(20 * 1024 * 1024) // Default to 20 MB
|
||||||
.try_into()
|
.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),
|
registration_disabled: config.get_bool("registration_disabled").unwrap_or(false),
|
||||||
encryption_disabled: config.get_bool("encryption_disabled").unwrap_or(false),
|
encryption_disabled: config.get_bool("encryption_disabled").unwrap_or(false),
|
||||||
federation_enabled: config.get_bool("federation_enabled").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 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 thiserror::Error;
|
||||||
|
|
||||||
|
use crate::{database::admin::AdminCommand, Database};
|
||||||
|
|
||||||
#[cfg(feature = "conduit_bin")]
|
#[cfg(feature = "conduit_bin")]
|
||||||
use {
|
use {
|
||||||
crate::RumaResponse,
|
crate::RumaResponse,
|
||||||
|
@ -53,6 +60,11 @@ impl Error {
|
||||||
error!("BadDatabase: {}", message);
|
error!("BadDatabase: {}", message);
|
||||||
Self::BadDatabase(message)
|
Self::BadDatabase(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bad_config(message: &'static str) -> Self {
|
||||||
|
error!("BadConfig: {}", message);
|
||||||
|
Self::BadConfig(message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "conduit_bin")]
|
#[cfg(feature = "conduit_bin")]
|
||||||
|
@ -95,3 +107,50 @@ where
|
||||||
.respond_to(r)
|
.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;
|
mod utils;
|
||||||
|
|
||||||
pub use database::Database;
|
pub use database::Database;
|
||||||
pub use error::{Error, Result};
|
pub use error::{ConduitLogger, Error, Result};
|
||||||
|
use log::LevelFilter;
|
||||||
pub use pdu::PduEvent;
|
pub use pdu::PduEvent;
|
||||||
pub use rocket::State;
|
pub use rocket::State;
|
||||||
pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse};
|
pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse};
|
||||||
|
@ -19,6 +20,9 @@ pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse};
|
||||||
use rocket::{fairing::AdHoc, routes};
|
use rocket::{fairing::AdHoc, routes};
|
||||||
|
|
||||||
fn setup_rocket() -> rocket::Rocket {
|
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()
|
rocket::ignite()
|
||||||
.mount(
|
.mount(
|
||||||
"/",
|
"/",
|
||||||
|
@ -133,6 +137,12 @@ fn setup_rocket() -> rocket::Rocket {
|
||||||
let data = Database::load_or_create(rocket.config().await).expect("valid config");
|
let data = Database::load_or_create(rocket.config().await).expect("valid config");
|
||||||
|
|
||||||
data.sending.start_handler(&data.globals, &data.rooms);
|
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))
|
Ok(rocket.manage(data))
|
||||||
}))
|
}))
|
||||||
|
@ -140,10 +150,5 @@ fn setup_rocket() -> rocket::Rocket {
|
||||||
|
|
||||||
#[rocket::main]
|
#[rocket::main]
|
||||||
async fn 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();
|
setup_rocket().launch().await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ where
|
||||||
handle.read_to_end(&mut body).await.unwrap();
|
handle.read_to_end(&mut body).await.unwrap();
|
||||||
|
|
||||||
let http_request = http_request.body(body.clone()).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) {
|
match <T as Outgoing>::Incoming::try_from(http_request) {
|
||||||
Ok(t) => Success(Ruma {
|
Ok(t) => Success(Ruma {
|
||||||
|
|
|
@ -58,12 +58,12 @@ where
|
||||||
T: Debug,
|
T: Debug,
|
||||||
{
|
{
|
||||||
if !globals.federation_enabled() {
|
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()
|
let resolver = AsyncResolver::tokio_from_system_conf().await.map_err(|_| {
|
||||||
.await
|
Error::bad_config("Failed to set up trust dns resolver with system config.")
|
||||||
.map_err(|_| Error::BadConfig("Failed to set up trust dns resolver with system config."))?;
|
})?;
|
||||||
|
|
||||||
let mut host = None;
|
let mut host = None;
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ where
|
||||||
#[cfg_attr(feature = "conduit_bin", get("/_matrix/federation/v1/version"))]
|
#[cfg_attr(feature = "conduit_bin", get("/_matrix/federation/v1/version"))]
|
||||||
pub fn get_server_version(db: State<'_, Database>) -> ConduitResult<get_server_version::Response> {
|
pub fn get_server_version(db: State<'_, Database>) -> ConduitResult<get_server_version::Response> {
|
||||||
if !db.globals.federation_enabled() {
|
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 {
|
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<'_>>,
|
body: Ruma<get_public_rooms_filtered::v1::Request<'_>>,
|
||||||
) -> ConduitResult<get_public_rooms_filtered::v1::Response> {
|
) -> ConduitResult<get_public_rooms_filtered::v1::Response> {
|
||||||
if !db.globals.federation_enabled() {
|
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(
|
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<'_>>,
|
body: Ruma<get_public_rooms::v1::Request<'_>>,
|
||||||
) -> ConduitResult<get_public_rooms::v1::Response> {
|
) -> ConduitResult<get_public_rooms::v1::Response> {
|
||||||
if !db.globals.federation_enabled() {
|
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(
|
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<'_>>,
|
body: Ruma<send_transaction_message::v1::Request<'_>>,
|
||||||
) -> ConduitResult<send_transaction_message::v1::Response> {
|
) -> ConduitResult<send_transaction_message::v1::Response> {
|
||||||
if !db.globals.federation_enabled() {
|
if !db.globals.federation_enabled() {
|
||||||
return Err(Error::BadConfig("Federation is disabled."));
|
return Err(Error::bad_config("Federation is disabled."));
|
||||||
}
|
}
|
||||||
|
|
||||||
//dbg!(&*body);
|
//dbg!(&*body);
|
||||||
|
@ -423,7 +423,7 @@ pub fn get_missing_events_route<'a>(
|
||||||
body: Ruma<get_missing_events::v1::Request<'_>>,
|
body: Ruma<get_missing_events::v1::Request<'_>>,
|
||||||
) -> ConduitResult<get_missing_events::v1::Response> {
|
) -> ConduitResult<get_missing_events::v1::Response> {
|
||||||
if !db.globals.federation_enabled() {
|
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();
|
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<'_>>,
|
body: Ruma<get_profile_information::v1::Request<'_>>,
|
||||||
) -> ConduitResult<get_profile_information::v1::Response> {
|
) -> ConduitResult<get_profile_information::v1::Response> {
|
||||||
if !db.globals.federation_enabled() {
|
if !db.globals.federation_enabled() {
|
||||||
return Err(Error::BadConfig("Federation is disabled."));
|
return Err(Error::bad_config("Federation is disabled."));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut displayname = None;
|
let mut displayname = None;
|
||||||
|
@ -500,7 +500,7 @@ pub fn get_user_devices_route<'a>(
|
||||||
body: Ruma<membership::v1::Request<'_>>,
|
body: Ruma<membership::v1::Request<'_>>,
|
||||||
) -> ConduitResult<get_profile_information::v1::Response> {
|
) -> ConduitResult<get_profile_information::v1::Response> {
|
||||||
if !db.globals.federation_enabled() {
|
if !db.globals.federation_enabled() {
|
||||||
return Err(Error::BadConfig("Federation is disabled."));
|
return Err(Error::bad_config("Federation is disabled."));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut displayname = None;
|
let mut displayname = None;
|
||||||
|
|
Loading…
Reference in New Issue