## Motivation:
The upgrade from Rust 1.36.0 to Rust 1.37.0 introduced a regression in
`tracing-log` on macOS, where callsite identifiers for generated `log`
callsites that were previously considered equal are no longer equal.
## Solution:
Previously, the generated callsite was represented as a zero-sized
struct with no fields:
```rust
struct Callsite;
```
The metadata for the generated callsite was constructed by invoking the
`identifiy_callsite!` macro with `&Callsite`, like this:
```rust
field::FieldSet::new(FIELD_NAMES, identify_callsite!(&Callsite)),
```
and the block generated by the macro ended with `&Callsite`, which would
be assigned to a static.
Previously, this resulted with the callsite identifier and the static
being pointers to the _same_ address, and everything worked correctly.
However, the compiler behaviour appears to have changed in Rust
1.37.0, and two &-references to the same zero-sized struct are, at least
on macOS, no longer pointers to the same memory address.
This commit fixes the regression by changing the `log_cs!` macro to
create a `static` and assign the zero-sized struct to it, like this:
```rust
static CALLSITE: Callsite = Callsite;
```
and use references to the _static_ rather than to the type constructor.
Now, references to `&CALLSITE` point to the same memory address, even on
macOS.
I've also made some minor tweaks to the tests that caught this to make
debugging future log callsite bugs easier. Now, rather than one test
function that tests all log levels, we create a separate test for each
level, to make it easier to determine whether there's a bug for all log
callsites or only a particular one. Also, I've added more information
to the assertion failure messages in these tests.
## Notes:
This may have been our fault. I'm not sure if the behaviour of
references to a new instance of a zero-sized struct (i.e. `&Callsite`)
were ever _guaranteed_ to point to the same memory location or not, so
it may be totally fine of the compiler to change this on us without
warning. However, if this is guaranteed, this is a compiler bug.
I think that by switching to using a static, however, we are making the
guarantee more explicit in either case: if the compiler were ever to
compile two references to the same static as references to different
addresses, that would be a violation of the guarantees of the `static`
keyword. Note that [The Rust Reference][1] states that:
> All references to the static refer to the same memory location.
[1]: https://doc.rust-lang.org/reference/items/static-items.html#static-items
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This PR prepares the `tracing-log` crate to publish an alpha release to
crates.io.
I realised this was necessary as I wanted to publish a new alpha of
`tracing-fmt`, and that crate now depends on `tracing-log`.
I've also done some cleanup & added some documentation.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* log: improve documentation/readme
* log: cleanup, fix warnings/edition idioms
* log: prepare to release 0.0.1-alpha.1
* fix unclear wording
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
## Motivation
Currently, the `tracing-log` crate represents `log` metadata as fields
on the `tracing` events it emits, rather than as `tracing` metadata.
This results in inconsistent formatting for `tracing` events versus
events generated from `log` records.
`tracing-fmt` should format the `log.module`, `log.target`, `log.file`,
and `log.line` fields the way it formats the same metadata on `tracing`
events. The output will look nicer this way.
## Solution
This branch introduces a new `NormalizeMetadata` extension trait to
`tracing-log`, which is implemented for `Event`s. When an `Event` has
fields indicating log metadata, its `normalized_metadata` method will
return a new `Metadata` with the metadata from the `log` crate
populated.
`tracing-fmt` has been updated to use this trait when support for
`tracing-log` is enabled.
Signed-off-by: Alexis Mousset <contact@amousset.me>
## Motivation
People writing libraries using tracing may wish to expose regular `log`
support via the `tracing/log` feature. At the same time, to get tracing
support for crates using `log`, users may turn to
`tracing_log::LogTracer`. Enabling both means logging events twice.
## Solution
This branch adds a `Builder` to the `tracing_log::LogTracer` type, which
allows configuring the `LogTracer` to ignore log records with targets
beginning with a certain string. This can be used to ignore any crates
which are emitting log records via the `tracing/log` feature.
Ideally, we would provide a way to do this automatically, without
requiring configuration, but that'll take some thinking. The ability to
ignore certain sets of log records may be valuable even if we have an
automatic method for crates to signal that they are using the
`tracing/log` feature in the future.
I've also moved the `LogTracer` and `TraceLogger` types in `tracing-log`
out of `lib.rs` into their own modules, since the main lib file was
getting a bit lengthy.
Refs: #204
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This branch makes a few small README and Cargo.toml changes:
* Add Azure Pipelines build status badges to Cargo.tomls
* Change README build status badges to Azure Pipelines
* Add "maintenance: experimental" badges to unreleased crates
* Link to `tracing` docs and crates.io page in the root README,
rather than `tracing-core`.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
## Motivation
As we started discussing in #197, setting up level filter for log is a
bit complicated, and currently has to be done twice (not counting
optional filtering in subscriber):
* Once in `log` with `log::set_max_level`
* Once in `tracing_log` with `LogTracer::with_filter`
Both use `log::LevelFilter` and have exactly the same behavior (but a
different default level).
## Solution
This PR removes the filter in `LogTracer`, and adds a function to allow
easily setting up a logger and a filter directly from `tracing_log`.
The equivalent in the `env_logger` crate are:
```rust
pub fn try_init() -> Result<(), SetLoggerError> {
try_init_from_env(Env::default())
}
pub fn init() {
try_init().expect("env_logger::init should not be called after logger initialized");
}
```
Co-Authored-By: Eliza Weisman <eliza@buoyant.io>
## Motivation
The metadata produced for logs by `as_trace` (used for filtering), when
using `tracing-log`, have inverted file and module path fields:
```
Metadata { name: "log record", target: "tokio_reactor", level: Level(Trace),
module_path: "/.../.cargo/registry/src/github.com-.../tokio-reactor-0.1.9/src/lib.rs",
location: tokio_reactor:390, [...] }
```
## Solution
It is fixed by passing them in the right order in the `Metadata` constructor.
## Motivation
`tracing-core` 0.1.2 deprecated the `Subscriber::drop_span` function in
favour of `try_close`.
## Solution
This branch updates all other crates to depend on core 0.1.2, and
replaces uses of `drop_span` with `try_close`.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
## Motivation
It would be nice if `Event`s created by `tracing-log` (which are derived
from `log::Record`) include the additional metadata that `log` includes:
target, module, file, and line information. This can be used by
subscribers to print this metadata to make the events look more like
tracing events.
In fact, the static `Callsite` in `tracing-log` includes those as
fields, so I hoped this was the intended behaviour.
## Solution
This follows the same patterns as existed for adding values to the
`ValueSet` included with a dispatched event.
## Motivation
#122 updated all crates to use Rust 2018 syntax, but I neglected to add
`edition = "2018"` to the `Cargo.toml`s.
## Solution
This fixes that.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Revert "update crates to depend on core from crates.io (#113)" and let tracing-core use tracing from crates.io
This reverts commit 1c6b4388d49aa3202ae39fd396500677cb3c5730.
This branch updates `tracing`, `tracing-fmt`, and `tracing-log`
to depend on `tracing-core` 0.1 from crates.io.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
## Motivation
Currently, the `span::Attributes` type in `tokio-trace-core` contains a
reference to `Metadata` with a generic lifetime `'a`. This means that if
a `Subscriber` wishes to store span metadata, it cannot simply store a
`&'static Metadata<'static>`. Instead, it must extract the individual
components from the metadata and store them in its own structure. In
addition, while the `name` and `FieldSet` in a `Metadata` are always
`'static`, the target and file path are not. If the `Subscriber` needs
to store those values, they must be cloned into a `String` on the heap.
This is somewhat unergonomic for subscriber implementors, in comparison
to being able to use a `&'static Metadata<'static>` reference. In
addition, it implies additional overhead when using certain parts of a
span's metadata.
## Solution
This branch changes the `Metadata` fields in `Event` and `Attributes` to
be `'static`, and `Subscriber::register_callsite` to take an
`&'static Metadata<'static>`. Unlike PR #108, this branch leaves
`Metadata` generic over a lifetime, and `Subscriber::enabled` takes an
`&'a Metadata<'a>`.
Since subscribers are provided all span metadata as a static reference
in both `register_callsite` and `new_span`, they can clone _those_
static references, but `Subscriber::enabled` can still be called with
`Metadata` constructed from a `log::Record`. This means that log records
can still be filtered as normal. A different callsite, which does not
have metadata from the log record, is used when actually recording
events constructed from `log::Records`; in a follow-up, we can propagate
the log metadata as fields there.
Closes#78Closes#108
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
## Motivation
PR #106 broke some APIs that the nursery crates `tracing-fmt` and
`tracing-log` depended on. At the time, we didn't catch this, as those
crates still depended on `tokio-trace`/`tokio-trace-core` from
crates.io. However, after merging #101, which updated those crates to
use path dependencies on `tracing`/`tracing-core`, those crates broke.
## Solution
This branch updates `tracing-fmt` and `tracing-log` to compile with the
changed APIs. `tracing-log` was also changed to depend on `tracing-core`
rather than `tracing`, as only the `core API is required by that crate,
and the `identify_callsite!` macro is not publically re-exported by
`tracing`.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This branch updates the "nursery" crates to depend on `tracing` and
`tracing-core` as path dependencies, rather than depending on the
crates.io releases of `tokio-trace` and `tokio-trace-core`. When
`tracing` and `tracing-core` are released, we will change these from
path dependencies to crates.io dependencies.
This branch also updates those crates to track API changes in `tracing`
and `tracing-core`.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
See #95
This branch renames everything from `tokio-trace` to `tracing`.
Unlike PR #98, the nursery crates still depend on the crates.io
versions of `tokio-trace` and `tokio-trace-core`, but renamed
to `tracing`/`tracing-core` in `Cargo.toml`. We can update the
nursery crates to depend on local path dependencies in a
subsequent PR, as that will require making code changes to the
nursery crates.
This branch _also_ updates the minimum Rust version to 1.34.0,
to the shock and horror of the millions of `tracing` users still
on Rust 1.26.0. This was necessary in order to allow renaming
crates in `Cargo.toml`, and to resolve that not using the `dyn`
keyword is now a warning on nightly.
Closes#98Closes#95
Signed-off-by: Eliza Weisman <eliza@buoyant.io>