From 36e5e8afe6606fd085e899cf23cc6e59cab57a73 Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Sun, 20 Sep 2026 19:14:33 +0800 Subject: [PATCH] chore(log): cap container log growth and echo the resolved config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit P2 of the logging plan (the README recipe landed with the code change): - `docker-compose.yml.example`: one `x-logging` anchor applied to all three services. json-file grows without limit by default, so a long-running bot and the proxy in front of it fill the disk; capped at 10m × 3 files. - The startup `config:` line now reports what the process actually resolved — the state DB path (a mistyped `DATA_DIR` or a surprising CWD was invisible until it bit), both TTLs, the caption-quote setting (`off` rather than a bare `0`) and whether a proxy is configured. The proxy URL is never printed (it may embed credentials) and admin ids — chat identifiers — stay at `debug`. Verified: `docker compose config -q` accepts the file, and a scripted fake-API run shows `caption quote off` / `link cache TTL 3600s` under overrides, `proxy=yes` with no credential in any line, and the ids at `debug` only. --- crates/xmedia-bot/src/handlers/mod.rs | 2 ++ crates/xmedia-bot/src/handlers/statics.rs | 5 +++-- crates/xmedia-bot/src/main.rs | 20 ++++++++++++++++++-- docker-compose.yml.example | 12 ++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/crates/xmedia-bot/src/handlers/mod.rs b/crates/xmedia-bot/src/handlers/mod.rs index 398198e..b2dcf81 100644 --- a/crates/xmedia-bot/src/handlers/mod.rs +++ b/crates/xmedia-bot/src/handlers/mod.rs @@ -15,6 +15,8 @@ mod urls; pub use callback::callback_query_handler; pub use commands::register_commands; pub use inline::inline_query_handler; +/// The resolved `$DATA_DIR/task_queue.db` path, for the startup config line. +pub(crate) use statics::db_path; pub use statics::{CHAT_STORE, CONFIG, LINK_CACHE, TASK_QUEUE}; pub use urls::{start_url_workers, stop_url_workers}; diff --git a/crates/xmedia-bot/src/handlers/statics.rs b/crates/xmedia-bot/src/handlers/statics.rs index 28984e3..8c1d8cd 100644 --- a/crates/xmedia-bot/src/handlers/statics.rs +++ b/crates/xmedia-bot/src/handlers/statics.rs @@ -23,8 +23,9 @@ static DB: LazyLock> = LazyLock::new(|| { /// create parent dirs, so the old hardcoded `data/task_queue.db` failed with /// a confusing error when started from a directory without `data/`, and a /// CWD-relative path is a footgun for systemd / cron deployments — `DATA_DIR` -/// lets them pin the state anywhere. -fn db_path() -> std::path::PathBuf { +/// lets them pin the state anywhere. Also read by the startup config line, so +/// the log says where the state actually landed. +pub(crate) fn db_path() -> std::path::PathBuf { let dir = std::env::var("DATA_DIR").unwrap_or_else(|_| "data".to_string()); let dir_path = std::path::Path::new(&dir); std::fs::create_dir_all(dir_path).expect("failed to create data directory"); diff --git a/crates/xmedia-bot/src/main.rs b/crates/xmedia-bot/src/main.rs index 22ddc73..7da7beb 100644 --- a/crates/xmedia-bot/src/main.rs +++ b/crates/xmedia-bot/src/main.rs @@ -67,11 +67,27 @@ async fn main() { log::warn!("failed to register commands: {e}"); } + // The effective tunables, so an operator can see what the process actually + // resolved (a mistyped DATA_DIR or a forgotten TTL override is otherwise + // invisible until it bites). The proxy URL is never printed — it may embed + // credentials — and admin ids are chat identifiers, so they stay at debug. + let quote_chars = match CONFIG.caption_quote_text_chars { + 0 => "off".to_string(), + n => format!("{n} chars"), + }; log::info!( - "config: {} admin(s), edit-message TTL {}s", + "config: {} admin(s), state {}, edit-message TTL {}s, link cache TTL {}s, caption quote {quote_chars}, proxy={}", CONFIG.admin_ids.len(), - CONFIG.edit_message_ttl.as_secs() + crate::handlers::db_path().display(), + CONFIG.edit_message_ttl.as_secs(), + CONFIG.link_cache_ttl.as_secs(), + if std::env::var("TELOXIDE_PROXY").is_ok() { + "yes" + } else { + "no" + } ); + log::debug!("config: admin ids {:?}", CONFIG.admin_ids); // Queue worker: handles typed tasks, dead-letters failed sends to the // task's chat. Both closures use the shared context (the queue requires diff --git a/docker-compose.yml.example b/docker-compose.yml.example index add0ec8..58ef2e2 100644 --- a/docker-compose.yml.example +++ b/docker-compose.yml.example @@ -1,3 +1,12 @@ +# JSON-file logs grow without limit by default: a long-running bot (and the +# proxy in front of it) will fill the disk. One cap, applied to every service +# below via the anchor. +x-logging: &default-logging + driver: json-file + options: + max-size: '10m' + max-file: '3' + services: nginx-proxy: image: nginxproxy/nginx-proxy:1.11.6-alpine @@ -13,6 +22,7 @@ services: labels: - 'com.github.nginx-proxy.nginx' container_name: nginx-proxy + logging: *default-logging acme-companion: image: nginxproxy/acme-companion @@ -28,6 +38,7 @@ services: container_name: acme-companion depends_on: - nginx-proxy + logging: *default-logging tgxmb: image: yoursfunny/telegram-twitter-media-bot:latest @@ -55,6 +66,7 @@ services: depends_on: - nginx-proxy container_name: tgxmb + logging: *default-logging # Webhook mode only: the bot listens on WEBHOOK_PORT; nginx-proxy shows # 502s while this is down, so surface it to the orchestrator. healthcheck: