about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-10-09 07:31:36 -0700
committerbors <bors@rust-lang.org>2013-10-09 07:31:36 -0700
commit2e64a718ea7db51f79a46441907bf659cb761e9c (patch)
tree21763a628e345263523b01905de4b57ca2063259
parenta3b04c1535ab0e733e59b8e1f7801e523cd72fa3 (diff)
parent88593fc3fc808e78dd89be95c997c94ba4c816da (diff)
downloadrust-2e64a718ea7db51f79a46441907bf659cb761e9c.tar.gz
rust-2e64a718ea7db51f79a46441907bf659cb761e9c.zip
auto merge of #9664 : alexcrichton/rust/logging, r=huonw
This makes some headway on #3309, see commits for details.
-rw-r--r--src/librustc/middle/trans/expr.rs12
-rw-r--r--src/librustc/rustc.rs3
-rw-r--r--src/libstd/logging.rs115
-rw-r--r--src/libstd/rt/logging.rs21
-rw-r--r--src/rt/rust_builtin.cpp21
-rw-r--r--src/rt/rustrt.def.in3
-rw-r--r--src/test/auxiliary/logging_right_crate.rs14
-rw-r--r--src/test/run-pass/logging-right-crate.rs30
8 files changed, 143 insertions, 76 deletions
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index d31ca763209..7d772a997c1 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -119,6 +119,7 @@ use back::link;
 use lib::llvm::{ValueRef, llvm, SetLinkage, False};
 use lib;
 use metadata::csearch;
+use metadata::cstore;
 use middle::trans::_match;
 use middle::trans::adt;
 use middle::trans::asm;
