Coder Social home page Coder Social logo

env_logger's People

Contributors

alexcrichton avatar atouchet avatar brambonne avatar budziq avatar divergentdave avatar dtolnay avatar eijebong avatar epage avatar fugangqiang avatar gtsiam avatar hcpl avatar huonw avatar ifreund avatar jimmycuadra avatar jplatte avatar kodraus avatar mainrs avatar matthiasbeyer avatar mjkillough avatar morrme avatar oherrala avatar peter-kehl avatar quadrupleslap avatar renovate[bot] avatar rnestler avatar salewski avatar sebasmagri avatar sfackler avatar shepmaster avatar tmccombs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

env_logger's Issues

timestamps with milliseconds

I read through #87 and I can't help but (humbly) second-guess (no pun intended) the decision. In my opinion, second-level precision is too coarse, and nanosecond-level is too fine, and milliseconds are the happy medium. And I would argue that it doesn't even need to be configurable. I'd propose that if default_format_timestamp logged millisecond-level timestamps, that would be good enough for almost everybody. I realize humantime doesn't support milliseconds, so I guess this would mean going back to chronos, unless we can convince humantime to add that...

Slowness

As soon as you enable RUST_LOG, even for just a small module that logs infrequently, the performance of your program is going to go drastically downhill.

Example: https://i.imgur.com/al4BJUn.png

+   94.04%     0.39%  rust-bitcoin-in  rust-bitcoin-indexer  [.] <serde_json::read::IoRead<R> as serde_json::read::Read<
+   93.61%     0.48%  rust-bitcoin-in  rust-bitcoin-indexer  [.] serde_json::read::next_or_eof                          
+   93.19%     0.60%  rust-bitcoin-in  rust-bitcoin-indexer  [.] std::io::read_one_byte                                 
+   92.55%     0.14%  rust-bitcoin-in  rust-bitcoin-indexer  [.] std::io::impls::<impl std::io::Read for &'a mut R>::rea
+   92.43%     1.50%  rust-bitcoin-in  rust-bitcoin-indexer  [.] <hyper::client::response::Response as std::io::Read>::r
+   91.04%     0.27%  rust-bitcoin-in  rust-bitcoin-indexer  [.] <hyper::http::h1::Http11Message as std::io::Read>::read
+   90.72%     2.96%  rust-bitcoin-in  rust-bitcoin-indexer  [.] <hyper::http::h1::HttpReader<R> as std::io::Read>::read
-   86.85%    82.85%  rust-bitcoin-in  rust-bitcoin-indexer  [.] log::__log                                             
   - 80.92% <serde_json::read::IoRead<R> as serde_json::read::Read<'de>>::parse_str                                     
      + serde_json::read::next_or_eof                                                                                   
   + 4.00% log::__log                                                                                                   
   + 1.91% jsonrpc::client::Client::send_request                                                                        
+    2.44%     0.02%  rust-bitcoin-in  rust-bitcoin-indexer  [.] rust_bitcoin_indexer::db::parse_node_block             
+    2.20%     0.00%  rust-bitcoin-in  rust-bitcoin-indexer  [.] jsonrpc::client::Client::send_request                  
+    2.18%     0.00%  rust-bitcoin-in  rust-bitcoin-indexer  [.] serde::de::impls::<impl serde::de::Deserialize<'de> for
+    2.18%     0.00%  rust-bitcoin-in  rust-bitcoin-indexer  [.] <&'a mut serde_json::de::Deserializer<R> as serde::de::
+    2.17%     0.00%  rust-bitcoin-in  rust-bitcoin-indexer  [.] serde_json::de::from_reader                            
+    2.01%     1.91%  rust-bitcoin-in  rust-bitcoin-indexer  [.] log::logger                                            
+    1.71%     0.43%  rust-bitcoin-in  rust-bitcoin-indexer  [.] <env_logger::Logger as log::Log>::log                  
+    1.59%     0.13%  rust-bitcoin-in  rust-bitcoin-indexer  [.] core::fmt::write                                       
+    1.44%     1.21%  rust-bitcoin-in  rust-bitcoin-indexer  [.] bitcoin::util::misc::he                     

