diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-02-20 01:23:38 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-02-20 01:23:38 +0100 |
| commit | 5caf1f1db721d6dee2ddb5d0613e8c9914ccf879 (patch) | |
| tree | 7816c2a9e1a5222f8068ab2cf941df55743ba6d3 | |
| parent | 62984a7250c8998556e0258d67964e8e481b243c (diff) | |
| download | jellything-5caf1f1db721d6dee2ddb5d0613e8c9914ccf879.tar jellything-5caf1f1db721d6dee2ddb5d0613e8c9914ccf879.tar.bz2 jellything-5caf1f1db721d6dee2ddb5d0613e8c9914ccf879.tar.zst | |
admin log
| -rw-r--r-- | Cargo.lock | 2 | ||||
| -rw-r--r-- | common/Cargo.toml | 2 | ||||
| -rw-r--r-- | common/src/api.rs | 4 | ||||
| -rw-r--r-- | common/src/internal.rs | 31 | ||||
| -rw-r--r-- | common/src/routes.rs | 3 | ||||
| -rw-r--r-- | server/src/logger.rs | 23 | ||||
| -rw-r--r-- | server/src/routes.rs | 5 | ||||
| -rw-r--r-- | server/src/ui/admin/log.rs | 62 | ||||
| -rw-r--r-- | server/src/ui/admin/mod.rs | 1 | ||||
| -rw-r--r-- | ui/client-scripts/src/log_live.ts | 4 | ||||
| -rw-r--r-- | ui/src/components/admin_log.rs (renamed from ui/src/old/admin/log.rs) | 20 | ||||
| -rw-r--r-- | ui/src/components/mod.rs | 1 | ||||
| -rw-r--r-- | ui/src/lib.rs | 5 | ||||
| -rw-r--r-- | ui/src/scaffold.rs | 4 |
14 files changed, 95 insertions, 72 deletions
@@ -1788,6 +1788,8 @@ version = "0.1.0" dependencies = [ "jellyobject", "jellystream-types", + "serde", + "serde_json", ] [[package]] diff --git a/common/Cargo.toml b/common/Cargo.toml index 4eae9f8..fabd3d2 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -6,3 +6,5 @@ edition = "2024" [dependencies] jellystream-types = { path = "../stream/types" } jellyobject = { path = "object", features = ["json"] } +serde_json = "1.0.149" +serde = { version = "1.0.228", features = ["derive"] } diff --git a/common/src/api.rs b/common/src/api.rs index 3c4e958..12d9243 100644 --- a/common/src/api.rs +++ b/common/src/api.rs @@ -26,11 +26,13 @@ fields! { VIEW_ADMIN_DASHBOARD: () = b"adda"; VIEW_ADMIN_IMPORT: Object = b"adim"; VIEW_ADMIN_INFO: Object = b"adin"; + VIEW_ADMIN_LOG: Object = b"adlo"; ADMIN_IMPORT_BUSY: () = b"busy"; ADMIN_IMPORT_ERROR: &str = b"erro"; // multi ADMIN_INFO_TITLE: &str = b"aiti"; ADMIN_INFO_TEXT: &str = b"aite"; + ADMIN_LOG_MESSAGE: &str = b"aite"; NKU_NODE: Object = b"node"; NKU_UDATA: Object = b"udat"; @@ -38,7 +40,7 @@ fields! { NODELIST_TITLE: &str = b"titl"; NODELIST_DISPLAYSTYLE: Tag = b"dsty"; - NODELIST_ITEM: Object = b"item"; + NODELIST_ITEM: Object = b"item"; // multi MESSAGE_KIND: &str = b"kind"; MESSAGE_TEXT: &str = b"text"; diff --git a/common/src/internal.rs b/common/src/internal.rs index 58a2dae..5aedfc7 100644 --- a/common/src/internal.rs +++ b/common/src/internal.rs @@ -4,9 +4,40 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ +use std::fmt::Display; + use jellyobject::fields; +use serde::{Deserialize, Serialize}; fields! { IM_PATH: &str = b"Ipth"; IM_MTIME: u64 = b"Imtm"; } + +#[derive(Serialize, Deserialize, Clone)] +pub struct LogLine { + pub time: String, + pub module: Option<&'static str>, + pub level: LogLevel, + pub message: String, +} + +#[derive(Serialize, Deserialize, Clone, Copy, PartialEq)] +pub enum LogLevel { + Trace, + Debug, + Info, + Warn, + Error, +} +impl Display for LogLevel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + LogLevel::Trace => "trace", + LogLevel::Debug => "debug", + LogLevel::Info => "info", + LogLevel::Warn => "warn", + LogLevel::Error => "error", + }) + } +}
\ No newline at end of file diff --git a/common/src/routes.rs b/common/src/routes.rs index fcef144..82a6f45 100644 --- a/common/src/routes.rs +++ b/common/src/routes.rs @@ -73,9 +73,6 @@ pub fn u_admin_import_post(incremental: bool) -> String { pub fn u_admin_update_search() -> String { "/admin/update_search".to_string() } -pub fn u_account_register() -> String { - "/account/register".to_owned() -} pub fn u_account_login() -> String { "/account/login".to_owned() } diff --git a/server/src/logger.rs b/server/src/logger.rs index e7419ba..8ba572f 100644 --- a/server/src/logger.rs +++ b/server/src/logger.rs @@ -4,9 +4,9 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use chrono::{DateTime, Utc}; +use chrono::Utc; +use jellycommon::internal::{LogLevel, LogLine}; use log::Level; -use serde::{Deserialize, Serialize}; use std::{ collections::VecDeque, sync::{Arc, LazyLock, RwLock}, @@ -14,7 +14,6 @@ use std::{ use tokio::sync::broadcast; const MAX_LOG_LEN: usize = 4096; - static LOGGER: LazyLock<Log> = LazyLock::new(Log::default); pub fn setup_logger() { @@ -22,22 +21,6 @@ pub fn setup_logger() { log::set_max_level(log::LevelFilter::Debug); } -pub struct LogLine { - pub time: DateTime<Utc>, - pub module: Option<&'static str>, - pub level: LogLevel, - pub message: String, -} - -#[derive(Serialize, Deserialize, Clone, Copy, PartialEq)] -pub enum LogLevel { - Trace, - Debug, - Info, - Warn, - Error, -} - type LogBuffer = VecDeque<Arc<LogLine>>; pub struct Log { @@ -92,7 +75,7 @@ impl Log { fn do_log(&self, record: &log::Record) { let time = Utc::now(); let line = Arc::new(LogLine { - time, + time: time.to_rfc3339(), module: record.module_path_static(), level: match record.level() { Level::Error => LogLevel::Error, diff --git a/server/src/routes.rs b/server/src/routes.rs index acf6ffd..4a875f4 100644 --- a/server/src/routes.rs +++ b/server/src/routes.rs @@ -15,6 +15,7 @@ use crate::{ account::{r_account_login, r_account_login_post, r_account_logout, r_account_logout_post}, admin::{ import::{r_admin_import, r_admin_import_post, r_admin_import_stream}, + log::{r_admin_log, r_admin_log_stream}, r_admin_dashboard, }, assets::r_image, @@ -84,8 +85,8 @@ pub(super) fn build_rocket(state: Arc<State>) -> Rocket<Build> { r_admin_import_post, r_admin_import_stream, // r_admin_invite, - // r_admin_log_stream, - // r_admin_log, + r_admin_log_stream, + r_admin_log, // r_admin_remove_invite, // r_admin_remove_user, // r_admin_update_search, diff --git a/server/src/ui/admin/log.rs b/server/src/ui/admin/log.rs index da70360..0965a25 100644 --- a/server/src/ui/admin/log.rs +++ b/server/src/ui/admin/log.rs @@ -3,50 +3,60 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{request_info::RequestInfo, ui::error::MyResult}; +use crate::{ + logger::{get_log_buffer, get_log_stream}, + request_info::RequestInfo, + ui::error::MyResult, +}; +use jellyui::{Scaffold, ServerLogPage, render_log_line}; use rocket::{get, response::content::RawHtml}; use rocket_ws::{Message, Stream, WebSocket}; use serde_json::json; #[get("/admin/log?<warnonly>", rank = 2)] pub fn r_admin_log(ri: RequestInfo, warnonly: bool) -> MyResult<RawHtml<String>> { - ri.session.assert_admin()?; + ri.require_admin()?; let messages = get_log_buffer(warnonly) .into_iter() .map(|l| render_log_line(&l)) .collect::<Vec<_>>(); - Ok(RawHtml(render_page( - &ServerLogPage { - messages: &messages, - warnonly, - }, - ri.render_info(), - ))) + + Ok(RawHtml( + Scaffold { + class: "theme-purple", + main: ServerLogPage { + messages: &messages, + warnonly, + }, + ri: &ri.render_info(), + title: "Admin Log", + } + .to_string(), + )) } #[get("/admin/log?stream&<warnonly>&<html>", rank = 1)] pub fn r_admin_log_stream( - session: A<Session>, + ri: RequestInfo, ws: WebSocket, warnonly: bool, html: bool, -) -> Stream!['static] { - // TODO type problems - let ok = session.0.assert_admin().is_ok(); +) -> MyResult<Stream!['static]> { + ri.require_admin()?; let mut stream = get_log_stream(warnonly); - Stream! { ws => - if !ok { - yield Message::Text("unauthorized".to_string()); - } else if html { - let _ = ws; - while let Ok(line) = stream.recv().await { - yield Message::Text(render_log_line(&line)); - } - } else { - let _ = ws; - while let Ok(line) = stream.recv().await { - yield Message::Text(json!(line).to_string()); + Ok({ + Stream! { ws => + if html { + let _ = ws; + while let Ok(line) = stream.recv().await { + yield Message::Text(render_log_line(&line)); + } + } else { + let _ = ws; + while let Ok(line) = stream.recv().await { + yield Message::Text(json!(line).to_string()); + } } } - } + }) } diff --git a/server/src/ui/admin/mod.rs b/server/src/ui/admin/mod.rs index 57f00db..8413ead 100644 --- a/server/src/ui/admin/mod.rs +++ b/server/src/ui/admin/mod.rs @@ -5,6 +5,7 @@ */ pub mod import; +pub mod log; use super::error::MyResult; use crate::{request_info::RequestInfo, ui_responder::UiResponse}; diff --git a/ui/client-scripts/src/log_live.ts b/ui/client-scripts/src/log_live.ts index b8af11e..d16553c 100644 --- a/ui/client-scripts/src/log_live.ts +++ b/ui/client-scripts/src/log_live.ts @@ -5,8 +5,8 @@ */ /// <reference lib="dom" /> globalThis.addEventListener("DOMContentLoaded", () => { - if (!document.body.classList.contains("admin_log")) return - const log = document.getElementById("log")! + const log = document.getElementById("log") + if (!log) return const warnonly = new URL(globalThis.location.href).searchParams.get("warnonly") == "true" const ws = new WebSocket(`/admin/log?stream&warnonly=${warnonly}&html=true`) diff --git a/ui/src/old/admin/log.rs b/ui/src/components/admin_log.rs index 637158f..abec7fe 100644 --- a/ui/src/old/admin/log.rs +++ b/ui/src/components/admin_log.rs @@ -4,23 +4,13 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::Page; -use jellycommon::routes::u_admin_log; +use jellycommon::{ + internal::{LogLevel, LogLine}, + routes::u_admin_log, +}; use markup::raw; use std::fmt::Write; -impl Page for ServerLogPage<'_> { - fn title(&self) -> String { - "Server Log".to_string() - } - fn class(&self) -> Option<&'static str> { - Some("admin_log") - } - fn to_render(&self) -> markup::DynRender<'_> { - markup::new!(@self) - } -} - markup::define! { ServerLogPage<'a>(warnonly: bool, messages: &'a [String]) { h1 { "Server Log" } @@ -33,7 +23,7 @@ markup::define! { } ServerLogLine<'a>(e: &'a LogLine) { tr[class=format!("level-{}", e.level).to_ascii_lowercase()] { - td.time { @e.time.to_rfc3339() } + td.time { @e.time } td.loglevel { @format_level(e.level) } td.module { @e.module } td { @markup::raw(vt100_to_html(&e.message)) } diff --git a/ui/src/components/mod.rs b/ui/src/components/mod.rs index c3ba9b0..15b2ae2 100644 --- a/ui/src/components/mod.rs +++ b/ui/src/components/mod.rs @@ -12,6 +12,7 @@ pub mod node_list; pub mod node_page; pub mod props; pub mod stats; +pub mod admin_log; use crate::{ RenderInfo, diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 63a2d07..f32657d 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -10,9 +10,12 @@ mod scaffold; pub use jellyui_client_scripts::*; pub use jellyui_client_style::*; +pub use components::admin_log::ServerLogPage; +pub use components::admin_log::render_log_line; pub use jellyui_locale::tr; +pub use scaffold::Scaffold; -use crate::{components::View, scaffold::Scaffold}; +use crate::components::View; use jellycommon::{jellyobject::Object, *}; use serde::{Deserialize, Serialize}; diff --git a/ui/src/scaffold.rs b/ui/src/scaffold.rs index 5a70460..f24550d 100644 --- a/ui/src/scaffold.rs +++ b/ui/src/scaffold.rs @@ -7,8 +7,8 @@ use crate::RenderInfo; use jellycommon::{ routes::{ - u_account_login, u_account_logout, u_account_register, u_account_settings, - u_admin_dashboard, u_home, u_items, u_node_slug, u_search, u_stats, + u_account_login, u_account_logout, u_account_settings, u_admin_dashboard, u_home, u_items, + u_node_slug, u_search, u_stats, }, user::{USER_ADMIN, USER_NAME}, }; |