From f6bcb6b50bbc0a0430746b391f428954e9b5d00e Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 30 May 2024 09:44:48 +0200 Subject: [PATCH] syslog-api: new crate, split out from system-management-api --- Cargo.toml | 1 + proxmox-acme-api/debian/control | 7 +-- proxmox-syslog-api/Cargo.toml | 21 +++++++ proxmox-syslog-api/debian/changelog | 6 ++ proxmox-syslog-api/debian/copyright | 18 ++++++ proxmox-syslog-api/debian/debcargo.toml | 7 +++ proxmox-syslog-api/src/api_types.rs | 58 ++++++++++++++++++++ proxmox-syslog-api/src/journal.rs | 73 +++++++++++++++++++++++++ proxmox-syslog-api/src/lib.rs | 7 +++ 9 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 proxmox-syslog-api/Cargo.toml create mode 100644 proxmox-syslog-api/debian/changelog create mode 100644 proxmox-syslog-api/debian/copyright create mode 100644 proxmox-syslog-api/debian/debcargo.toml create mode 100644 proxmox-syslog-api/src/api_types.rs create mode 100644 proxmox-syslog-api/src/journal.rs create mode 100644 proxmox-syslog-api/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 43640c66..727d9346 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ members = [ "proxmox-sortable-macro", "proxmox-subscription", "proxmox-sys", + "proxmox-syslog-api", "proxmox-system-management-api", "proxmox-tfa", "proxmox-time", diff --git a/proxmox-acme-api/debian/control b/proxmox-acme-api/debian/control index 9bd3b63b..3d4b8fc0 100644 --- a/proxmox-acme-api/debian/control +++ b/proxmox-acme-api/debian/control @@ -78,22 +78,21 @@ Depends: librust-proxmox-acme-api+api-types-dev (= ${binary:Version}), librust-base64-0.13+default-dev, librust-futures-0.3+default-dev, - librust-hex-0.4+default-dev, librust-http-0.2+default-dev, librust-hyper-0.14+default-dev (>= 0.14.5-~~), librust-lazy-static-1+default-dev (>= 1.4-~~), librust-log-0.4+default-dev (>= 0.4.17-~~), librust-nix-0.26+default-dev (>= 0.26.1-~~), - librust-openssl-0.10+default-dev, librust-proxmox-acme-0.5+api-types-dev (>= 0.5.2-~~), librust-proxmox-acme-0.5+async-client-dev (>= 0.5.2-~~), librust-proxmox-acme-0.5+impl-dev (>= 0.5.2-~~), + librust-proxmox-config-digest-0.1+default-dev, + librust-proxmox-config-digest-0.1+openssl-dev, librust-proxmox-product-config-0.1+default-dev, - librust-proxmox-product-config-0.1+impl-dev, librust-proxmox-rest-server-0.5+default-dev (>= 0.5.2-~~), librust-proxmox-router-2+default-dev (>= 2.1.3-~~), librust-proxmox-section-config-2+default-dev, - librust-proxmox-sys-0.5+default-dev (>= 0.5.1-~~), + librust-proxmox-sys-0.5+default-dev (>= 0.5.5-~~), librust-tokio-1+default-dev (>= 1.6-~~), librust-tokio-1+fs-dev (>= 1.6-~~) Provides: diff --git a/proxmox-syslog-api/Cargo.toml b/proxmox-syslog-api/Cargo.toml new file mode 100644 index 00000000..f4b26f24 --- /dev/null +++ b/proxmox-syslog-api/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "proxmox-syslog-api" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +exclude.workspace = true +description = "Syslog Management API implementation" + +[dependencies] +anyhow.workspace = true + +serde = { workspace = true, features = ["derive"] } +log = { workspace = true, optional = true } + +proxmox-schema = { workspace = true, features = ["api-macro", "api-types"] } + +[features] +default = [] +impl = ["dep:log"] diff --git a/proxmox-syslog-api/debian/changelog b/proxmox-syslog-api/debian/changelog new file mode 100644 index 00000000..1214e2a4 --- /dev/null +++ b/proxmox-syslog-api/debian/changelog @@ -0,0 +1,6 @@ +rust-proxmox-syslog-api (0.1.0-1) bookworm; urgency=medium + + * initial packaging (split out from proxmox-system-management-api) + + -- Proxmox Support Team Thu, 30 May 2024 09:35:54 +0200 + diff --git a/proxmox-syslog-api/debian/copyright b/proxmox-syslog-api/debian/copyright new file mode 100644 index 00000000..0d9eab3e --- /dev/null +++ b/proxmox-syslog-api/debian/copyright @@ -0,0 +1,18 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + +Files: + * +Copyright: 2019 - 2023 Proxmox Server Solutions GmbH +License: AGPL-3.0-or-later + This program is free software: you can redistribute it and/or modify it under + the terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) any + later version. + . + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + details. + . + You should have received a copy of the GNU Affero General Public License along + with this program. If not, see . diff --git a/proxmox-syslog-api/debian/debcargo.toml b/proxmox-syslog-api/debian/debcargo.toml new file mode 100644 index 00000000..b7864cdb --- /dev/null +++ b/proxmox-syslog-api/debian/debcargo.toml @@ -0,0 +1,7 @@ +overlay = "." +crate_src_path = ".." +maintainer = "Proxmox Support Team " + +[source] +vcs_git = "git://git.proxmox.com/git/proxmox.git" +vcs_browser = "https://git.proxmox.com/?p=proxmox.git" diff --git a/proxmox-syslog-api/src/api_types.rs b/proxmox-syslog-api/src/api_types.rs new file mode 100644 index 00000000..8bf99cac --- /dev/null +++ b/proxmox-syslog-api/src/api_types.rs @@ -0,0 +1,58 @@ +use serde::{Deserialize, Serialize}; + +use proxmox_schema::api; +use proxmox_schema::api_types::SYSTEMD_DATETIME_FORMAT; + +#[api( + properties: { + start: { + type: Integer, + description: "Start line number.", + minimum: 0, + optional: true, + }, + limit: { + type: Integer, + description: "Max. number of lines.", + optional: true, + minimum: 0, + }, + since: { + type: String, + optional: true, + description: "Display all log since this date-time string.", + format: &SYSTEMD_DATETIME_FORMAT, + }, + until: { + type: String, + optional: true, + description: "Display all log until this date-time string.", + format: &SYSTEMD_DATETIME_FORMAT, + }, + service: { + type: String, + optional: true, + description: "Service ID.", + max_length: 128, + }, + }, +)] +#[derive(Clone, PartialEq, Serialize, Deserialize)] +/// Syslog filtering options. +pub struct SyslogFilter { + pub start: Option, + pub limit: Option, + pub since: Option, + pub until: Option, + pub service: Option, +} + +#[api] +#[derive(Clone, PartialEq, Serialize, Deserialize)] +/// Syslog line with line number. +pub struct SyslogLine { + /// Line number. + pub n: u64, + /// Line text. + pub t: String, +} \ No newline at end of file diff --git a/proxmox-syslog-api/src/journal.rs b/proxmox-syslog-api/src/journal.rs new file mode 100644 index 00000000..73b5c96d --- /dev/null +++ b/proxmox-syslog-api/src/journal.rs @@ -0,0 +1,73 @@ +use std::process::{Command, Stdio}; + +use anyhow::Error; + +use super::{SyslogFilter, SyslogLine}; + +pub fn dump_journal(filter: SyslogFilter) -> Result<(u64, Vec), Error> { + let mut args = vec!["-o", "short", "--no-pager"]; + + if let Some(service) = &filter.service { + args.extend(["--unit", service]); + } + if let Some(since) = &filter.since { + args.extend(["--since", since]); + } + if let Some(until) = &filter.until { + args.extend(["--until", until]); + } + + let mut lines: Vec = Vec::new(); + let mut limit = filter.limit.unwrap_or(50); + let start = filter.start.unwrap_or(0); + let mut count: u64 = 0; + + let mut child = Command::new("journalctl") + .args(&args) + .stdout(Stdio::piped()) + .spawn()?; + + use std::io::{BufRead, BufReader}; + + if let Some(ref mut stdout) = child.stdout { + for line in BufReader::new(stdout).lines() { + match line { + Ok(line) => { + count += 1; + if count < start { + continue; + }; + if limit == 0 { + continue; + }; + + lines.push(SyslogLine { n: count, t: line }); + + limit -= 1; + } + Err(err) => { + log::error!("reading journal failed: {}", err); + let _ = child.kill(); + break; + } + } + } + } + + let status = child.wait().unwrap(); + if !status.success() { + log::error!("journalctl failed with {}", status); + } + + // HACK: ExtJS store.guaranteeRange() does not like empty array + // so we add a line + if count == 0 { + count += 1; + lines.push(SyslogLine { + n: count, + t: String::from("no content"), + }); + } + + Ok((count, lines)) +} diff --git a/proxmox-syslog-api/src/lib.rs b/proxmox-syslog-api/src/lib.rs new file mode 100644 index 00000000..f2e026a5 --- /dev/null +++ b/proxmox-syslog-api/src/lib.rs @@ -0,0 +1,7 @@ +mod api_types; +pub use api_types::*; + +#[cfg(feature = "impl")] +mod journal; +#[cfg(feature = "impl")] +pub use journal::dump_journal;