As you can see, just because serde_json::read::Read has some trace! in parse_str somewhere, is completely destroying my program, for which I've enabled debugging just for my main module.

Is there anything that can be done about it?

Tweaks to the default format and format stability

Our current env_logger format is pretty good, but I think there are a few tweaks we can make to it that would improve readability, parsability and compactness. Before that though, I think it would be good if we thought about whether or not we consider the default format as part of our semver'd API.

Changing the default format in patches

I think we should be mindful, but not against changing the default format in patches. We do eventually want it to be fairly stable, but if a user needs a truly stable format then they should use a custom format.

I'm keen to hear what other people think about this!

Improvements to our default format

I think we can make some tweaks to our current format that should be an improvement for the majority of users:

  • Wrap parts of the format that aren't the actual message in brackets so they're easier to distinguish from the message. This also means all logs (unless you disable all optional parts of the format) will start on a new line with the same character.
  • Shorten the log level so they're all the same length. So:
    • Trace => TRC
    • Debug => DBG
    • Info => INF
    • Warn => WRN
    • Error => ERR

To see how this might look, here's a few examples using our current format, and the changes I was thinking about:

Proposed format:
proposed-all

Current format:
current-all

Proposed format:
proposed-multi-line

Current format:
current-multi-line

This is also a bit subjective, so I'd like to know what you all think about the current and proposed format too!

Add gray color[s].

Gray colors are useful for the less-than-essential details. But it looks like this uses termcolor, so maybe I should open an issue on BurntSushi/ripgrep instead?

Detect type of output to omit coloring in redirected output.

May be it is not so clear title, but

