Giter Club home page Giter Club logo

slog's Issues

Support custom timestamp, level, msg key names.

Timestamp could be really OwnedKeyValue with the value being a closure, with a possibility of an user adding it's own. The problem it's evaluation would happen a bit later (important for async drain).

Level & msg are kind of special, but maybe something similiar could be done for them.

Review the list of `emit_x` functions in `Serializer`.

While not tragic, every time this list changes, API breaks for serializer adapters (slog-serde).

Also, while at it, review the list of types implementing Serializable. Adding these is backward-compatible, but it's better to check now.

Strategies and tools for libraries to allow seamless `slog` support.

Currently most libraries can just keep using log logging statement. Applications using them can just use slog-stdlog + slog-stdlog::scope to redirect it where they want.

The more complicated ones can just accept Logger, but what if they don't want to force slog dependency on their user?

Derive or implement `Debug` for `Logger`

Loggers should be stored in the structs their context is associated with. Since Logger doesn't implement Debug this imposes a limitation on these structs.

How should the output of Debug look? The connected drain and a list of owned values are available in the loggers. I think printing the list of owned values is sufficient to identify the logger.

`CompactStreamer` / `CompactTextFormat` ?

Text logging streamer/format(?) that looks something like this:

 build: 'adfksj2kdfl'
   server-ip: 32.24.2.1 server-port: 23434
      peer-ip: 2.3.65.2
          2016-08-23 16:32:23.235 Connected
          2016-08-23 16:32:26.642 Request received
      peer-ip: 11.32.53.12
          2016-08-23 16:32:33.343 Connected
          2016-08-23 16:32:34.322 Request received
          2016-08-23 16:32:35.112 Response sent
      peer-ip: 2.3.65.2
          2016-08-23 16:32:36.231 Response sent
          2016-08-23 16:32:37.542 Disconnected
      peer-ip: 11.32.53.12
          2016-08-23 16:32:38.938 Disconnected

This is almost as compact/short as normal log, while, the structured information can be easily found be following the indention.

Thread local loggers

I was wondering if we could have some sort of thread local logger (possibly adaptors for coroutine local as well), this way you wouldn't have to pass the logger around in most cases, making the crate much more ergonomic.

It wouldn't work for all occasions, granted, but I can see it being very useful in a lot of cases.

slog-scopes

Create a library that uses thread_local stack of Loggers to allow not passing Logger when not desired.

Easier `slog_stdlog` invocation.

#[macro_use]
extern crate log;
extern crate slog_stdlog;

 fn main() { 
   slog_stdlog::init();
    info!("should just work out of the box");
 }

StdLog doesn't pass key => value from inside log messages with env_logger

I'm currently trying to implement stdlog for Amethyst for optional slog support for a binary. To enable this, I'm using the

struct Foo {
    logger: logger.unwrap_or(slog::Logger::root(slog_stdlog::StdLog.fuse(), o!()))
}

method described in crates/example-lib However, when a binary doesn't use a slog drain, but env_logger, messages that should look like this with env_logger (and does with slog)

ERROR:my:library:source: error message here, errorid: 405, cause: foo

looks like

ERROR:my:library:source: error message here

skipping the information that should be delivered with error!(self.logger, "error message here"; "errorid" => error_id, "cause" => cause);

Interoperability with standard logging facilities.

It might make sense to build log crate adapters, so calls like info!(...) would be logged as some_global_logger.info("original-info-message"). This most pobably could be done as a separate library (log-slog-logger)?

The other way around could be useful too: implement a slog::Drain that forwards logging record to log calls, formatting them before the write.

Add AsyncStreamer

Same as Stremer, but using channel and worker thread to write message asynchronously.

slog-syslog: Streamer3164 doesn't empty buffer after writing

The Drain::log implementation for Streamer3164 never trims TL_BUF after writing some bytes from it via syslog::Logger::send.

Note that syslog::Logger::send_raw returns the number of bytes written from the RFC3164 formatted message and not the raw message passed to it, so using the count returned by send is not suitable for trimming TL_BUF.

Streamer3164 should probably use format_3164 directly and continuously call send_raw until the message is fully written. Drain::log feels like std::io::Write::write_all to me, so I think this is semantically appropriate.

slog-atomic 0.3.0 out of date with master

I suspect the slog-atomic crate was not published with the 1.0.0 release as the code on master does not match that in 0.3.0.

0.3.0:

