Forráskód Böngészése

Implement thread IDs based on @cehteh's work

This adds features named "threads" and "nightly".

Enabling "threads" and calling `.with_threads(true)` on the logger
before init will show thread names in the output. If a thread is not
named, '?' will be shown.

Enabling "threads" and "nightly" will show the numeric thread ID if
a thread does not have a name.

This is based on https://github.com/borntyping/rust-simple_logger/pull/39
Sam Clements 3 éve
szülő
commit
70f5d5e1be
4 módosított fájl, 83 hozzáadás és 3 törlés
  1. 3 1
      .github/workflows/ci.yml
  2. 7 1
      Cargo.toml
  3. 25 0
      examples/threads.rs
  4. 48 1
      src/lib.rs

+ 3 - 1
.github/workflows/ci.yml

@@ -1,3 +1,4 @@
+---
 name: ci
 
 on: [pull_request, push]
@@ -42,9 +43,10 @@ jobs:
         toolchain:
           - stable
         features:
-          - --all-features
+          - ""
           - --no-default-features
           - --no-default-features --features colors
+          - --no-default-features --features threads
           - --no-default-features --features timestamps
         continue-on-error:
           - false

+ 7 - 1
Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "simple_logger"
-version = "1.14.0"
+version = "1.15.0"
 license = "MIT"
 authors = ["Sam Clements <[email protected]>"]
 description = "A logger that prints all messages with a readable output format"
@@ -10,7 +10,9 @@ edition = "2018"
 [features]
 default = ["colored", "time"]
 colors = ["colored"]
+threads = []
 timestamps = ["time"]
+nightly = []
 stderr = []
 
 [dependencies]
@@ -26,6 +28,10 @@ winapi = { version = "0.3", features = ["handleapi", "winbase"]}
 name = "colors"
 required-features = ["colors"]
 
+[[example]]
+name = "threads"
+required-features = ["threads"]
+
 [[example]]
 name = "timestamps"
 required-features = ["timestamps"]

+ 25 - 0
examples/threads.rs

@@ -0,0 +1,25 @@
+use simple_logger::SimpleLogger;
+
+fn main() {
+    SimpleLogger::new().with_threads(true).init().unwrap();
+
+    log::info!("Main thread logs here.");
+
+    // If the "nightly" feature is enabled, the output will include thread ids.
+    for _ in 1..=5 {
+        std::thread::spawn(|| {
+            log::info!("Unnamed thread logs here.");
+        })
+        .join()
+        .unwrap();
+    }
+
+    std::thread::Builder::new()
+        .name("named_thread".to_string())
+        .spawn(|| {
+            log::info!("Named thread logs here.");
+        })
+        .unwrap()
+        .join()
+        .unwrap();
+}

+ 48 - 1
src/lib.rs

@@ -28,6 +28,8 @@
 //! simple_logger::init_with_level(log::Level::Warn).unwrap();
 //! ```
 
+#![cfg_attr(feature = "nightly", feature(thread_id_value))]
+
 #[cfg(feature = "colored")]
 use colored::*;
 use log::{Level, LevelFilter, Log, Metadata, Record, SetLoggerError};
@@ -55,6 +57,12 @@ pub struct SimpleLogger {
     /// directly gives us the desired log level.
     module_levels: Vec<(String, LevelFilter)>,
 
+    /// Whether to include thread names (and IDs) or not
+    ///
+    /// This field is only available if the `threads` feature is enabled.
+    #[cfg(feature = "threads")]
+    threads: bool,
+
     /// Whether to include timestamps or not
     ///
     /// This field is only available if the `timestamps` feature is enabled.
@@ -85,6 +93,9 @@ impl SimpleLogger {
             default_level: LevelFilter::Trace,
             module_levels: Vec::new(),
 
+            #[cfg(feature = "threads")]
+            threads: false,
+
             #[cfg(feature = "timestamps")]
             timestamps: true,
 
@@ -212,6 +223,17 @@ impl SimpleLogger {
         self
     }
 
+    /// Control whether thread names (and IDs) are printed or not.
+    ///
+    /// This method is only available if the `threads` feature is enabled.
+    /// Thread names are disabled by default.
+    #[must_use = "You must call init() to begin logging"]
+    #[cfg(feature = "threads")]
+    pub fn with_threads(mut self, threads: bool) -> SimpleLogger {
+        self.threads = threads;
+        self
+    }
+
     /// Control whether timestamps are printed or not.
     ///
     /// This method is only available if the `timestamps` feature is enabled.
@@ -308,6 +330,30 @@ impl Log for SimpleLogger {
                 record.module_path().unwrap_or_default()
             };
 
+            let thread = {
+                #[cfg(feature = "threads")]
+                if self.threads {
+                    let thread = std::thread::current();
+
+                    format!("@{}", {
+                        #[cfg(feature = "nightly")]
+                        {
+                            thread.name().unwrap_or(&thread.id().as_u64().to_string())
+                        }
+
+                        #[cfg(not(feature = "nightly"))]
+                        {
+                            thread.name().unwrap_or("?")
+                        }
+                    })
+                } else {
+                    "".to_string()
+                }
+
+                #[cfg(not(feature = "threads"))]
+                ""
+            };
+
             let timestamp = {
                 #[cfg(feature = "timestamps")]
                 if self.timestamps {
@@ -328,10 +374,11 @@ impl Log for SimpleLogger {
             };
 
             let message = format!(
-                "{}{:<5} [{}] {}",
+                "{}{:<5} [{}{}] {}",
                 timestamp,
                 level_string,
                 target,
+                thread,
                 record.args()
             );