Skip to content

Commit

Permalink
implement logging to a file
Browse files Browse the repository at this point in the history
  • Loading branch information
zkxs committed Jun 29, 2024
1 parent b9d245c commit 31fc0df
Show file tree
Hide file tree
Showing 6 changed files with 392 additions and 49 deletions.
215 changes: 214 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hooligan"
version = "1.0.0"
version = "1.1.0"
edition = "2021"
authors = ["Michael Ripley <[email protected]"]
license = "GPL-3.0-only"
Expand All @@ -18,3 +18,5 @@ codegen-units = 1
strip = true

[dependencies]
directories = "5"
file-rotate = {git = "https://github.com/zkxs/file-rotate.git", branch = "time-and-compression-features", default-features = false}
10 changes: 10 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use std::process::Command;

fn main() {
// record git commit hash
{
let output = Command::new("git").args(["rev-parse", "HEAD"]).output().unwrap();
let git_commit_hash = String::from_utf8(output.stdout).unwrap();
println!("cargo:rustc-env=GIT_COMMIT_HASH={}", git_commit_hash);
}
}
16 changes: 8 additions & 8 deletions src/local_player_moderations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct Line {
}

impl Line {
pub fn parse(line: &str) -> Result<Line, ParseError> {
pub fn parse(line: &str) -> Result<Self, ParseError> {
let mut split = line.split(' ').filter(|s| !s.is_empty());
let key = split.next().ok_or_else(|| ParseError::BadSplit(line.to_owned()))?;
let value = split.next().ok_or_else(|| ParseError::BadSplit(line.to_owned()))?;
Expand All @@ -29,7 +29,7 @@ impl Line {
let value: Value = Value::parse(value)?;
let key = key.to_owned();

Ok(Line {
Ok(Self {
key,
value,
})
Expand All @@ -48,18 +48,18 @@ pub enum Value {

impl Value {
/// `value` is an integer in the range \[000,999]
fn parse(value: &str) -> Result<Value, ParseError> {
fn parse(value: &str) -> Result<Self, ParseError> {
match value {
HIDE_AVATAR_VALUE => Ok(Value::Hide),
SHOW_AVATAR_VALUE => Ok(Value::Show),
HIDE_AVATAR_VALUE => Ok(Self::Hide),
SHOW_AVATAR_VALUE => Ok(Self::Show),
unknown_value => Err(ParseError::UnknownValue(unknown_value.to_owned())),
}
}

fn serialize(&self) -> &str {
const fn serialize(&self) -> &str {
match self {
Value::Hide => HIDE_AVATAR_VALUE,
Value::Show => SHOW_AVATAR_VALUE,
Self::Hide => HIDE_AVATAR_VALUE,
Self::Show => SHOW_AVATAR_VALUE,
}
}
}
Expand Down
77 changes: 77 additions & 0 deletions src/logging.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// This file is part of hooligan and is licenced under the GNU GPL v3.0.
// See LICENSE file for full text.
// Copyright © 2024 Michael Ripley

//! Logging-related utilities

use std::{fmt, fs, io};
use std::fmt::{Display, Formatter};
use std::io::{BufWriter, Write};
use std::path::PathBuf;
use std::time::SystemTime;
use directories::ProjectDirs;
use file_rotate::{ContentLimit, FileRotate};
use file_rotate::suffix::AppendCount;

type LogWrite = BufWriter<FileRotate<AppendCount>>;

pub struct LogFile {
write: LogWrite,
}

impl LogFile {
fn new(write: LogWrite) -> Self {
Self { write }
}

pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) {
write!(self.write, "{}: ", CurrentTime).expect("failed to write log timestamp");
self.write.write_fmt(args).expect("failed to write log arguments");
}

pub fn flush(&mut self) -> io::Result<()> {
self.write.flush()
}
}

pub fn get_logger() -> io::Result<LogFile> {
let file_rotate = FileRotate::new(
get_log_file_prefix()?,
AppendCount::new(3),
ContentLimit::BytesSurpassed(1024 * 1024 * 10),
);
Ok(LogFile::new(BufWriter::new(file_rotate)))
}

fn get_log_file_prefix() -> io::Result<PathBuf> {
let mut log_file_prefix_path = create_log_dir_path()?;
log_file_prefix_path.push("hooligan.log");
Ok(log_file_prefix_path)
}

fn create_log_dir_path() -> io::Result<PathBuf> {
let log_dir_path: PathBuf = get_log_dir()?;
fs::create_dir_all(log_dir_path.as_path())?;
Ok(log_dir_path)
}

fn get_log_dir() -> io::Result<PathBuf> {
Ok(
ProjectDirs::from("zkxs.dev", "", "hooligan")
.ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "failed to find valid project directory"))?
.data_local_dir()
.join("logs")
)
}

/// Handles displaying the current time in a minimally expensive way
struct CurrentTime;

impl Display for CurrentTime {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match SystemTime::UNIX_EPOCH.elapsed() {
Ok(current_time) => write!(f, "{}", current_time.as_secs()),
Err(e) => write!(f, "-{}", e.duration().as_secs())
}
}
}
Loading

0 comments on commit 31fc0df

Please sign in to comment.