aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Perry <np@nathanperry.dev>2024-08-16 06:40:25 -0400
committerNathan Perry <np@nathanperry.dev>2024-08-16 06:40:25 -0400
commit5a2dc4070c1d14f22a7671c6f82ca2f4578369bd (patch)
tree4dfa57f42a6cca70f1cac5363b7b547e46318c26
parent728d951b87ae9ba15ca1453d24ce9ce618badd5a (diff)
rework logging to use tracing via grate
-rw-r--r--Cargo.lock46
-rw-r--r--Cargo.toml5
-rw-r--r--src/bin/batch_delmeme.rs8
-rw-r--r--src/bot.rs52
-rw-r--r--src/commands/game.rs22
-rw-r--r--src/commands/meme/create.rs20
-rw-r--r--src/commands/meme/delete.rs4
-rw-r--r--src/commands/meme/history.rs25
-rw-r--r--src/commands/meme/invoke.rs8
-rw-r--r--src/commands/meme/mod.rs4
-rw-r--r--src/commands/playback.rs15
-rw-r--r--src/commands/roll.rs5
-rw-r--r--src/commands/today/mod.rs8
-rw-r--r--src/config.rs12
-rw-r--r--src/db/mod.rs5
-rw-r--r--src/log_setup.rs59
-rw-r--r--src/main.rs2
-rw-r--r--src/util/mod.rs8
-rw-r--r--src/util/windows.rs21
19 files changed, 130 insertions, 199 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4aab3f6..48bce4a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -370,17 +370,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
-name = "colored"
-version = "1.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a5f741c91823341bebf717d4c71bda820630ce065443b58bd1b7451af008355"
-dependencies = [
- "is-terminal",
- "lazy_static",
- "winapi",
-]
-
-[[package]]
name = "command_attr"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -766,16 +755,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]]
-name = "fern"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee"
-dependencies = [
- "colored",
- "log",
-]
-
-[[package]]
name = "finl_unicode"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -981,6 +960,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
+name = "grate"
+version = "0.1.0"
+source = "git+https://pub.npry.dev/grate#be5e81815b1bbda770f00df80009d1b5aec78e3a"
+dependencies = [
+ "cfg-if",
+ "tracing",
+ "tracing-log",
+ "tracing-subscriber",
+]
+
+[[package]]
name = "h2"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1187,17 +1177,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
-name = "is-terminal"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
-dependencies = [
- "hermit-abi",
- "libc",
- "windows-sys 0.52.0",
-]
-
-[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3021,11 +3000,10 @@ dependencies = [
"dotenv",
"envconfig",
"envconfig_derive",
- "fern",
"fnv",
+ "grate",
"itertools",
"lazy_static",
- "log",
"poise",
"rand",
"regex",
diff --git a/Cargo.toml b/Cargo.toml
index 8ccd283..fbac972 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,6 +27,7 @@ windows_autostart_postgres = []
[workspace.dependencies]
lazy_static = "1.4"
rand = "0.8"
+grate = { git = "https://pub.npry.dev/grate" }
thulani_calc.path = "calc"
@@ -34,15 +35,14 @@ thulani_calc.path = "calc"
lazy_static.workspace = true
rand.workspace = true
thulani_calc.workspace = true
+grate.workspace = true
anyhow = "1.0"
thiserror = "1.0"
-log = "0.4"
url = "2.5"
dotenv = "0.15"
chrono = "0.4"
time = "0.3"
-fern = { version = "0.6", features = ["colored"] }
reqwest = { version = "0.11", features = ["json"] }
sha1 = { version = "0.10", features = ["std"] }
regex = "1.10"
@@ -72,6 +72,7 @@ diesel_async_migrations = { version = "0.12", optional = true }
tokio-postgres = { version = "0.7", optional = true, features = ["with-chrono-0_4"] }
deadpool-postgres = { version = "0.13", optional = true }
+
[dependencies.serenity]
version = "0.12"
default-features = false
diff --git a/src/bin/batch_delmeme.rs b/src/bin/batch_delmeme.rs
index 946bbc3..03aa6aa 100644
--- a/src/bin/batch_delmeme.rs
+++ b/src/bin/batch_delmeme.rs
@@ -1,6 +1,8 @@
use clap::Parser;
use diesel_async::AsyncPgConnection;
use dotenv::dotenv;
+use grate::tracing;
+
use thulani::db;
#[derive(clap::Parser)]
@@ -26,14 +28,14 @@ async fn create_demo_meme(conn: &mut AsyncPgConnection, owner: u64) -> anyhow::R
image_id: None,
};
let meme = meme.save(conn, owner).await?;
- log::debug!("created demo meme: {meme:#?}");
+ tracing::debug!("created demo meme: {meme:#?}");
Ok(())
}
#[tokio::main]
pub async fn main() -> anyhow::Result<()> {
- thulani::log_setup::init(false).expect("initializing logging");
+ thulani::log_setup::init();
dotenv().ok();
let opts = Opts::parse();
@@ -45,7 +47,7 @@ pub async fn main() -> anyhow::Result<()> {
}
let memes_deleted = db::del_memes_by_userid(&mut conn, opts.user_id, opts.deleter).await?;
- log::info!("deleted memes: {memes_deleted:?}");
+ tracing::info!("deleted memes: {memes_deleted:?}");
Ok(())
}
diff --git a/src/bot.rs b/src/bot.rs
index ec0bf92..ed6e118 100644
--- a/src/bot.rs
+++ b/src/bot.rs
@@ -13,14 +13,8 @@ use fnv::{
FnvHashMap,
FnvHashSet,
};
+use grate::tracing;
use lazy_static::lazy_static;
-use log::{
- debug,
- error,
- info,
- trace,
- warn,
-};
use poise::{
BoxFuture,
FrameworkError,
@@ -75,11 +69,11 @@ impl EventHandler for Handler {
let guild = r.guilds.iter().find(|g| g.id == CONFIG.discord.guild());
if guild.is_none() {
- info!("bot isn't in configured guild. join here: {:?}", OAUTH_URL.as_str());
+ tracing::info!("bot isn't in configured guild. join here: {:?}", OAUTH_URL.as_str());
return;
}
- info!("connected");
+ tracing::info!("connected");
#[cfg(debug_assertions)]
let botname = "thulani (dev)";
@@ -89,7 +83,7 @@ impl EventHandler for Handler {
if let Some(guild) = guild {
if let Err(e) = guild.id.edit_nickname(&ctx, Some(botname)).await {
- error!("changing nickname: {:?}", e);
+ tracing::error!("changing nickname: {:?}", e);
}
}
@@ -104,7 +98,7 @@ impl EventHandler for Handler {
}
async fn resume(&self, _ctx: Context, _resume: ResumedEvent) {
- info!("reconnected to discord");
+ tracing::info!("reconnected to discord");
}
async fn message_delete(
@@ -153,12 +147,12 @@ lazy_static! {
.and_then(|f| serde_json::from_reader::<_, Vec<u64>>(f).map_err(anyhow::Error::from));
if let Err(ref e) = restrict_ids {
- warn!("opening restrict file: {}", e);
+ tracing::warn!("opening restrict file: {}", e);
}
let result = restrict_ids.unwrap_or_default().into_iter().collect::<FnvHashSet<_>>();
- info!("restricted ids: {result:?}");
+ tracing::info!("restricted ids: {result:?}");
result
};
@@ -167,7 +161,7 @@ lazy_static! {
fn on_err(err: FrameworkError<PoiseData, anyhow::Error>) -> BoxFuture<()> {
Box::pin(async move {
let Some(msg) = err_msg(&err) else {
- warn!("error handler missing poise context");
+ tracing::warn!("error handler missing poise context");
return;
};
@@ -234,7 +228,7 @@ fn on_err(err: FrameworkError<PoiseData, anyhow::Error>) -> BoxFuture<()> {
if content.is_empty() {
if let Err(e) = util::reply(PoiseContext::Prefix(ctx), "what?").await {
- error!("responding to empty message: {e}");
+ tracing::error!("responding to empty message: {e}");
};
return;
@@ -253,14 +247,14 @@ fn on_err(err: FrameworkError<PoiseData, anyhow::Error>) -> BoxFuture<()> {
if let Err(e) =
commands::link_unrecognized(PoiseContext::Prefix(ctx), u).await
{
- error!("processing audio: {e}");
+ tracing::error!("processing audio: {e}");
"BANIC".to_string()
} else {
return;
}
},
Err(e) => {
- error!("processing unrecognized message: {e}");
+ tracing::error!("processing unrecognized message: {e}");
"BANIC".to_string()
},
}
@@ -272,7 +266,7 @@ fn on_err(err: FrameworkError<PoiseData, anyhow::Error>) -> BoxFuture<()> {
)
.await
{
- error!("producing meme for unrecognized: {e}");
+ tracing::error!("producing meme for unrecognized: {e}");
"BANIC".to_string()
} else {
return;
@@ -282,14 +276,14 @@ fn on_err(err: FrameworkError<PoiseData, anyhow::Error>) -> BoxFuture<()> {
_ => "BANIC".to_string(),
};
- error!("error encountered: {err:#?}");
+ tracing::error!("error encountered: {err:#?}");
if let Err(e) = msg.react(ctx, ReactionType::Unicode("❌".to_owned())).await {
- error!("reacting to failed message: {e}");
+ tracing::error!("reacting to failed message: {e}");
}
let cm = CreateMessage::default().content(text).tts(msg.tts);
if let Err(e) = msg.channel_id.send_message(ctx, cm).await {
- error!("sending error to chat: {e}");
+ tracing::error!("sending error to chat: {e}");
}
})
}
@@ -331,7 +325,7 @@ async fn framework() -> poise::Framework<PoiseData, anyhow::Error> {
fn check(ctx: PoiseContext) -> BoxFuture<anyhow::Result<bool>> {
Box::pin(async move {
if !ctx.guild_id().map_or(false, |x| x == CONFIG.discord.guild()) {
- info!(
+ tracing::info!(
"rejecting command '{}' from user '{}': wrong guild",
ctx.command().name,
ctx.author().name
@@ -364,7 +358,7 @@ fn check(ctx: PoiseContext) -> BoxFuture<anyhow::Result<bool>> {
format!("it is {PERMITTED_WEEKDAY:?}")
};
- info!(
+ tracing::info!(
"rejecting command '{}' from user '{}': {}",
ctx.command().name,
ctx.author().name,
@@ -378,7 +372,7 @@ fn check(ctx: PoiseContext) -> BoxFuture<anyhow::Result<bool>> {
}
fn before_handle<'fut>(ctx: PoiseContext<'fut>) -> Pin<Box<dyn Future<Output = ()> + Send + 'fut>> {
- debug!(
+ tracing::debug!(
"got command '{}' from user '{}' ({})",
ctx.command().name,
ctx.author().name,
@@ -390,7 +384,7 @@ fn before_handle<'fut>(ctx: PoiseContext<'fut>) -> Pin<Box<dyn Future<Output = (
fn after_handle(ctx: PoiseContext) -> BoxFuture<()> {
Box::pin(async move {
- trace!("command '{}' completed successfully", ctx.command().name);
+ tracing::trace!("command '{}' completed successfully", ctx.command().name);
})
}
@@ -415,21 +409,21 @@ pub async fn run() -> anyhow::Result<()> {
let shard_manager = client.shard_manager.clone();
let run_handle = tokio::spawn(async move {
- info!("connecting to discord");
+ tracing::info!("connecting to discord");
client.start().await.expect("running discord client");
});
tokio::signal::ctrl_c().await?;
- warn!("got ^C, gracefully halting discord");
+ tracing::warn!("got ^C, gracefully halting discord");
shard_manager.shutdown_all().await;
run_handle.await?;
- info!("discord shutdown");
+ tracing::info!("discord shutdown");
#[cfg(all(windows, feature = "windows_autostart_postgres"))]
unsafe {
if started_pg {
- log::info!("we started postgres, stopping it before shutdown");
+ tracing::info!("we started postgres, stopping it before shutdown");
tokio::task::spawn_blocking(|| util::windows::shutdown_postgres()).await??;
}
diff --git a/src/commands/game.rs b/src/commands/game.rs
index ba9ac69..258feaf 100644
--- a/src/commands/game.rs
+++ b/src/commands/game.rs
@@ -17,13 +17,9 @@ use fnv::{
FnvHashMap,
FnvHashSet,
};
+use grate::tracing;
use itertools::Itertools;
use lazy_static::lazy_static;
-use log::{
- debug,
- error,
- info,
-};
use serde::Deserialize;
use serenity::model::{
guild::Guild,
@@ -86,7 +82,7 @@ lazy_static! {
})
.collect::<FnvHashMap<_, _>>();
- info!(
+ tracing::info!(
"loaded user info for {} users ({:#?})",
result.len(),
result.keys().collect::<Vec<_>>()
@@ -248,14 +244,14 @@ async fn _game(
let Ok(guild) =
guild.guild(&ctx).ok_or_else(|| anyhow!("couldn't find guild"))
else {
- error!("failed retrieving guild");
+ tracing::error!("failed retrieving guild");
return None;
};
get_user_id(guild.borrow(), &u)
};
- debug!("parsed userid {:?}", possible);
+ tracing::debug!("parsed userid {:?}", possible);
match possible {
Ok(x) => Some(x),
@@ -276,7 +272,7 @@ async fn _game(
let res = DISCORD_MAP.get(&uid).map(|s| s.to_lowercase());
if res.is_none() {
- info!("user {uid} is not recognized");
+ tracing::info!("user {uid} is not recognized");
}
res
@@ -314,7 +310,7 @@ async fn _game(
let inferred = users.is_empty();
if inferred && users.len() < 2 || !inferred && users.is_empty() {
- info!("too few known users to make game comparison");
+ tracing::info!("too few known users to make game comparison");
util::reply(ctx, "yer too lonely").await?;
return Ok(());
}
@@ -458,7 +454,7 @@ pub async fn updategaem(ctx: PoiseContext<'_>, user: Option<String>) -> anyhow::
},
};
- debug!("parsed userid {:?}", user);
+ tracing::debug!("parsed userid {:?}", user);
let username = match DISCORD_MAP.get(&user) {
Some(s) => s,
@@ -498,7 +494,7 @@ pub async fn updategaem(ctx: PoiseContext<'_>, user: Option<String>) -> anyhow::
let appid_column = match appid_column {
Some(c) => &spreadsheet[c][1..],
None => {
- error!("didn't find an appid column in the spreadsheet");
+ tracing::error!("didn't find an appid column in the spreadsheet");
util::reply(ctx, "SPREADSHEET BROKE").await?;
return Ok(());
},
@@ -555,7 +551,7 @@ pub async fn updategaem(ctx: PoiseContext<'_>, user: Option<String>) -> anyhow::
let games_owned =
games_owned.response.games.into_iter().map(|ge| ge.app_id).collect::<FnvHashSet<_>>();
- debug!("user owns {} steam games", games_owned.len());
+ tracing::debug!("user owns {} steam games", games_owned.len());
let found_games = missing_appids
.filter_map(|(ai, x)| {
diff --git a/src/commands/meme/create.rs b/src/commands/meme/create.rs
index 185e1f6..a4e9656 100644
--- a/src/commands/meme/create.rs
+++ b/src/commands/meme/create.rs
@@ -2,11 +2,7 @@ use std::process::Stdio;
use anyhow::anyhow;
use diesel::result::Error as DieselError;
-use log::{
- debug,
- error,
- warn,
-};
+use grate::tracing;
use serenity::all::ReactionType;
use tap::Pipe;
use tokio::{
@@ -40,7 +36,7 @@ pub async fn addmeme(
let image = util::msg(ctx).and_then(|msg| msg.attachments.first());
if image.is_none() && text.is_none() {
- warn!("tried to create non-audio meme with no image or text");
+ tracing::warn!("tried to create non-audio meme with no image or text");
util::reply(ctx, "hahAA it's empty xdddd").await?;
return Ok(());
@@ -74,7 +70,7 @@ pub async fn addmeme(
if let Some(DieselError::DatabaseError(DatabaseErrorKind::UniqueViolation, _)) =
e.downcast_ref::<DieselError>()
{
- error!("tried to create meme that already exists");
+ tracing::error!("tried to create meme that already exists");
util::react(ctx, '❌').await?;
util::reply(ctx, "that meme already exists").await?;
@@ -97,7 +93,7 @@ pub async fn addaudiomeme(
audio_str: String,
#[rest] text: Option<String>,
) -> anyhow::Result<()> {
- debug!("running addaudiomeme");
+ tracing::debug!("running addaudiomeme");
let elems = audio_str.split_whitespace().collect::<Vec<_>>();
@@ -113,7 +109,7 @@ pub async fn addaudiomeme(
util::react(ctx, '🔃').await?;
let youtube_url = util::ytdl_url(audio_link.as_str()).await?;
- debug!("got download url: {youtube_url}");
+ tracing::debug!("got download url: {youtube_url}");
let duration_opts = if let Some(e) = end {
vec![
@@ -166,10 +162,10 @@ pub async fn addaudiomeme(
let mut audio_data = Vec::new();
let bytes = audio_reader.read_to_end(&mut audio_data).await?;
- debug!("downloaded audio ({} bytes)", audio_data.len());
+ tracing::debug!("downloaded audio ({} bytes)", audio_data.len());
if bytes == 0 {
- debug!("read 0 bytes from audio reader");
+ tracing::debug!("read 0 bytes from audio reader");
util::unreact(ctx, '🔃').await?;
util::reply(ctx, "🔇🔇🔇🔕🔕🔕🔕🔕🔇🔕🔕🔇🔕🔕📣📢📣📢📣").await?;
@@ -200,7 +196,7 @@ pub async fn addaudiomeme(
if let Some(DieselError::DatabaseError(DatabaseErrorKind::UniqueViolation, _)) =
e.downcast_ref::<DieselError>()
{
- error!("tried to create meme that already exists");
+ tracing::error!("tried to create meme that already exists");
util::react(ctx, ReactionType::Unicode("❌".to_owned())).await?;
util::reply(ctx, "that meme already exists").await?;
diff --git a/src/commands/meme/delete.rs b/src/commands/meme/delete.rs
index 4769cc8..560da28 100644
--- a/src/commands/meme/delete.rs
+++ b/src/commands/meme/delete.rs
@@ -2,7 +2,7 @@ use diesel::{
result::Error as DieselError,
NotFound,
};
-use log::info;
+use grate::tracing;
use serenity::all::ReactionType;
use crate::{
@@ -26,7 +26,7 @@ pub async fn delmeme(ctx: PoiseContext<'_>, title: String) -> anyhow::Result<()>
},
Err(e) => {
if let Some(NotFound) = e.downcast_ref::<DieselError>() {
- info!("attempted to delete nonexistent meme: '{}'", title);
+ tracing::info!("attempted to delete nonexistent meme: '{}'", title);
util::react(ctx, ReactionType::Unicode("❓".to_owned())).await?;
util::reply(ctx, "nice try").await?;
diff --git a/src/commands/meme/history.rs b/src/commands/meme/history.rs
index 68416e5..e3d0de3 100644
--- a/src/commands/meme/history.rs
+++ b/src/commands/meme/history.rs
@@ -3,13 +3,9 @@ use diesel::{
result::Error as DieselError,
NotFound,
};
+use grate::tracing;
use itertools::Itertools;
use lazy_static::lazy_static;
-use log::{
- debug,
- error,
- info,
-};
use serenity::{
futures::{
StreamExt,
@@ -58,7 +54,7 @@ pub async fn wat(ctx: PoiseContext<'_>) -> anyhow::Result<()> {
Ok(x) => x,
Err(e) => {
if let Some(NotFound) = e.downcast_ref::<DieselError>() {
- info!("found no memes in history");
+ tracing::info!("found no memes in history");
util::reply(ctx, "no one has ever memed before").await?;
return Ok(());
@@ -89,7 +85,7 @@ pub async fn wat(ctx: PoiseContext<'_>) -> anyhow::Result<()> {
},
Err(e) => {
if let Some(NotFound) = e.downcast_ref::<DieselError>() {
- info!("last meme not found in database");
+ tracing::info!("last meme not found in database");
util::reply(ctx, "heuueueeeeh?").await?;
return Ok(());
@@ -110,7 +106,10 @@ pub async fn history(ctx: PoiseContext<'_>, n: Option<usize>) -> anyhow::Result<
let n = n.unwrap_or(CONFIG.default_hist);
if n > CONFIG.max_hist {
- debug!("user requested more than MAX_HIST ({}) items from history", CONFIG.max_hist);
+ tracing::debug!(
+ "user requested more than MAX_HIST ({}) items from history",
+ CONFIG.max_hist
+ );
util::reply(ctx, "YER PUSHIN ME OVER THE FUCKIN LINE").await?;
}
@@ -122,13 +121,13 @@ pub async fn history(ctx: PoiseContext<'_>, n: Option<usize>) -> anyhow::Result<
};
if records.is_empty() {
- info!("no memes in history");
+ tracing::info!("no memes in history");
util::reply(ctx, "i don't remember anything :(").await?;
return Ok(());
}
- info!("reporting meme history (len {})", n);
+ tracing::info!("reporting meme history (len {})", n);
let resp = serenity::futures::stream::iter(records.into_iter().enumerate().rev())
.then(|(i, rec)| async move {
@@ -182,7 +181,7 @@ pub async fn history(ctx: PoiseContext<'_>, n: Option<usize>) -> anyhow::Result<
Err(e) => {
if let Some(variant) = e.downcast_ref::<DieselError>() {
if *variant != NotFound {
- error!("error encountered loading meme history: {}", e);
+ tracing::error!("error encountered loading meme history: {}", e);
}
}
@@ -213,7 +212,7 @@ pub async fn stats(ctx: PoiseContext<'_>) -> anyhow::Result<()> {
let mut conn = connection().await?;
let stats = db::stats(&mut conn).await?;
- debug!("reporting stats");
+ tracing::debug!("reporting stats");
let rand_user: User = UserId::new(stats.most_random_meme_user).to_user(&ctx).await?;
let direct_user: User = UserId::new(stats.most_directly_named_meme_user).to_user(&ctx).await?;
@@ -408,7 +407,7 @@ pub async fn query(ctx: PoiseContext<'_>, rest: util::RestVec) -> anyhow::Result
.join("\n");
if result.is_empty() {
- info!("no memes matched query");
+ tracing::info!("no memes matched query");
util::reply(ctx, "no match").await?;
return Ok(());
diff --git a/src/commands/meme/invoke.rs b/src/commands/meme/invoke.rs
index 1d9040d..37a78f5 100644
--- a/src/commands/meme/invoke.rs
+++ b/src/commands/meme/invoke.rs
@@ -2,7 +2,7 @@ use diesel::{
result::Error as DieselError,
NotFound,
};
-use log::info;
+use grate::tracing;
use crate::{
commands::meme::send_meme,
@@ -89,7 +89,7 @@ pub(crate) async fn _meme(
},
Err(e) => {
return if let Some(NotFound) = e.downcast_ref::<DieselError>() {
- info!("requested meme not found in database");
+ tracing::info!("requested meme not found in database");
util::reply(ctx, "c'mon baby, guesstimate").await?;
Ok(())
@@ -123,7 +123,7 @@ async fn rand_meme(ctx: PoiseContext<'_>, audio_playback: AudioPlayback) -> anyh
},
Err(e) => {
if let Some(NotFound) = e.downcast_ref::<DieselError>() {
- info!("random meme not found");
+ tracing::info!("random meme not found");
util::reply(ctx, "i don't know any :(").await?;
return Ok(());
@@ -151,7 +151,7 @@ pub async fn rare_meme(ctx: PoiseContext<'_>) -> anyhow::Result<()> {
},
Err(e) => {
if let Some(NotFound) = e.downcast_ref::<DieselError>() {
- info!("rare meme not found");
+ tracing::info!("rare meme not found");
util::reply(ctx, "i don't know any :(").await?;
return Ok(());
diff --git a/src/commands/meme/mod.rs b/src/commands/meme/mod.rs
index ca7714a..4819c1d 100644
--- a/src/commands/meme/mod.rs
+++ b/src/commands/meme/mod.rs
@@ -1,5 +1,5 @@
use diesel_async::AsyncPgConnection;
-use log::debug;
+use grate::tracing;
use rand::random;
use serenity::{
all::ReactionType,
@@ -70,7 +70,7 @@ async fn send_meme(
let should_tts =
t.content.as_ref().map(|t| !t.is_empty()).unwrap_or(false) && random::<u32>() % 25 == 0;
- debug!("sending meme (tts: {}): {:?}", should_tts, t);
+ tracing::debug!("sending meme (tts: {}): {:?}", should_tts, t);
let image = t.image(conn).await;
let audio = t.audio(conn).await;
diff --git a/src/commands/playback.rs b/src/commands/playback.rs
index 9b74c02..ad24eb3 100644
--- a/src/commands/playback.rs
+++ b/src/commands/playback.rs
@@ -1,16 +1,11 @@
-use std::sync::Arc;
-
-use log::{
- debug,
- info,
- warn,
-};
+use grate::tracing;
use serenity::prelude::*;
use songbird::{
input::YoutubeDl,
Call,
Songbird,
};
+use std::sync::Arc;
use crate::{
bot::HttpKey,
@@ -38,9 +33,9 @@ pub async fn songbird(ctx: PoiseContext<'_>) -> anyhow::Result<(Arc<Songbird>, A
pub async fn _play(ctx: PoiseContext<'_>, url: &url::Url) -> anyhow::Result<()> {
use url::Host;
- debug!("playing '{}'", url);
+ tracing::debug!("playing '{}'", url);
if !url.scheme().starts_with("http") {
- warn!("got bad url argument to play: {}", url);
+ tracing::warn!("got bad url argument to play: {}", url);
util::reply(ctx, "bAD LiNk").await?;
return Ok(());
@@ -52,7 +47,7 @@ pub async fn _play(ctx: PoiseContext<'_>, url: &url::Url) -> anyhow::Result<()>
});
if host.is_some_and(|h| h.to_lowercase().contains("imgur")) {
- info!("detected imgur link");
+ tracing::info!("detected imgur link");
if ctx.author().id == 106160362109272064 {
util::reply(ctx, "fuck you conway").await?;
diff --git a/src/commands/roll.rs b/src/commands/roll.rs
index fd3102c..16fe15f 100644
--- a/src/commands/roll.rs
+++ b/src/commands/roll.rs
@@ -1,4 +1,5 @@
use crate::util;
+use grate::tracing;
/// Roll some number of dice or perform a calculation.
#[poise::command(prefix_command, guild_only, aliases("calc", "calculate"))]
@@ -8,11 +9,11 @@ pub async fn roll<U: Send + Sync>(
) -> anyhow::Result<()> {
match thulani_calc::Calc::eval(&rest) {
Ok(result) => {
- log::debug!("got calc result '{}'", result);
+ tracing::debug!("got calc result '{}'", result);
util::reply(ctx, result.to_string()).await?;
},
Err(e) => {
- log::error!("error encountered reading calc '{}': {}", rest, e);
+ tracing::error!("error encountered reading calc '{}': {}", rest, e);
util::reply(ctx, "I COULDN'T READ THAT YOU FUCK").await?;
},
}
diff --git a/src/commands/today/mod.rs b/src/commands/today/mod.rs
index 7b5fe8d..0b9b857 100644
--- a/src/commands/today/mod.rs
+++ b/src/commands/today/mod.rs
@@ -1,6 +1,6 @@
use chrono::Duration;
+use grate::tracing;
use lazy_static::lazy_static;
-use log::debug;
use rand::{
seq::SliceRandom,
thread_rng,
@@ -76,11 +76,11 @@ pub async fn today(ctx: PoiseContext<'_>, #[rest] _rest: Option<String>) -> anyh
match dt {
Ok(dt) => {
- debug!("overriding with datetime: {dt}");
+ tracing::debug!("overriding with datetime: {dt}");
result = dt;
},
Err(e) => {
- debug!("parsing datetime: {e:?}");
+ tracing::debug!("parsing datetime: {e:?}");
},
};
}
@@ -91,7 +91,7 @@ pub async fn today(ctx: PoiseContext<'_>, #[rest] _rest: Option<String>) -> anyh
let options: Vec<TodayArgs> = ALL.iter().flat_map(|f| f(today)).collect();
- debug!("{} options for {}", options.len(), today);
+ tracing::debug!("{} options for {}", options.len(), today);
let play_args = options.choose(&mut thread_rng());
diff --git a/src/config.rs b/src/config.rs
index 896f82f..046a2be 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,15 +1,15 @@
use std::path::PathBuf;
+use dotenv::dotenv;
+use envconfig::Envconfig;
+use grate::tracing;
+use lazy_static::lazy_static;
use serenity::model::id::{
ChannelId,
GuildId,
UserId,
};
-use dotenv::dotenv;
-use envconfig::Envconfig;
-use lazy_static::lazy_static;
-
lazy_static! {
pub static ref CONFIG: Config = {
dotenv().ok();
@@ -18,13 +18,13 @@ lazy_static! {
};
pub static ref FFMPEG_COMMAND: String = {
let result = CONFIG.ffmpeg.clone().unwrap_or("ffmpeg".to_owned());
- log::debug!("got ffmpeg: {result}");
+ tracing::debug!("got ffmpeg: {result}");
result
};
pub static ref YTDL_COMMAND: String = {
let result = CONFIG.ytdl.clone().unwrap_or("yt-dlp".to_owned());
- log::debug!("got ytdl: {result}");
+ tracing::debug!("got ytdl: {result}");
result
};
diff --git a/src/db/mod.rs b/src/db/mod.rs
index 74f67b1..e8e6596 100644
--- a/src/db/mod.rs
+++ b/src/db/mod.rs
@@ -34,6 +34,7 @@ use diesel_async::{
AsyncPgConnection,
RunQueryDsl,
};
+use grate::tracing;
use serenity::FutureExt;
pub use self::models::*;
@@ -87,9 +88,9 @@ pub async fn connection()
async fn do_migrate(conn: &mut AsyncPgConnection) {
MIGRATE
.get_or_init(|| async move {
- log::info!("running migrations");
+ tracing::info!("running migrations");
MIGRATIONS.run_pending_migrations(conn).await.expect("failed running migrations");
- log::info!("migrations complete");
+ tracing::info!("migrations complete");
})
.await;
}
diff --git a/src/log_setup.rs b/src/log_setup.rs
index e483c2d..ff18483 100644
--- a/src/log_setup.rs
+++ b/src/log_setup.rs
@@ -1,51 +1,18 @@
-use fern::colors::{
- Color,
- ColoredLevelConfig,
-};
+use grate::tracing::Level;
-pub fn init(file_output: bool) -> anyhow::Result<()> {
- let colors = ColoredLevelConfig::new()
- .info(Color::Green)
- .debug(Color::BrightBlue)
- .trace(Color::BrightMagenta);
+pub fn init() {
+ let mut config = grate::Config::default();
- let mut logger = fern::Dispatch::new()
- .level_for("serenity::voice::connection", log::LevelFilter::Error)
- .chain(
- fern::Dispatch::new()
- .format(move |out, message, record| {
- out.finish(format_args!(
- "{} [{}] [{}] {}",
- chrono::Local::now().format("%_m/%_d/%y %l:%M:%S%P"),
- colors.color(record.level()),
- record.target(),
- message
- ))
- })
- .level(log::LevelFilter::Warn)
- .level_for("thulani", log::LevelFilter::Debug)
- .level_for("batch_delmeme", log::LevelFilter::Debug)
- .chain(std::io::stdout()),
- );
+ config.pretty = true;
- if file_output {
- logger = logger.chain(
- fern::Dispatch::new()
- .format(|out, message, record| {
- out.finish(format_args!(
- "{} [{}] [{}] {}",
- chrono::Local::now().format("%_m/%_d/%y %l:%M:%S%P"),
- record.level(),
- record.target(),
- message
- ))
- })
- .level(log::LevelFilter::Info)
- .level_for("thulani", log::LevelFilter::Trace)
- .level_for("batch_delmeme", log::LevelFilter::Trace)
- .chain(fern::log_file("thulani.log").expect("problem creating log file")),
- );
- }
+ config.default_filter = grate::LevelConfig {
+ default_debug_level: Level::INFO,
+ default_release_level: Level::INFO,
+ default_filters: vec![
+ (Level::ERROR, vec!["serenity::voice::connection".to_string()]),
+ (Level::DEBUG, vec!["thulani".to_string(), "batch_delmeme".to_string()]),
+ ],
+ };
- logger.apply().map_err(anyhow::Error::from)
+ grate::init(&config);
}
diff --git a/src/main.rs b/src/main.rs
index e4f2014..db22047 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,6 +7,6 @@
#[tokio::main]
async fn main() -> anyhow::Result<()> {
- thulani::log_setup::init(false).expect("initializing logging");
+ thulani::log_setup::init();
thulani::bot::run().await
}
diff --git a/src/util/mod.rs b/src/util/mod.rs
index b9e5f0f..c5bed98 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -1,8 +1,8 @@
use std::process::Stdio;
use chrono::Duration;
+use grate::tracing;
use lazy_static::lazy_static;
-use log::debug;
use poise::{
CreateReply,
FrameworkError,
@@ -161,7 +161,7 @@ pub async fn send_result(
tts: bool,
) -> anyhow::Result<MessageId> {
let text = text.as_ref();
- debug!("sending message {:?} to channel {:?} (tts: {})", text, channel, tts);
+ tracing::debug!("sending message {:?} to channel {:?} (tts: {})", text, channel, tts);
let result = channel.send_message(ctx, CreateMessage::default().content(text).tts(tts)).await?;
Ok(result.id)
@@ -203,12 +203,12 @@ pub async fn ytdl_url(uri: &str) -> anyhow::Result<String> {
uri,
];
- debug!("downloading info for uri: {uri}");
+ tracing::debug!("downloading info for uri: {uri}");
let mut command = Command::new(&*crate::config::YTDL_COMMAND);
command.args(args).stdin(Stdio::null());
- debug!("running command: {command:?}");
+ tracing::debug!("running command: {command:?}");
let out = command.output().await?;
diff --git a/src/util/windows.rs b/src/util/windows.rs
index 3b1339e..8856aed 100644
--- a/src/util/windows.rs
+++ b/src/util/windows.rs
@@ -1,3 +1,4 @@
+use grate::tracing;
use windows::{
core::{
HSTRING,
@@ -26,17 +27,17 @@ pub unsafe fn ensure_postgres_started() -> windows::core::Result<bool> {
match svc.status.dwCurrentState {
Services::SERVICE_RUNNING => {
- log::info!("postgres was already running, done");
+ tracing::info!("postgres was already running, done");
return Ok(false);
},
Services::SERVICE_START_PENDING => {
- log::info!("postgres was already in startup, done");
+ tracing::info!("postgres was already in startup, done");
return Ok(false);
},
_ => {
- log::info!("postgres is not running: starting it")
+ tracing::info!("postgres is not running: starting it")
},
}
@@ -45,7 +46,7 @@ pub unsafe fn ensure_postgres_started() -> windows::core::Result<bool> {
Services::StartServiceW(service, None)?;
- log::info!("started postgres service");
+ tracing::info!("started postgres service");
Services::CloseServiceHandle(service)?;
Services::CloseServiceHandle(sc_manager)?;
@@ -61,12 +62,12 @@ pub unsafe fn shutdown_postgres() -> windows::core::Result<()> {
)?;
let Some(svc) = get_psql_service(sc_manager)? else {
- log::warn!("wasn't able to find postgres service");
+ tracing::warn!("wasn't able to find postgres service");
return Ok(());
};
if svc.status.dwCurrentState != Services::SERVICE_RUNNING {
- log::warn!("postgres wasn't in running state, not attempting to shut it down");
+ tracing::warn!("postgres wasn't in running state, not attempting to shut it down");
return Ok(());
}
@@ -88,7 +89,7 @@ pub unsafe fn shutdown_postgres() -> windows::core::Result<()> {
&mut params as *mut _ as _,
)?;
- log::info!("stopped postgres service");
+ tracing::info!("stopped postgres service");
Services::CloseServiceHandle(service)?;
Services::CloseServiceHandle(sc_manager)?;
@@ -108,18 +109,18 @@ pub unsafe fn get_psql_service(
1 => {},
0 => {
- log::warn!("unable to identify an installed postgres service");
+ tracing::warn!("unable to identify an installed postgres service");
return Ok(None);
},
other => {
- log::warn!("unable to identify postgres service: {other} potential matches found");
+ tracing::warn!("unable to identify postgres service: {other} potential matches found");
return Ok(None);
},
}
let svc = psql_services.remove(0);
- log::debug!("identified postgres service: {}", svc.name);
+ tracing::debug!("identified postgres service: {}", svc.name);
Ok(Some(svc))
}