1
0
forked from Proxmox/proxmox

syslog-api: new crate, split out from system-management-api

This commit is contained in:
Dietmar Maurer 2024-05-30 09:44:48 +02:00
parent 6bb74338b4
commit f6bcb6b50b
9 changed files with 194 additions and 4 deletions

View File

@ -33,6 +33,7 @@ members = [
"proxmox-sortable-macro",
"proxmox-subscription",
"proxmox-sys",
"proxmox-syslog-api",
"proxmox-system-management-api",
"proxmox-tfa",
"proxmox-time",

View File

@ -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:

View File

@ -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"]

View File

@ -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 <support@proxmox.com> Thu, 30 May 2024 09:35:54 +0200

View File

@ -0,0 +1,18 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Files:
*
Copyright: 2019 - 2023 Proxmox Server Solutions GmbH <support@proxmox.com>
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 <https://www.gnu.org/licenses/>.

View File

@ -0,0 +1,7 @@
overlay = "."
crate_src_path = ".."
maintainer = "Proxmox Support Team <support@proxmox.com>"
[source]
vcs_git = "git://git.proxmox.com/git/proxmox.git"
vcs_browser = "https://git.proxmox.com/?p=proxmox.git"

View File

@ -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<u64>,
pub limit: Option<u64>,
pub since: Option<String>,
pub until: Option<String>,
pub service: Option<String>,
}
#[api]
#[derive(Clone, PartialEq, Serialize, Deserialize)]
/// Syslog line with line number.
pub struct SyslogLine {
/// Line number.
pub n: u64,
/// Line text.
pub t: String,
}

View File

@ -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<SyslogLine>), 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<SyslogLine> = 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))
}

View File

@ -0,0 +1,7 @@
mod api_types;
pub use api_types::*;
#[cfg(feature = "impl")]
mod journal;
#[cfg(feature = "impl")]
pub use journal::dump_journal;