/// Handle to `AtomicSwitch` allowing switching it's sub-drain
pub struct AtomicSwitchCtrl<E>(Arc<ArcCell<Box<Drain<Error=E>>>>);

/// Drain allowing atomically switching a sub-drain in runtime
pub struct AtomicSwitch<E>(Arc<ArcCell<Box<Drain<Error=E>>>>);

impl<E> AtomicSwitchCtrl<E> {
    /// Create new `AtomicSwitchCtrl`
    pub fn new<D: Drain<Error=E> + 'static>(d: D) -> Self {
        let a = Arc::new(ArcCell::new(Arc::new(Box::new(d) as Box<Drain<Error=E>>)));
        AtomicSwitchCtrl(a)
    }

    /// Create new `AtomicSwitchCtrl` from an existing `Arc<...>`
    pub fn new_from_arc(d: Arc<ArcCell<Box<Drain<Error=E>>>>) -> Self {
        AtomicSwitchCtrl(d)
    }

    /// Get a `AtomicSwitch` drain controlled by this `AtomicSwitchCtrl`
    pub fn drain(&self) -> AtomicSwitch<E> {
        AtomicSwitch(self.0.clone())
    }

    /// Set the drain
    pub fn set<D: Drain<Error=E>>(&self, drain: D) {
        let _ = self.0.set(Arc::new(Box::new(drain)));
    }

    /// Swap the existing drain with a new one
    pub fn swap(&self, drain: Arc<Box<Drain<Error=E>>>) -> Arc<Box<Drain<Error=E>>> {
        self.0.set(drain)
    }
}

impl<E> Drain for AtomicSwitch<E> {
    type Error = E;
    fn log(&self, info: &Record, logger_values: &OwnedKeyValueList) -> std::result::Result<(), E> {
        self.0.get().log(info, logger_values)
    }
}

master:

/// Handle to `AtomicSwitch` that controls it.
pub struct AtomicSwitchCtrl<E>(Arc<ArcCell<Box<Drain<Error=E>>>>);

/// Drain wrapping another drain, allowing atomic substitution in runtime
pub struct AtomicSwitch<E>(Arc<ArcCell<Box<Drain<Error=E>>>>);

impl<E> AtomicSwitch<E> {
    /// Wrap `drain` in `AtomicSwitch` to allow swapping it later
    ///
    /// Use `AtomicSwitch::ctrl()` to get a handle to it
    pub fn new<D: Drain<Error=E> + 'static>(drain: D) -> Self {
        AtomicSwitch::new_from_arc(Arc::new(ArcCell::new(Arc::new(Box::new(drain) as Box<Drain<Error=E>>))))
    }

    /// Create new `AtomicSwitch` from an existing `Arc<...>`
    ///
    /// See `AtomicSwitch::new()`
    pub fn new_from_arc(d: Arc<ArcCell<Box<Drain<Error=E>>>>) -> Self {
        AtomicSwitch(d)
    }

    /// Get a `AtomicSwitchCtrl` handle to control this `AtomicSwitch` drain
    pub fn ctrl(&self) -> AtomicSwitchCtrl<E> {
        AtomicSwitchCtrl(self.0.clone())
    }
}

impl<E> AtomicSwitchCtrl<E> {
    /// Get Arc to the currently wrapped drain 
    pub fn get(&self) -> Arc<Box<Drain<Error=E>>> {
        self.0.get()
    }

    /// Set the current wrapped drain
    pub fn set<D: Drain<Error=E>>(&self, drain: D) {
        let _ = self.0.set(Arc::new(Box::new(drain)));
    }

    /// Swap the existing drain with a new one
    pub fn swap(&self, drain: Arc<Box<Drain<Error=E>>>) -> Arc<Box<Drain<Error=E>>> {
        self.0.set(drain)
    }

    /// Get a `AtomicSwitch` drain controlled by this `AtomicSwitchCtrl`
    pub fn drain(&self) -> AtomicSwitch<E> {
        AtomicSwitch(self.0.clone())
    }
}

impl<E> Drain for AtomicSwitch<E> {
    type Error = E;
    fn log(&self, info: &Record, logger_values: &OwnedKeyValueList) -> std::result::Result<(), E> {
        self.0.get().log(info, logger_values)
    }
}

`trivial_casts` and `unused_qualification` warnings in `o!` macro

trivial_casts and unused_qualification warnings in o! macro.
This should be fixed or add #[allow(..)] attribute at the macro definition.