On Windows with default formatter, colors are enabled. When running some app with env_logger inside console, it outputs colored messaged.
So it does (tries to do) when you redirect your app to a file (via app.exe 2> app.log) and that file becomes pretty messy (full of lines like �[m�[32m INFO�[m 2018-01-17T14:56:26Z).

I think it would be worth to detect whether STDERR is a tty (console in terms of Windows) or a file.

I am not sure whether it is an issue of env_logger or termcolor, but ripgrep, for instance, behaves correctly. So may be it can be done here.

LogLevelFilter - overhead effect

Hello,

log = "0.3.8"
env_logger = "0.4.3"

Is it free to use macro debug! or trace! when LogLevelFilter is set to Info? LogLevelFilter::Info
Is There extra overhead when using LogLevelFilter::Info or LogLevelFilter::Debug and using trace!(very_large_stream)? is it not called or is redirected to /dev/null? how it done? is it in runtime or at compile time?
`
let mut builder = LogBuilder::new();

if matches.is_present("debug") {
    let format = |record: &LogRecord| {
        format!(
            "{} [{}] {}:{} {:?} - {}",
            Local::now().format("%d-%m-%Y %H:%M:%S"),
            record.level(),
            record.location().file(),
            record.location().line(),
            thread::current().id(),
            record.args()
        )
    };


    if matches.is_present("trace") {
        builder.format(format).filter(None, LogLevelFilter::Trace);
    } else {
        builder.format(format).filter(None, LogLevelFilter::Debug);
    }

} else {
    let format = |record: &LogRecord| {
        format!(
            "{} [{}] - {}",
            Local::now().format("%d-%m-%Y %H:%M:%S"),
            record.level(),
            record.args()
        )
    };

    builder.format(format).filter(None, LogLevelFilter::Info);
}

builder.init().unwrap();

`

Tracking issue for API guidelines review

env_logger already got some care during the log review. Lets do an additional pass to conform with the API guidelines as a separate crate.

Crate conformance checklist

  • Organization (crate is structured in an intelligible way)
    • Crate root re-exports common functionality ([C-REEXPORT])
    • Modules provide a sensible API hierarchy ([C-HIERARCHY])
  • Naming (crate aligns with Rust naming conventions)
    • Casing conforms to RFC 430 ([C-CASE])
    • Ad-hoc conversions follow as_, to_, into_ conventions ([C-CONV])
    • Methods on collections that produce iterators follow iter, iter_mut, into_iter ([C-ITER])
    • Iterator type names match the methods that produce them ([C-ITER-TY])
    • Ownership suffixes use _mut and _ref ([C-OWN-SUFFIX])
    • Single-element containers implement appropriate getters ([C-GETTERS])
  • Interoperability (crate interacts nicely with other library functionality)
    • Types eagerly implement common traits ([C-COMMON-TRAITS])
      • Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug,
        Display, Default
    • Conversions use the standard traits From, AsRef, AsMut ([C-CONV-TRAITS])
    • Collections implement FromIterator and Extend ([C-COLLECT])
    • Data structures implement Serde's Serialize, Deserialize ([C-SERDE])
    • Crate has a "serde" cfg option that enables Serde ([C-SERDE-CFG])
    • Types are Send and Sync where possible ([C-SEND-SYNC])
    • Error types are Send and Sync ([C-SEND-SYNC-ERR])
    • Error types are meaningful, not () ([C-MEANINGFUL-ERR])
    • Binary number types provide Hex, Octal, Binary formatting ([C-NUM-FMT])
  • Macros (crate presents well-behaved macros)
    • Input syntax is evocative of the output ([C-EVOCATIVE])
    • Macros compose well with attributes ([C-MACRO-ATTR])
    • Item macros work anywhere that items are allowed ([C-ANYWHERE])
    • Item macros support visibility specifiers ([C-MACRO-VIS])
    • Type fragments are flexible ([C-MACRO-TY])
  • Documentation (crate is abundantly documented)
    • Crate level docs are thorough and include examples ([C-CRATE-DOC])
    • All items have a rustdoc example ([C-EXAMPLE])
    • Examples use ?, not try!, not unwrap ([C-QUESTION-MARK])
    • Function docs include error conditions in "Errors" section ([C-ERROR-DOC])
    • Function docs include panic conditions in "Panics" section ([C-PANIC-DOC])
    • Prose contains hyperlinks to relevant things ([C-LINK])
    • Cargo.toml publishes CI badges for tier 1 platforms ([C-CI])
    • Cargo.toml includes all common metadata ([C-METADATA])
      • authors, description, license, homepage, documentation, repository,
        readme, keywords, categories
    • Crate sets html_root_url attribute "https://docs.rs/$crate/$version" ([C-HTML-ROOT])
    • Cargo.toml documentation key points to "https://docs.rs/$crate" ([C-DOCS-RS])
    • Release notes document all significant changes ([C-RELNOTES])
  • Predictability (crate enables legible code that acts how it looks)
    • Smart pointers do not add inherent methods ([C-SMART-PTR])
    • Conversions live on the most specific type involved ([C-CONV-SPECIFIC])
    • Functions with a clear receiver are methods ([C-METHOD])
    • Functions do not take out-parameters ([C-NO-OUT])
    • Operator overloads are unsurprising ([C-OVERLOAD])
    • Only smart pointers implement Deref and DerefMut ([C-DEREF])
    • Deref and DerefMut never fail ([C-DEREF-FAIL])
    • Constructors are static, inherent methods ([C-CTOR])
  • Flexibility (crate supports diverse real-world use cases)
    • Functions expose intermediate results to avoid duplicate work ([C-INTERMEDIATE])
    • Caller decides where to copy and place data ([C-CALLER-CONTROL])
    • Functions minimize assumptions about parameters by using generics ([C-GENERIC])
    • Traits are object-safe if they may be useful as a trait object ([C-OBJECT])
  • Type safety (crate leverages the type system effectively)
    • Newtypes provide static distinctions ([C-NEWTYPE])
    • Arguments convey meaning through types, not bool or Option ([C-CUSTOM-TYPE])
    • Types for a set of flags are bitflags, not enums ([C-BITFLAG])
    • Builders enable construction of complex values ([C-BUILDER])
  • Dependability (crate is unlikely to do the wrong thing)
    • Functions validate their arguments ([C-VALIDATE])
    • Destructors never fail ([C-DTOR-FAIL])
    • Destructors that may block have alternatives ([C-DTOR-BLOCK])
  • Debuggability (crate is conducive to easy debugging)
    • All public types implement Debug ([C-DEBUG])
    • Debug representation is never empty ([C-DEBUG-NONEMPTY])
  • Future proofing (crate is free to improve without breaking users' code)
    • Structs have private fields ([C-STRUCT-PRIVATE])
    • Newtypes encapsulate implementation details ([C-NEWTYPE-HIDE])
  • Necessities (to whom they matter, they really matter)
    • Public dependencies of a stable crate are stable ([C-STABLE])
    • Crate and its dependencies have a permissive license ([C-PERMISSIVE])

Support reparsing filters at runtime

Originally raised in #103

Currently, I don't see a nice way to change logging levels dynamically. (Or is there?). It is not very friendly with log::set_max_level_filter either to able to make even small changes.

Would be nice to be able to make small changes if not full reparse during runtime. It becomes extremely helpful in server environments to be able to to that.

Support and clearly document a means to change the default log level

I often write projects in Python where my logging level should be warn or even info if the user doesn't specify anything.

Currently, the docs are unclear whether there's a way to set a logging level, but still allow it to be overridden by RUST_LOG, other than by checking for the RUST_LOG environment variable and setting it if it's absent before calling env_logger::init()... a solution which, I think you'll agree, looks like an ugly hack.

Make it easy to define a slightly different format (without writing a formatter from scratch)

Hi there!

While it is possible to define a custom formatting via the Builder, often one only wants to adjust small things. For example, the timestamp is way too noisy for my application, so I want to disable it. But now I have to do everything else by myself. Especially right now I cannot use colors, so I cannot implement the formatting I want. It would be nice to say something like builder.with_timestamps(false). Sure, this would introduce one (or a few, if we want to add options for other parts -- like the module path -- as well) boolean flag that has to be checked for each log message. But that should be fine, right?

Figure out logging output

We've got a couple of open questions related to the logging sink:

  • Colour support (#2)
  • Alternative sinks (right now we support stdout, stderr and null)
  • Issues with unbuffered writes to stderr when there are multiple threads/processes involved (#19 (comment))
  • Efficiency. We don't want to spend more time than necessary processing logs
  • Any other concerns?

It would be good to iterate towards a design that satisfies all these things, without complicating things too much. I think it might be worth looking at opening up the Target enum into a trait, and seeing where that gets us.

Issues to file

  • Support UTC timestamps in default format
  • Lock/buffer stderr

Make the color API public

There's a private API for writing colours that we use in the default format. This should be public so anyone building their own format can use it. Colours currently use an enum from termcolor, which means we'd need to make it a public dependency, or wrap it somehow.

Release 0.5.0

Once log has an 0.4.0 release out we should get env_logger 0.5.0 out. Before that, we should sort out:

  • #13
  • #42
  • #47
  • #48
  • Pass over docs (broken links, missing examples)

stdweb

would it be reasonable to add wasm support via stdweb?

changing target to stdout did not take effect?

Hello,

I'm changing println! to info! when using the env_logger and trying to change target to stdout. However it does not seem to make any different. All logs still go to console. Is not it supposed to be different?

Cargo.toml:

[dependencies]
log = "0.4"
env_logger = "0.5"

lib.rs:

extern crate log;
extern crate env_logger;.

logger.rs
extern crate log;
extern crate env_logger;

use std::env;
use log::*;
use self::env_logger::{Builder, Target};

::std::env::set_var("RUST_LOG", "info");

println!("env RUST_LOG as {:?}", env::var("RUST_LOG"));

let mut builder = Builder::new();
builder.target(Target::Stdout);
if env::var("RUST_LOG").is_ok() {
    builder.parse(&env::var("RUST_LOG").unwrap());
}
builder.init();
info!("builder={:?}", builder);

Note that I did get following error and not sure why So I made change as instructed by adding "self", it passed.

8 | use env_logger::{Builder, Target};
| ^^^^^^^^^^ Did you mean self::env_logger?

==========================
Here is the output of cargo run as well as docker run:

env RUST_LOG as Ok("info")
INFO 2018-11-02T19:17:37Z: myapp::utils::logger: builder=Logger { filter: Filter { filter: None, directives: [] }, writer: Logger { target: Stdout, write_style: Auto } }

Include timestamp on default format

We should include an ISO-formatted timestamp on the default log format. It's not uncommon for apps running in virtualised or headless environments to capture stdout/stderr for later review, and having timestamps is a helpful bit of insight.

Since formats are configurable, tools like cargo that are probably being watched can opt-out of displaying a timestamp to reduce noise.

Add a toggle to enable more precise timestamp

In my application I really need to see the exact time it takes in milliseconds between each log. This will give me an idea if something is slow.

As suggested here, I'm asking if it would be possible to implement a toggle to have it more precise?

cargo test not capturing log outputs

I can't seem to get cargo test to properly capture either STDOUT or STDERR when logging with env_logger. My understanding is that cargo should capture both when tests pass and only show the results when tests fail.

Instead, all logs from env_logger/log macros are interleaved as the tests are running, and none are displayed in the "--- test_name stdout ----" section.

Here's the code I'm using:

extern crate env_logger;

#[test]
fn test_name() -> Result<(), Box<Error>> {
    env_logger::init();

    println!("PRINTLN"); // gets captured properly

    // none of these are captured
    error!("error"); 
    info!("info");
    trace!("trace");
    Err(Box::from("test"))
}

I don't have the same issue using another crate such as simple_logger:

#[test]
fn test_name() -> Result<(), Box<Error>> {
    simple_logger::init().unwrap();

    println!("PRINTLN");
    error!("error");
    info!("info");
    trace!("trace");
    Err(Box::from("test"))
}

Allow disabling the humantime dependency

Some environments, e.g. Kubernetes, already timestamp every log message. Thus, adding our own timestamp if wastefully duplicative. We currently have a custom formatter to disable the timestamping.

That works OK, as far as the runtime characteristic of the application are concerned. However, because Cargo downloads each dependency serially, and because Cargo builds each dependency serially, every single dependency inhibits the build performance by some constant factor that's independent of the complexity of the dependency. Some applications have continuous integration and/or container build systems that have to rebuild everything from scratch any time any dependency changes, and/or on every commit, so minimizing the from-scratch download + build time is important.

I noticed when upgrading such an application from env_logger 0.4 to env_logger 0.5 that chrono and then later humantime were added as dependencies. In our situation this is a regression, since it increases the number of dependencies (and thus the application size and the build time) compared to env_logger 0.4. We can't stay with env_logger 0.4 because some other libraries we use depend on env_logger 0.5 already; we're actually trying to optimize the build so that only only version of env_logger (0.5) needs to be built.

For these reasons, it would be beneficial to make the dependency on humantime, and the default timestamping functionality in general, optional, e.g. by making them configurable via a default feature, perhaps named "timestamp".

try_init shouldn't set the LevelFilter if there was already a logger

edit: sorry, pressed Enter too fast.

I've had an issue where our library (Spidermonkey) has two ways to initialize the global logger:

  • one in a standalone environment
  • one embedded in a bigger program (Firefox)

In the program case, the program will first initialize its logger with a specific LevelFilter; then the code runs into our initialization path that runs env_logger::try_init() which fails since a logger has already been set. Unfortunately, this also resets the LevelFilter. There's an easy workaround on our side, but I thought in general you wouldn't want to implicitly override the LevelFilter if there was already a logger set. Thoughts?

segv on arm7hf

Program received signal SIGSEGV, Segmentation fault.
0x0020ca34 in env_logger::Format::into_boxed_fn::_$u7b$$u7b$closure$u7d$$u7d$::ha67fa042fe85d5e5 ()
(gdb) bt
#0  0x0020ca34 in env_logger::Format::into_boxed_fn::_$u7b$$u7b$closure$u7d$$u7d$::ha67fa042fe85d5e5 ()
#1  0x0020b6d8 in _$LT$env_logger..Logger$u20$as$u20$log..Log$GT$::log::h9c942721ccf6110b ()
#2  0x002f9068 in carrier::main::h4eed1b21f4e13567 ()
#3  0x00304248 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h931ab8c3620c5b29 ()
#4  0x002f8d68 in main ()

Option to include thread name

I think it would be useful if env_logger had an option to include thread name.

E. g. RUST_LOG=myapp=debug?thread_name=true myapp

Would help debug multithreaded apps.

API Guidelines tracking issue

Allow disabling of the termcolor and atty dependencies

Some environments will never, or will practically never, output to a terminal, or otherwise do not ever need or want stylized output. This is often the case for an application that is intended to be deployed in a containerized environment like Kubernetes or Docker, for example.

Because Cargo downloads each dependency serially, and because Cargo builds each dependency serially, every single dependency inhibits the build performance by some constant factor that's independent of the complexity of the dependency. Further, some applications have continuous integration and/or container build systems that have to rebuild everything from scratch any time any dependency changes, and/or on every commit.

I noticed when upgrading such an application from env_logger 0.4 to env_logger 0.5 that termcolor and atty were added as dependencies. In our situation this is a regression, since it increases the number of dependencies (and thus the application size and the build time) compared to env_logger 0.4. We can't stay with env_logger 0.4 because some other libraries we use depend on env_logger 0.5 already; we're actually trying to optimize the build so that only only version of env_logger (0.5) needs to be built.

For these reasons, it would be beneficial to make the dependencies on termcolor and atty optional, controlled by a default feature, perhaps named "style" or "tty", so that we can use default-features = false to disable them. Or, otherwise, provide a way to get the configurability by environment variables that env_logger provides, without these dependencies.

Errors logged by default

Hello!

This is more of a question, but it seems the default loglevel for env_logger includes error. While I would like to allow setting a log level with RUST_LOG=, I would also like to fully disable logging if that environment variable isn't set because it's interfering with the process indicator. I have my own error handling and one of my dependencies is using error! in some cases which messes with the terminal.

I was wondering: What's the most elegant way to have an env_logger that defaults to "fully silent"? :)

What should we do for the next breaking (0.6.0) release?

Hi all!

The 0.5.x release of env_logger has been around for a while now, and I've started thinking it's about time to think about 0.6.x. I'd like to find out whether there's anything anyone would like changed while we've got the opportunity.

There are two changes I'd like to work into the new release that really just lay down a policy around logically breaking changes to the default format going forward:

  • #82 Where we allow changes to the default format in patches (we'll try to avoid it, but new features in log like structured logging would need additions to the format and requiring a breaking bump for these sorts of additions will limit discoverability).
  • #100 Where we make dependencies optional to reduce compile times. These dependencies mostly impact the default format, so when they're not available the format will change. We should be able to introduce new optional dependencies without requiring a breaking bump.

It's a bit of a fresh start with a (hopefully) clear policy around the format that lets us keep improving env_logger through its format while we're still 0.x. Post stabilization would be a new conversation.

Does anyone have any other thoughts on that? Or any other breaking improvements to the API they'd like to see?

Reduce noise in the timestamp format

Was raised in #33 that the current timestamp format is pretty verbose, but could be simpler while still being useful and valid RFC3339. We should:

  • Remove nanoseconds
  • Replace +00:00 with a simple Z

Behaviour when stdout is broken

Not sure if this is the correct place for this, and excuse me if this information is already in the docs 😅

How does this crate behave when stdout is broken? The std::print macro's panic when they can't write to stdout. I would hope this is not the case in this crate.
I had a look through the source code but I'm unable to find it.

Could color be disabled?

I really like the new format, including the color!

Unfortunately when the log output is piped and stored elsewhere (for example in AWS CloudWatch) I see all the control characters which makes reading the log actually harder.

Could the color be disabled with a feature flag?

Accept default log level

I noticed this a couple of times now: I'm considering using log and env_logger for my logging, but env_logger would require that I set RUST_LOG every time I want to actually have output, or I wouldn't get anything at all. What I want to do would be something along these lines:

env_logger::init_or("something=info");

So, if $RUST_LOG is not set, env_logger would use something=info instead. This could be overwritten with RUST_LOG= ./app, causing env_logger to use an empty string.

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.