Added logging to bot
+ Cleaned up error handling to make it easier to handle multiple error levelsmain
parent
199516f3cc
commit
c45bb592db
|
@ -442,11 +442,13 @@ dependencies = [
|
|||
"async-trait",
|
||||
"config",
|
||||
"geoffrey_models",
|
||||
"log",
|
||||
"reqwest",
|
||||
"serde 1.0.130",
|
||||
"serde_json",
|
||||
"serde_plain",
|
||||
"serenity",
|
||||
"simple_logger",
|
||||
"structopt",
|
||||
"tokio",
|
||||
]
|
||||
|
@ -471,6 +473,7 @@ name = "geoffrey_models"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"log",
|
||||
"serde 1.0.130",
|
||||
"serde_json",
|
||||
]
|
||||
|
|
|
@ -2,37 +2,7 @@ use log::{LevelFilter, SetLoggerError};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use simple_logger::SimpleLogger;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub enum LogLevel {
|
||||
None,
|
||||
Warn,
|
||||
Info,
|
||||
Debug,
|
||||
}
|
||||
|
||||
impl From<&str> for LogLevel {
|
||||
#[allow(clippy::wildcard_in_or_patterns)]
|
||||
fn from(s: &str) -> Self {
|
||||
let s = s.to_lowercase();
|
||||
match s.as_str() {
|
||||
"warn" | "w" => LogLevel::Warn,
|
||||
"info" | "i" => LogLevel::Info,
|
||||
"debug" | "d" => LogLevel::Debug,
|
||||
"none" | _ => LogLevel::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LogLevel> for LevelFilter {
|
||||
fn from(l: LogLevel) -> Self {
|
||||
match l {
|
||||
LogLevel::None => LevelFilter::Off,
|
||||
LogLevel::Warn => LevelFilter::Warn,
|
||||
LogLevel::Info => LevelFilter::Info,
|
||||
LogLevel::Debug => LevelFilter::Debug,
|
||||
}
|
||||
}
|
||||
}
|
||||
use geoffrey_models::logging::LogLevel;
|
||||
|
||||
pub fn init_logging(log_level: LogLevel) -> Result<(), SetLoggerError> {
|
||||
SimpleLogger::new()
|
||||
|
|
|
@ -1,24 +1,28 @@
|
|||
mod commands;
|
||||
mod config;
|
||||
mod context;
|
||||
mod helper;
|
||||
mod logging;
|
||||
|
||||
use crate::commands::add_token::AddToken;
|
||||
use crate::commands::{command_filter, Command};
|
||||
use crate::config::GeoffreyAPIConfig;
|
||||
use crate::context::Context;
|
||||
use crate::logging::{init_logging, LogLevel};
|
||||
use geoffrey_models::models::parameters::add_token_params::AddTokenParams;
|
||||
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||
use geoffrey_models::models::token::Permissions;
|
||||
use std::convert::TryFrom;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
use geoffrey_models::logging::LogLevel;
|
||||
use geoffrey_models::models::parameters::add_token_params::AddTokenParams;
|
||||
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||
use geoffrey_models::models::token::Permissions;
|
||||
|
||||
use crate::commands::{Command, command_filter};
|
||||
use crate::commands::add_token::AddToken;
|
||||
use crate::config::GeoffreyAPIConfig;
|
||||
use crate::context::Context;
|
||||
use crate::logging::init_logging;
|
||||
|
||||
mod commands;
|
||||
mod config;
|
||||
mod context;
|
||||
mod helper;
|
||||
mod logging;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, GeoffreyAPIError>;
|
||||
|
||||
#[derive(Debug, StructOpt, Clone)]
|
||||
|
|
|
@ -16,3 +16,5 @@ serde_plain = "1.0.0"
|
|||
async-trait = "0.1.51"
|
||||
config = "0.11.0"
|
||||
structopt = "0.3.21"
|
||||
log = "0.4.14"
|
||||
simple_logger = "1.13.0"
|
||||
|
|
|
@ -98,33 +98,29 @@ pub trait BotCommand {
|
|||
resp
|
||||
} else {
|
||||
match err {
|
||||
CommandError::GeoffreyApi(err) => match err {
|
||||
GeoffreyAPIError::PlayerNotRegistered => {
|
||||
"You need to register before using this command!".to_string()
|
||||
}
|
||||
GeoffreyAPIError::EntryNotFound => {
|
||||
CommandError::GeoffreyApi(GeoffreyAPIError::PlayerNotRegistered) => {
|
||||
"You need to register before using this command!".to_string()
|
||||
}
|
||||
CommandError::GeoffreyApi(GeoffreyAPIError::EntryNotFound) => {
|
||||
"Couldn't find that, maybe look for something that exists?".to_string()
|
||||
}
|
||||
GeoffreyAPIError::PermissionInsufficient => {
|
||||
"Looks like you don't have permission for that.".to_string()
|
||||
}
|
||||
GeoffreyAPIError::EntryNotUnique => {
|
||||
"Slow down, I already know that thing. Try a new name.".to_string()
|
||||
}
|
||||
GeoffreyAPIError::DatabaseError(_) => "How the heck u mess that up".to_string(),
|
||||
GeoffreyAPIError::TokenNotAuthorized => "WHO ARE YOU????".to_string(),
|
||||
GeoffreyAPIError::MultipleLocationsMatch => {
|
||||
"I couldn't match a single location, narrow down your search".to_string()
|
||||
}
|
||||
GeoffreyAPIError::ParameterInvalid(err) => {
|
||||
format!(
|
||||
"Welp, you some how messed up the {} parameter, great job",
|
||||
err
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
CommandError::GeoffreyApi(GeoffreyAPIError::PermissionInsufficient) => {
|
||||
"Looks like you don't have permission for that.".to_string()
|
||||
}
|
||||
CommandError::GeoffreyApi(GeoffreyAPIError::EntryNotUnique) => {
|
||||
"Slow down, I already know that thing. Try a new name.".to_string()
|
||||
}
|
||||
CommandError::GeoffreyApi(GeoffreyAPIError::MultipleLocationsMatch) => {
|
||||
"I couldn't match a single location, narrow down your search".to_string()
|
||||
}
|
||||
CommandError::GeoffreyApi(GeoffreyAPIError::ParameterInvalid(err)) => {
|
||||
format!(
|
||||
"Welp, you some how messed up the {} parameter, great job",
|
||||
err
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
println!("GeoffreyBot got an unhandled error: {}", err);
|
||||
log::warn!("GeoffreyBot got an unhandled error: {}", err);
|
||||
format!("OOPSIE WOOPSIE!! Uwu We made a fucky wucky!! A wittle fucko boingo! The admins at our \
|
||||
headquarters are working VEWY HAWD to fix this! (Error in command {})", Self::command_name())
|
||||
}
|
||||
|
@ -149,6 +145,8 @@ pub trait BotCommand {
|
|||
) -> Result<String, CommandError> {
|
||||
let mut args = Self::process_arguments(command_interact).await?;
|
||||
|
||||
log::info!("Running command {}, with args {:?}", Self::command_name(), args);
|
||||
|
||||
args.set_token(ctx.cfg.api.token.clone());
|
||||
args.set_user_id(user_id);
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
use log::{LevelFilter, SetLoggerError};
|
||||
use simple_logger::SimpleLogger;
|
||||
|
||||
use geoffrey_models::logging::LogLevel;
|
||||
|
||||
pub fn init_logging(log_level: LogLevel) -> Result<(), SetLoggerError> {
|
||||
SimpleLogger::new()
|
||||
.with_level(LevelFilter::Warn)
|
||||
.with_module_level("geoffrey_bot", log_level.into())
|
||||
.init()
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
mod bot;
|
||||
mod configs;
|
||||
mod context;
|
||||
mod logging;
|
||||
|
||||
use crate::bot::create_commands;
|
||||
use crate::configs::GeoffreyBotConfig;
|
||||
|
@ -22,12 +23,22 @@ use serenity::{
|
|||
};
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
use geoffrey_models::logging::LogLevel;
|
||||
use crate::logging::init_logging;
|
||||
|
||||
#[derive(Debug, StructOpt, Clone)]
|
||||
#[structopt(name = "GeoffreyBot", about = "Geoffrey Discord Bot")]
|
||||
struct Args {
|
||||
#[structopt(env = "GEOFFREY_BOT_CONFIG", parse(from_os_str))]
|
||||
config: PathBuf,
|
||||
#[structopt(
|
||||
short,
|
||||
long,
|
||||
env = "GEOFFREY_LOG_LEVEL",
|
||||
parse(from_str),
|
||||
default_value = "Info"
|
||||
)]
|
||||
log_level: LogLevel,
|
||||
}
|
||||
|
||||
struct HttpClient;
|
||||
|
@ -41,13 +52,13 @@ struct Handler;
|
|||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn ready(&self, ctx: Context, ready: Ready) {
|
||||
println!("{} is connected!", ready.user.name);
|
||||
log::info!("{} is connected!", ready.user.name);
|
||||
let commands = create_commands(&ctx).await.unwrap();
|
||||
|
||||
println!("The following bot have been registered:");
|
||||
log::debug!("The following bot have been registered:");
|
||||
|
||||
for command in commands {
|
||||
println!(
|
||||
log::debug!(
|
||||
"{}: {} - {:?}",
|
||||
command.name, command.description, command.options
|
||||
);
|
||||
|
@ -92,7 +103,7 @@ impl EventHandler for Handler {
|
|||
.await
|
||||
.unwrap()
|
||||
} else if let Interaction::Ping(_) = interaction {
|
||||
println!("Ping recv'ed");
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,21 +111,30 @@ impl EventHandler for Handler {
|
|||
#[tokio::main]
|
||||
async fn main() {
|
||||
let args: Args = Args::from_args();
|
||||
init_logging(args.log_level).expect("Unable to init logging");
|
||||
|
||||
let cfg = match GeoffreyBotConfig::new(args.config.as_path()) {
|
||||
Ok(cfg) => cfg,
|
||||
Err(e) => {
|
||||
println!("Error opening config: {}", e);
|
||||
log::warn!("Error opening config: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut client = Client::builder(cfg.discord.token.clone())
|
||||
let client = Client::builder(cfg.discord.token.clone())
|
||||
.event_handler(Handler)
|
||||
.application_id(cfg.discord.app_id)
|
||||
.await
|
||||
.expect("Error creating Geoffrey client");
|
||||
.await;
|
||||
|
||||
let mut client = match client {
|
||||
Ok(client) => client,
|
||||
Err(e) => {
|
||||
log::warn!("Unable to init serenity client: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Block for initializing global data
|
||||
{
|
||||
let mut data = client.data.write().await;
|
||||
|
||||
|
@ -124,7 +144,7 @@ async fn main() {
|
|||
})
|
||||
}
|
||||
|
||||
if let Err(why) = client.start().await {
|
||||
println!("Client error: {:?}", why);
|
||||
if let Err(e) = client.start().await {
|
||||
log::warn!("Client error: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,3 +10,4 @@ edition = "2018"
|
|||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
chrono = { version = "0.4.19", features = ["serde"] }
|
||||
log = "0.4.14"
|
||||
|
|
|
@ -4,6 +4,7 @@ use serde::Serialize;
|
|||
use std::fmt::Debug;
|
||||
|
||||
pub mod models;
|
||||
pub mod logging;
|
||||
|
||||
pub trait GeoffreyDatabaseModel: Serialize + DeserializeOwned + Debug {
|
||||
fn id(&self) -> Option<u64>;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
use log::LevelFilter;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub enum LogLevel {
|
||||
None,
|
||||
Warn,
|
||||
Info,
|
||||
Debug,
|
||||
}
|
||||
|
||||
impl From<&str> for LogLevel {
|
||||
#[allow(clippy::wildcard_in_or_patterns)]
|
||||
fn from(s: &str) -> Self {
|
||||
let s = s.to_lowercase();
|
||||
match s.as_str() {
|
||||
"warn" | "w" => LogLevel::Warn,
|
||||
"info" | "i" => LogLevel::Info,
|
||||
"debug" | "d" => LogLevel::Debug,
|
||||
"none" | _ => LogLevel::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LogLevel> for LevelFilter {
|
||||
fn from(l: LogLevel) -> Self {
|
||||
match l {
|
||||
LogLevel::None => LevelFilter::Off,
|
||||
LogLevel::Warn => LevelFilter::Warn,
|
||||
LogLevel::Info => LevelFilter::Info,
|
||||
LogLevel::Debug => LevelFilter::Debug,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue