Skip to content

Commit

Permalink
source: save the source info when the user calls the macros
Browse files Browse the repository at this point in the history
  • Loading branch information
chensoft committed Mar 20, 2024
1 parent 1fdfb17 commit e4d2fae
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 20 deletions.
8 changes: 7 additions & 1 deletion HISTORY.md
@@ -1,4 +1,4 @@
### Todo
## Todo

- predefined fields do not need invoked every time
- async write support and thread local
Expand All @@ -7,6 +7,12 @@
- highlight keywords in console output
- sampling by level

## [Unreleased] - 2024-0x-xx

### Added

- Save the source info when the user calls the macros

## [0.3.4] - 2024-03-13

### Added
Expand Down
1 change: 1 addition & 0 deletions examples/hello_world.rs
Expand Up @@ -4,6 +4,7 @@ fn main() {
let mut logger = logkit::Logger::new(Some(&logkit::StdoutTarget));
logger.mount(logkit::LevelPlugin);
logger.mount(logkit::TimePlugin::from_millis());
logger.mount(logkit::SourcePlugin);
logkit::set_default_logger(logger);

trace!("hello, this is a trace log");
Expand Down
2 changes: 1 addition & 1 deletion src/define.rs
Expand Up @@ -18,7 +18,7 @@ pub(crate) use std::sync::Mutex;
/// }};
/// }
///
/// assert_eq!(logkit::default_logger().spawn(LEVEL_CUSTOM).unwrap().level(), LEVEL_CUSTOM);
/// assert_eq!(logkit::default_logger().spawn(LEVEL_CUSTOM, file!(), line!(), column!()).unwrap().level(), LEVEL_CUSTOM);
/// custom!("this is a custom log level");
/// ```
pub type Level = i32;
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Expand Up @@ -168,6 +168,7 @@ pub mod logger;
pub mod macros;
pub mod plugin;
pub mod record;
pub mod source;
pub mod target;

#[doc(inline)]
Expand All @@ -181,4 +182,6 @@ pub use plugin::*;
#[doc(hidden)]
pub use record::*;
#[doc(hidden)]
pub use source::*;
#[doc(hidden)]
pub use target::*;
11 changes: 6 additions & 5 deletions src/logger.rs
@@ -1,6 +1,7 @@
//! The central struct designed for managing logging tasks
use super::define::*;
use super::record::*;
use super::source::*;
use super::plugin::*;
use super::target::*;

Expand Down Expand Up @@ -181,14 +182,14 @@ impl Logger {
/// ```
/// let logger = logkit::Logger::new(Some(&logkit::StderrTarget));
///
/// if let Some(mut record) = logger.spawn(logkit::LEVEL_TRACE) {
/// if let Some(mut record) = logger.spawn(logkit::LEVEL_TRACE, file!(), line!(), column!()) {
/// record.append("hello", &"world");
/// record.finish();
/// assert_eq!(String::from_utf8_lossy(record.buffer().as_slice()), "{\"hello\":\"world\"}\n")
/// }
/// ```
#[inline]
pub fn spawn(&self, level: Level) -> Option<Record> {
pub fn spawn(&self, level: Level, file: &'static str, line: u32, column: u32) -> Option<Record> {
if !self.allow(level) {
return None;
}
Expand All @@ -199,8 +200,8 @@ impl Logger {
};

let mut record = match record {
None => Record::new(level, self.alloc),
Some(val) => Record::set(val, level),
None => Record::new(level, self.alloc, Source::new(file, line, column)),
Some(val) => Record::set(val, level, file, line, column),
};

for plugin in &self.plugins {
Expand All @@ -224,7 +225,7 @@ impl Logger {
/// ```
/// let logger = logkit::Logger::new(Some(&logkit::StderrTarget));
///
/// if let Some(mut record) = logger.spawn(logkit::LEVEL_TRACE) {
/// if let Some(mut record) = logger.spawn(logkit::LEVEL_TRACE, file!(), line!(), column!()) {
/// record.append("msg", &"this log will be directed to stderr");
/// logger.flush(record);
/// }
Expand Down
8 changes: 4 additions & 4 deletions src/macros.rs
Expand Up @@ -200,7 +200,7 @@ macro_rules! record {
// record!(logkit::LEVEL_TRACE);
// {}
($log:expr, $lvl:expr $(,)?) => {{
if let Some(record) = $log.spawn($lvl) {
if let Some(record) = $log.spawn($lvl, file!(), line!(), column!()) {
$log.flush(record);
}
}};
Expand All @@ -214,7 +214,7 @@ macro_rules! record {
// record!(logkit::LEVEL_TRACE, "Hi {}! It's been {} years since our last trip together.", "Alice", 2);
// {"msg":"Hi Alice! It's been 2 years since our last trip together."}
($log:expr, $lvl:expr, $fmt:literal, $($arg:tt)*) => {{
if let Some(mut record) = $log.spawn($lvl) {
if let Some(mut record) = $log.spawn($lvl, file!(), line!(), column!()) {
record.append("msg", &format!($fmt, $($arg)*));
$log.flush(record);
}
Expand All @@ -223,7 +223,7 @@ macro_rules! record {
// record!(logkit::LEVEL_TRACE, name = "Alice", age = 20);
// {"name":"Alice","age":20}
($log:expr, $lvl:expr, $($key:tt = $val:expr),+ $(,)?) => {{
if let Some(mut record) = $log.spawn($lvl) {
if let Some(mut record) = $log.spawn($lvl, file!(), line!(), column!()) {
$(record.append(stringify!($key), &$val);)+
$log.flush(record);
}
Expand All @@ -238,7 +238,7 @@ macro_rules! record {
// record!(logkit::LEVEL_TRACE, name = "Alice", age = 20; "Hi {}! I know, time flies. I've visited {} countries since then.", "Bob", 3);
// {"msg":"Hi Bob! I know, time flies. I've visited 3 countries since then.","name":"Alice","age":20}
($log:expr, $lvl:expr, $($key:tt = $val:expr),+; $fmt:literal, $($arg:tt)*) => {{
if let Some(mut record) = $log.spawn($lvl) {
if let Some(mut record) = $log.spawn($lvl, file!(), line!(), column!()) {
record.append("msg", &format!($fmt, $($arg)*));
$(record.append(stringify!($key), &$val);)*

Expand Down
15 changes: 15 additions & 0 deletions src/plugin.rs
Expand Up @@ -110,6 +110,21 @@ impl Plugin for TimePlugin {
}
}

/// Add source info to a record
///
/// ```json,no_run
/// {"src":"examples/hello_world.rs:9"}
/// ```
pub struct SourcePlugin;

impl Plugin for SourcePlugin {
#[inline]
fn post(&self, record: &mut Record) -> bool {
record.append("src", &format!("{}:{}", record.source().file, record.source().line));
true
}
}

/// Represent a stack trace frame
#[derive(Debug, Default, Clone)]
pub struct StackFrame {
Expand Down
29 changes: 20 additions & 9 deletions src/record.rs
@@ -1,5 +1,6 @@
//! Record represent a single log entry
use super::define::*;
use super::source::*;

/// Log Record
///
Expand All @@ -11,6 +12,7 @@ use super::define::*;
pub struct Record {
level: Level,
cache: Vec<u8>,
source: Source,
}

impl Record {
Expand All @@ -19,29 +21,32 @@ impl Record {
/// The `capacity` argument specifies the initial capacity of the buffer.
///
/// ```
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512);
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512, logkit::Source::new(file!(), line!(), column!()));
/// assert_eq!(record.level(), logkit::LEVEL_TRACE);
/// ```
#[inline]
pub fn new(level: Level, capacity: usize) -> Self {
let mut obj = Self {level, cache: Vec::with_capacity(capacity)};
pub fn new(level: Level, capacity: usize, source: Source) -> Self {
let mut obj = Self {level, cache: Vec::with_capacity(capacity), source};
obj.cache.push(b'{');
obj
}

/// Reset record for reuse
///
/// ```
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512);
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512, logkit::Source::new(file!(), line!(), column!()));
/// assert_eq!(record.level(), logkit::LEVEL_TRACE);
///
/// record = logkit::Record::set(record, logkit::LEVEL_ERROR);
/// record = logkit::Record::set(record, logkit::LEVEL_ERROR, file!(), line!(), column!());
/// assert_eq!(record.level(), logkit::LEVEL_ERROR);
/// ```
#[inline]
pub fn set(mut record: Record, level: Level) -> Self {
pub fn set(mut record: Record, level: Level, file: &'static str, line: u32, column: u32) -> Self {
record.level = level;
record.cache.truncate(1); // preserve '{'
record.source.file = file;
record.source.line = line;
record.source.column = column;
record
}

Expand All @@ -51,14 +56,20 @@ impl Record {
self.level
}

/// Current record's source info
#[inline]
pub fn source(&self) -> &Source {
&self.source
}

/// Append field's key and value to record
///
/// The order of fields is fixed, fields are stored in the order they are added.
///
/// Note that duplicate fields are not filtered out.
///
/// ```
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512);
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512, logkit::Source::new(file!(), line!(), column!()));
/// record.append("pid", &12345);
/// record.append("msg", &"think outside the box");
/// record.finish();
Expand All @@ -76,7 +87,7 @@ impl Record {
/// Mark the end of the record
///
/// ```
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512);
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512, logkit::Source::new(file!(), line!(), column!()));
/// record.finish();
/// assert_eq!(String::from_utf8_lossy(record.buffer().as_slice()), "{}\n");
/// ```
Expand All @@ -93,7 +104,7 @@ impl Record {
/// Get the final buffer
///
/// ```
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512);
/// let mut record = logkit::Record::new(logkit::LEVEL_TRACE, 512, logkit::Source::new(file!(), line!(), column!()));
/// record.append("msg", &"less is more");
/// record.finish();
/// assert_eq!(String::from_utf8_lossy(record.buffer().as_slice()), "{\"msg\":\"less is more\"}\n");
Expand Down
31 changes: 31 additions & 0 deletions src/source.rs
@@ -0,0 +1,31 @@
//! Source represent source info

/// Source Info
///
/// Save the source info when the user calls the macros.
#[derive(Debug, Clone)]
pub struct Source {
/// File name in which it was invoked
pub file: &'static str,

/// line number on which it was invoked
pub line: u32,

/// Column number at which it was invoked
pub column: u32,
}

impl Source {
/// Create a new source info
///
/// ```
/// let mut source = logkit::Source::new(file!(), line!(), column!());
/// assert_eq!(source.file, "src/source.rs");
/// assert!(source.line > 0);
/// assert!(source.column > 0);
/// ```
#[inline]
pub fn new(file: &'static str, line: u32, column: u32) -> Self {
Self {file, line, column}
}
}

0 comments on commit e4d2fae

Please sign in to comment.