Code:

#![warn(trivial_casts)]
#![warn(unused_qualifications)]

#[macro_use]
extern crate slog;
extern crate slog_term;

use slog::RecordInfo;
use slog::drain::IntoLogger;

use std::sync::Arc;

fn main() {
    let log = slog_term::stderr().into_logger(o!{
        "module" => |rec: &RecordInfo| rec.module().to_string()
    });
    let arc = Arc::new(123);
    info!(log, "arc", "arc" => *arc);
}

Output:

<slog macros>:6:7: 7:19 warning: trivial cast: `std::sync::Arc<[closure@src/main.rs:15:21: 15:64]>` as `std::sync::Arc<slog::ser::SyncSerialize + 'static>`. Cast can be replaced by coercion, this might require type ascription or a temporary variable
<slog macros>:6 $ k , std :: sync :: Arc :: new ( $ v ) as std :: sync :: Arc < $ crate :: ser
                      ^
<slog macros>:3:11: 7:29 note: in this expansion of vec! (defined in <std macros>)
src/main.rs:14:47: 16:6 note: in this expansion of o! (defined in <slog macros>)
src/main.rs:1:9: 1:22 note: lint level defined here
src/main.rs:1 #![warn(trivial_casts)]
                      ^~~~~~~~~~~~~
<slog macros>:6:7: 6:32 warning: unnecessary qualification
<slog macros>:6 $ k , std :: sync :: Arc :: new ( $ v ) as std :: sync :: Arc < $ crate :: ser
                      ^~~~~~~~~~~~~~~~~~~~~~~~~
<slog macros>:3:11: 7:29 note: in this expansion of vec! (defined in <std macros>)
src/main.rs:14:47: 16:6 note: in this expansion of o! (defined in <slog macros>)
src/main.rs:2:9: 2:30 note: lint level defined here
src/main.rs:2 #![warn(unused_qualifications)]
                      ^~~~~~~~~~~~~~~~~~~~~
<slog macros>:6:44: 7:19 warning: unnecessary qualification
<slog macros>:6 $ k , std :: sync :: Arc :: new ( $ v ) as std :: sync :: Arc < $ crate :: ser
                                                           ^
<slog macros>:3:11: 7:29 note: in this expansion of vec! (defined in <std macros>)
src/main.rs:14:47: 16:6 note: in this expansion of o! (defined in <slog macros>)
src/main.rs:2:9: 2:30 note: lint level defined here
src/main.rs:2 #![warn(unused_qualifications)]
                      ^~~~~~~~~~~~~~~~~~~~~

`SwitchOnSignal` drain.

A drain handling signal by switching a drain. That would be useful for production debugging, as described in the README:

  • drains are run-time swappable - Send a signal to your program and start logging everything to a file for run-time production debugging. Send another one when you're done to return to normal operation. Build your own flexible scenarios easily.

Alternatives to slog-rs

Hi!

Seems like we're both doing the same thing: https://github.com/3Hren/blacklog. Even goals are nearly the same.

I've started this project as a port of my another logging library for C++ focusing on structured logs, performance and configuration from generic source.

Since both our projects in the early alpha stage, maybe we should to calm down and reunite our forces on neutral territory?

What I suggest:

  • Create a separate repo/organization with name we both like.
  • Declare the manifest, which describes how we code, what goals we have etc.
  • Prove each PR with tests and benchmarks. Automate with Travis CI and maybe homu.

Alternatives:

  • Bog off, I want my own crate!

Alterantive names for macros.

trace! would have an alternative slog_trace! alias and so on.

In case of macro name conflicts between log and slog user could just selectively import alternative names, and use this.

Unable to log any trace output

No matter how I configure my Cargo.toml, I am unable to produce any trace output.

The latest attempt is below:

[dependencies.slog]
version = "1.0.0-alpha6"
default-features = false
features = ["release_max_level_trace", "max_level_trace"]

After digging around a bit I believe the culprit is Cargo not honoring the default-features = false flag.

It seems that all the features are enabled (in this case, "release_max_level_info, release_max_level_trace, max_level_debug, and max_level_trace"). Due to the if clause in lib.rs, and a normal debug build, "max_level_debug" is always hit, and trace can never be enabled.