@@ -1799,9 +1800,14 @@ pub fn trans_log_level(bcx: @mut Block) -> DatumBlock {
     let ccx = bcx.ccx();
 
     let (modpath, modname) = {
-        let path = &mut bcx.fcx.path;
-        let mut modpath = ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))];
-        for e in path.iter() {
+        let srccrate = match ccx.external_srcs.find(&bcx.fcx.id) {
+            Some(&src) => {
+                cstore::get_crate_data(ccx.sess.cstore, src.crate).name
+            }
+            None => ccx.link_meta.name,
+        };
+        let mut modpath = ~[path_mod(ccx.sess.ident_of(srccrate))];
+        for e in bcx.fcx.path.iter() {
             match *e {
                 path_mod(_) => { modpath.push(*e) }
                 _ => {}
diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs
index 7cc1943a453..aa1ec26d426 100644
--- a/src/librustc/rustc.rs
+++ b/src/librustc/rustc.rs
@@ -197,9 +197,6 @@ pub fn describe_debug_flags() {
 }
 
 pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
-    // Don't display log spew by default. Can override with RUST_LOG.
-    ::std::logging::console_off();
-
     let mut args = args.to_owned();
     let binary = args.shift().to_managed();
 
diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs
index 27a2af95a2a..5e1ef3658b3 100644
--- a/src/libstd/logging.rs
+++ b/src/libstd/logging.rs
@@ -8,40 +8,101 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Logging
+/*!
 
-use fmt;
-use option::*;
-use os;
-use rt;
-use rt::logging::{Logger, StdErrLogger};
+Logging
 
-/// Turns on logging to stdout globally
-pub fn console_on() {
-    rt::logging::console_on();
-}
+This module is used by the compiler when emitting output for the logging family
+of macros. The methods of this module shouldn't necessarily be used directly,
+but rather through the logging macros defined.
 
-/**
- * Turns off logging to stdout globally
- *
- * Turns off the console unless the user has overridden the
- * runtime environment's logging spec, e.g. by setting
- * the RUST_LOG environment variable
- */
-pub fn console_off() {
-    // If RUST_LOG is set then the console can't be turned off
-    if os::getenv("RUST_LOG").is_some() {
-        return;
-    }
+There are five macros that the logging subsystem uses:
+
+* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
+                       related `format!` arguments
+* `debug!(...)` - a macro hard-wired to the log level of 4
+* `info!(...)` - a macro hard-wired to the log level of 3
+* `warn!(...)` - a macro hard-wired to the log level of 2
+* `error!(...)` - a macro hard-wired to the log level of 1
+
+All of these macros use the same style of syntax as the `format!` syntax
+extension. Details about the syntax can be found in the documentation of
+`std::fmt` along with the Rust tutorial/manual
+
+## Enabling logging
+
+Log levels are controlled on a per-module basis, and by default all logging is
+disabled except for `error!` (a log level of 1). Logging is controlled via the
+`RUST_LOG` environment variable. The value of this environment variable is a
+comma-separated list of logging directives. A logging directive is of the form:
+
+```
+path::to::module=log_level
+```
+
+The path to the module is rooted in the name of the crate it was compiled for,
+so if your program is contained in a file `hello.rs`, for example, to turn on
+logging for this file you would use a value of `RUST_LOG=hello`. Furthermore,
+this path is a prefix-search, so all modules nested in the specified module will
+also have logging enabled.
+
+The actual `log_level` is optional to specify. If omitted, all logging will be
+enabled. If specified, the it must be either a numeric in the range of 1-255, or
+it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric
+is specified, then all logging less than or equal to that numeral is enabled.
+For example, if logging level 3 is active, error, warn, and info logs will be
+printed, but debug will be omitted.
+
+As the log level for a module is optional, the module to enable logging for is
+also optional. If only a `log_level` is provided, then the global log level for
+all modules is set to this value.
 
-    rt::logging::console_off();
+Some examples of valid values of `RUST_LOG` are:
+
+```
+hello                // turns on all logging for the 'hello' module
+info                 // turns on all info logging
+hello=debug          // turns on debug logging for 'hello'
+hello=3              // turns on info logging for 'hello'
+hello,std::hashmap   // turns on hello, and std's hashmap logging
+error,hello=warn     // turn on global error logging and also warn for hello
+```
+
+## Performance and Side Effects
+
+Each of these macros will expand to code similar to:
+
+```rust
+if log_level <= my_module_log_level() {
+    ::std::logging::log(log_level, format!(...));
 }
+```
 
-#[allow(missing_doc)]
-pub fn log(_level: u32, args: &fmt::Arguments) {
-    use rt::task::Task;
-    use rt::local::Local;
+What this means is that each of these macros are very cheap at runtime if
+they're turned off (just a load and an integer comparison). This also means that
+if logging is disabled, none of the components of the log will be executed.
+
+## Useful Values
+
+For convenience, if a value of `::help` is set for `RUST_LOG`, a program will
+start, print out all modules registered for logging, and then exit.
 
+*/
+
+use fmt;
+use option::*;
+use rt::local::Local;
+use rt::logging::{Logger, StdErrLogger};
+use rt::task::Task;
+
+/// This function is called directly by the compiler when using the logging
+/// macros. This function does not take into account whether the log level
+/// specified is active or not, it will always log something if this method is
+/// called.
+///
+/// It is not recommended to call this function directly, rather it should be
+/// invoked through the logging family of macros.
+pub fn log(_level: u32, args: &fmt::Arguments) {
     unsafe {
         let optional_task: Option<*mut Task> = Local::try_unsafe_borrow();
         match optional_task {
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
index 8b8e2762381..b08e76921d8 100644
--- a/src/libstd/rt/logging.rs
+++ b/src/libstd/rt/logging.rs
@@ -10,7 +10,7 @@
 
 use fmt;
 use from_str::from_str;
-use libc::{uintptr_t, exit};
+use libc::exit;
 use option::{Some, None, Option};
 use rt;
 use rt::util::dumb_println;
@@ -174,9 +174,7 @@ pub struct StdErrLogger;
 
 impl Logger for StdErrLogger {
     fn log(&mut self, args: &fmt::Arguments) {
-        if should_log_console() {
-            fmt::writeln(self as &mut rt::io::Writer, args);
-        }
+        fmt::writeln(self as &mut rt::io::Writer, args);
     }
 }
 
@@ -222,21 +220,6 @@ pub fn init() {
     }
 }
 
-#[fixed_stack_segment] #[inline(never)]
-pub fn console_on() { unsafe { rust_log_console_on() } }
-
-#[fixed_stack_segment] #[inline(never)]
-pub fn console_off() { unsafe { rust_log_console_off() } }
-
-#[fixed_stack_segment] #[inline(never)]
-fn should_log_console() -> bool { unsafe { rust_should_log_console() != 0 } }
-
-extern {
-    fn rust_log_console_on();
-    fn rust_log_console_off();
-    fn rust_should_log_console() -> uintptr_t;
-}
-
 // Tests for parse_logging_spec()
 #[test]
 fn parse_logging_spec_valid() {
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index d1d4286a7c6..13fc3f1aa81 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -320,27 +320,6 @@ rust_mktime(rust_tm* timeptr) {
     return mktime(&t);
 }
 
-static lock_and_signal log_lock;
-static bool log_to_console = true;
-
-extern "C" CDECL void
-rust_log_console_on() {
-    scoped_lock with(log_lock);
-    log_to_console = true;
-}
-
-extern "C" CDECL void
-rust_log_console_off() {
-    scoped_lock with(log_lock);
-    log_to_console = false;
-}
-
-extern "C" CDECL uintptr_t
-rust_should_log_console() {
-    scoped_lock with(log_lock);
-    return log_to_console;
-}
-
 extern "C" lock_and_signal*
 rust_create_little_lock() {
     return new lock_and_signal();
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 30f60c662e9..959d1fa85f3 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -17,9 +17,6 @@ rust_get_stderr
 rust_list_dir_val
 rust_list_dir_wfd_size
 rust_list_dir_wfd_fp_buf
-rust_log_console_on
-rust_log_console_off
-rust_should_log_console
 rust_unset_sigprocmask
 rust_env_pairs
 rust_win32_rand_acquire
diff --git a/src/test/auxiliary/logging_right_crate.rs b/src/test/auxiliary/logging_right_crate.rs
new file mode 100644
index 00000000000..84bf6f0240f
--- /dev/null
+++ b/src/test/auxiliary/logging_right_crate.rs
@@ -0,0 +1,14 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo<T>() {
+    fn death() -> int { fail2!() }
+    debug2!("{:?}", (||{ death() })());
+}
diff --git a/src/test/run-pass/logging-right-crate.rs b/src/test/run-pass/logging-right-crate.rs
new file mode 100644
index 00000000000..21b45cec235
--- /dev/null
+++ b/src/test/run-pass/logging-right-crate.rs
@@ -0,0 +1,30 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:logging_right_crate.rs
+// xfail-fast
+// exec-env:RUST_LOG=logging-right-crate=debug
+
+// This is a test for issue #3046 to make sure that when we monomorphize a
+// function from one crate to another the right top-level logging name is
+// preserved.
+//
+// It used to be the case that if logging were turned on for this crate, all
+// monomorphized functions from other crates had logging turned on (their
+// logging module names were all incorrect). This test ensures that this no
+// longer happens by enabling logging for *this* crate and then invoking a
+// function in an external crate which will fail when logging is enabled.
+
+extern mod logging_right_crate;
+
+fn main() {
+    // this function fails if logging is turned on
+    logging_right_crate::foo::<int>();
+}