Skip to content

Commit 2e64a71

Browse files
committed
auto merge of #9664 : alexcrichton/rust/logging, r=huonw
This makes some headway on #3309, see commits for details.
2 parents a3b04c1 + 88593fc commit 2e64a71

File tree

8 files changed

+143
-76
lines changed

8 files changed

+143
-76
lines changed

src/librustc/middle/trans/expr.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ use back::link;
119119
use lib::llvm::{ValueRef, llvm, SetLinkage, False};
120120
use lib;
121121
use metadata::csearch;
122+
use metadata::cstore;
122123
use middle::trans::_match;
123124
use middle::trans::adt;
124125
use middle::trans::asm;
@@ -1799,9 +1800,14 @@ pub fn trans_log_level(bcx: @mut Block) -> DatumBlock {
17991800
let ccx = bcx.ccx();
18001801

18011802
let (modpath, modname) = {
1802-
let path = &mut bcx.fcx.path;
1803-
let mut modpath = ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))];
1804-
for e in path.iter() {
1803+
let srccrate = match ccx.external_srcs.find(&bcx.fcx.id) {
1804+
Some(&src) => {
1805+
cstore::get_crate_data(ccx.sess.cstore, src.crate).name
1806+
}
1807+
None => ccx.link_meta.name,
1808+
};
1809+
let mut modpath = ~[path_mod(ccx.sess.ident_of(srccrate))];
1810+
for e in bcx.fcx.path.iter() {
18051811
match *e {
18061812
path_mod(_) => { modpath.push(*e) }
18071813
_ => {}

src/librustc/rustc.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,6 @@ pub fn describe_debug_flags() {
197197
}
198198

199199
pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
200-
// Don't display log spew by default. Can override with RUST_LOG.
201-
::std::logging::console_off();
202-
203200
let mut args = args.to_owned();
204201
let binary = args.shift().to_managed();
205202

src/libstd/logging.rs

Lines changed: 88 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,101 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! Logging
11+
/*!
1212
13-
use fmt;
14-
use option::*;
15-
use os;
16-
use rt;
17-
use rt::logging::{Logger, StdErrLogger};
13+
Logging
1814
19-
/// Turns on logging to stdout globally
20-
pub fn console_on() {
21-
rt::logging::console_on();
22-
}
15+
This module is used by the compiler when emitting output for the logging family
16+
of macros. The methods of this module shouldn't necessarily be used directly,
17+
but rather through the logging macros defined.
2318
24-
/**
25-
* Turns off logging to stdout globally
26-
*
27-
* Turns off the console unless the user has overridden the
28-
* runtime environment's logging spec, e.g. by setting
29-
* the RUST_LOG environment variable
30-
*/
31-
pub fn console_off() {
32-
// If RUST_LOG is set then the console can't be turned off
33-
if os::getenv("RUST_LOG").is_some() {
34-
return;
35-
}
19+
There are five macros that the logging subsystem uses:
20+
21+
* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
22+
related `format!` arguments
23+
* `debug!(...)` - a macro hard-wired to the log level of 4
24+
* `info!(...)` - a macro hard-wired to the log level of 3
25+
* `warn!(...)` - a macro hard-wired to the log level of 2
26+
* `error!(...)` - a macro hard-wired to the log level of 1
27+
28+
All of these macros use the same style of syntax as the `format!` syntax
29+
extension. Details about the syntax can be found in the documentation of
30+
`std::fmt` along with the Rust tutorial/manual
31+
32+
## Enabling logging
33+
34+
Log levels are controlled on a per-module basis, and by default all logging is
35+
disabled except for `error!` (a log level of 1). Logging is controlled via the
36+
`RUST_LOG` environment variable. The value of this environment variable is a
37+
comma-separated list of logging directives. A logging directive is of the form:
38+
39+
```
40+
path::to::module=log_level
41+
```
42+
43+
The path to the module is rooted in the name of the crate it was compiled for,
44+
so if your program is contained in a file `hello.rs`, for example, to turn on
45+
logging for this file you would use a value of `RUST_LOG=hello`. Furthermore,
46+
this path is a prefix-search, so all modules nested in the specified module will
47+
also have logging enabled.
48+
49+
The actual `log_level` is optional to specify. If omitted, all logging will be
50+
enabled. If specified, the it must be either a numeric in the range of 1-255, or
51+
it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric
52+
is specified, then all logging less than or equal to that numeral is enabled.
53+
For example, if logging level 3 is active, error, warn, and info logs will be
54+
printed, but debug will be omitted.
55+
56+
As the log level for a module is optional, the module to enable logging for is
57+
also optional. If only a `log_level` is provided, then the global log level for
58+
all modules is set to this value.
3659
37-
rt::logging::console_off();
60+
Some examples of valid values of `RUST_LOG` are:
61+
62+
```
63+
hello // turns on all logging for the 'hello' module
64+
info // turns on all info logging
65+
hello=debug // turns on debug logging for 'hello'
66+
hello=3 // turns on info logging for 'hello'
67+
hello,std::hashmap // turns on hello, and std's hashmap logging
68+
error,hello=warn // turn on global error logging and also warn for hello
69+
```
70+
71+
## Performance and Side Effects
72+
73+
Each of these macros will expand to code similar to:
74+
75+
```rust
76+
if log_level <= my_module_log_level() {
77+
::std::logging::log(log_level, format!(...));
3878
}
79+
```
3980
40-
#[allow(missing_doc)]
41-
pub fn log(_level: u32, args: &fmt::Arguments) {
42-
use rt::task::Task;
43-
use rt::local::Local;
81+
What this means is that each of these macros are very cheap at runtime if
82+
they're turned off (just a load and an integer comparison). This also means that
83+
if logging is disabled, none of the components of the log will be executed.
84+
85+
## Useful Values
86+
87+
For convenience, if a value of `::help` is set for `RUST_LOG`, a program will
88+
start, print out all modules registered for logging, and then exit.
4489
90+
*/
91+
92+
use fmt;
93+
use option::*;
94+
use rt::local::Local;
95+
use rt::logging::{Logger, StdErrLogger};
96+
use rt::task::Task;
97+
98+
/// This function is called directly by the compiler when using the logging
99+
/// macros. This function does not take into account whether the log level
100+
/// specified is active or not, it will always log something if this method is
101+
/// called.
102+
///
103+
/// It is not recommended to call this function directly, rather it should be
104+
/// invoked through the logging family of macros.
105+
pub fn log(_level: u32, args: &fmt::Arguments) {
45106
unsafe {
46107
let optional_task: Option<*mut Task> = Local::try_unsafe_borrow();
47108
match optional_task {

src/libstd/rt/logging.rs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use fmt;
1212
use from_str::from_str;
13-
use libc::{uintptr_t, exit};
13+
use libc::exit;
1414
use option::{Some, None, Option};
1515
use rt;
1616
use rt::util::dumb_println;
@@ -174,9 +174,7 @@ pub struct StdErrLogger;
174174

175175
impl Logger for StdErrLogger {
176176
fn log(&mut self, args: &fmt::Arguments) {
177-
if should_log_console() {
178-
fmt::writeln(self as &mut rt::io::Writer, args);
179-
}
177+
fmt::writeln(self as &mut rt::io::Writer, args);
180178
}
181179
}
182180

@@ -222,21 +220,6 @@ pub fn init() {
222220
}
223221
}
224222

225-
#[fixed_stack_segment] #[inline(never)]
226-
pub fn console_on() { unsafe { rust_log_console_on() } }
227-
228-
#[fixed_stack_segment] #[inline(never)]
229-
pub fn console_off() { unsafe { rust_log_console_off() } }
230-
231-
#[fixed_stack_segment] #[inline(never)]
232-
fn should_log_console() -> bool { unsafe { rust_should_log_console() != 0 } }
233-
234-
extern {
235-
fn rust_log_console_on();
236-
fn rust_log_console_off();
237-
fn rust_should_log_console() -> uintptr_t;
238-
}
239-
240223
// Tests for parse_logging_spec()
241224
#[test]
242225
fn parse_logging_spec_valid() {

src/rt/rust_builtin.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -320,27 +320,6 @@ rust_mktime(rust_tm* timeptr) {
320320
return mktime(&t);
321321
}
322322

323-
static lock_and_signal log_lock;
324-
static bool log_to_console = true;
325-
326-
extern "C" CDECL void
327-
rust_log_console_on() {
328-
scoped_lock with(log_lock);
329-
log_to_console = true;
330-
}
331-
332-
extern "C" CDECL void
333-
rust_log_console_off() {
334-
scoped_lock with(log_lock);
335-
log_to_console = false;
336-
}
337-
338-
extern "C" CDECL uintptr_t
339-
rust_should_log_console() {
340-
scoped_lock with(log_lock);
341-
return log_to_console;
342-
}
343-
344323
extern "C" lock_and_signal*
345324
rust_create_little_lock() {
346325
return new lock_and_signal();

src/rt/rustrt.def.in

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ rust_get_stderr
1717
rust_list_dir_val
1818
rust_list_dir_wfd_size
1919
rust_list_dir_wfd_fp_buf
20-
rust_log_console_on
21-
rust_log_console_off
22-
rust_should_log_console
2320
rust_unset_sigprocmask
2421
rust_env_pairs
2522
rust_win32_rand_acquire
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub fn foo<T>() {
12+
fn death() -> int { fail2!() }
13+
debug2!("{:?}", (||{ death() })());
14+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:logging_right_crate.rs
12+
// xfail-fast
13+
// exec-env:RUST_LOG=logging-right-crate=debug
14+
15+
// This is a test for issue #3046 to make sure that when we monomorphize a
16+
// function from one crate to another the right top-level logging name is
17+
// preserved.
18+
//
19+
// It used to be the case that if logging were turned on for this crate, all
20+
// monomorphized functions from other crates had logging turned on (their
21+
// logging module names were all incorrect). This test ensures that this no
22+
// longer happens by enabling logging for *this* crate and then invoking a
23+
// function in an external crate which will fail when logging is enabled.
24+
25+
extern mod logging_right_crate;
26+
27+
fn main() {
28+
// this function fails if logging is turned on
29+
logging_right_crate::foo::<int>();
30+
}

0 commit comments

Comments
 (0)