Update
Running cargo build --verbose shows the following passed to rustc (and includes all 4 dependencies):

     Running `rustc /home/jozias/projects/slog-rs/src/lib.rs --crate-name slog --crate-type lib -g --cfg feature=\"max_level_trace\" --cfg feature=\"release_max_level_info\" --cfg feature=\"max_level_debug\" --cfg feature=\"default\" -C metadata=b5fec68b10428a12 --out-dir /home/jozias/projects/trace/target/debug/deps --emit=dep-info,link -L dependency=/home/jozias/projects/trace/target/debug/deps`

So this looks like a bug in Cargo where it isn't removing the default dependencies even when default-features = false is used.

I'm going to open an issue on the cargo project.

Optimize performance

https://github.com/dpc/slog-rs/wiki/Bench-log

Ideas:

  • &'a str in RecordInfo`
  • static dispatch - 39e6b5e
  • measure perf of closure-values
  • stdlog not to allocate String
  • Arc chaining instead of copying in Logger hierarchies?
  • closure-values not to allocate anything - implement SerializeKey for Fn(&RecordInfo, mut io::Writer) ? so the value can output itself without returning?
  • use the same feature that standard log uses to remove logging statesments at compile time. Now that macros are being used, this should work smoothly.

Final touches

  • flatten drain and logger module into root namespace
  • RecordInfo -> Record
  • Node -> List
  • move atomic switcher to separate crate, to remove crossbeam dependency
  • IntoMsg -> Message trait
    • Use write_to where possible for speedup?
  • Remove rustc_serialize dep
  • Write drain to old-style logging, so libraries can take Option<Logger> and use drain to old-style logging in case their user doesn't want to use slog.
    • Document it somewhere
  • More documentation!
  • Move decorators out of the slog create? This way they can be improved after 1.0 release, and eventually even moved back to main crate, without breaking compatibility.
  • Lazy values that can actually write to io::Write? Only then allocation can be completely avoided.

Bunyan format

Would be nice to have Bunyan output format, so we can keep using the same rich filtering and analysis tools across languages.

slog-stream unpublished

Iโ€™m unable to locate the slog-stream crate on crates.io. Is it possible to depend on it through some other mechanism?

Fails to compile on windows: error: unresolved name `lvl` [E0425]

When compiling a crate that uses slog-rs on Windows, I get the following:

<slog macros>:2:22: 2:25 error: unresolved name `lvl` [E0425]
<slog macros>:2 let lvl = $ lvl ; if lvl . as_usize (  ) <= $ crate:: __slog_static_max_level
                                     ^~~
<slog macros>:2:1: 2:48 note: in this expansion of log! (defined in <slog macros>)
src\main.rs:7:5: 7:44 note: in this expansion of trace! (defined in <slog macros>)

This happens for any log level. Potential blocker for the 1.0.0 release?

I just discovered it, so I'm still investigating the cause / fix.

I was using rustc 1.9.0 (e4e8b6668 2016-05-18)


Minimal example to reproduce (I use git bash):

cd /tmp
cargo new use_slog
cd use_slog
echo 'slog = "1.0.0-alpha3"' >> Cargo.toml
echo 'slog-term = "1.0.0-alpha3"' >> Cargo.toml
rm -f src/lib.rs
cat > src/main.rs << EOF
#[macro_use]
extern crate slog;
extern crate slog_term;

fn main() {
    let log = slog::Logger::root(slog_term::streamer().full().build(), o!());
    trace!(log, "logging a trace message");
}
EOF
cargo build

slog_stdlog::scope

slog_stdlog::scope(
    |prev_logger| { prev_logger.new(o!("more-data" => 2)) },
    || {
       /// code to be executed
        ....

      //// old logging statement to be used with a logger with `"more-data"`
      info!("check out more data");
});

info!("prev_logger will be used here");

Question: HowTo call logger via macro in modules

Hi. I'm kindly fresh to rust and I'm actually building a nickel-rs powered API.

I would like to implement slog-rs in the API, so I can use the logger within different modules and middlewares, to log data like: users accessing the API.

While I have a main.rs as starting point, a lib.rs as library and dozens of modules like middlewares, controllers, etc., I can't get the point, where I have to put the code to instantiate the logger, to let me call macros from these different modules, middlewares, controllers, etc.

I would be very glad, if you can point me, where I could implement this, so I can call the logging instance from different modules via a macro.

Hope you get, what I try to explain.

Yaml/toml/json builders.

Implement a crate that reads a configuration file and creates a drain defined in it. Box<Drain> will be used all over the place, which is supported and perfectly fine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.