edlang/tracing_subscriber/filter/trait.FilterExt.html
2024-07-26 09:42:18 +00:00

219 lines
23 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Extension trait adding combinators for combining `Filter`."><title>FilterExt in tracing_subscriber::filter - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,FiraSans-Medium-8f9a781e4970d388.woff2,SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2,SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-76eba96aa4d2e634.css"><link rel="stylesheet" href="../../static.files/rustdoc-dd39b87e5fcfba68.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="tracing_subscriber" data-themes="" data-resource-suffix="" data-rustdoc-version="1.80.0 (051478957 2024-07-21)" data-channel="1.80.0" data-search-js="search-d52510db62a78183.js" data-settings-js="settings-4313503d2e1961c2.js" ><script src="../../static.files/storage-118b08c4c78b968e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../../static.files/main-20a3ad099b048cf2.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-df360f571f6edeae.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-422f7d1d52889060.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-2c020d218678b618.svg"></head><body class="rustdoc trait"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button><a class="logo-container" href="../../tracing_subscriber/index.html"><img src="https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png" alt=""></a></nav><nav class="sidebar"><div class="sidebar-crate"><a class="logo-container" href="../../tracing_subscriber/index.html"><img src="https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png" alt="logo"></a><h2><a href="../../tracing_subscriber/index.html">tracing_subscriber</a><span class="version">0.3.18</span></h2></div><h2 class="location"><a href="#">FilterExt</a></h2><div class="sidebar-elems"><section><h3><a href="#provided-methods">Provided Methods</a></h3><ul class="block"><li><a href="#method.and">and</a></li><li><a href="#method.boxed">boxed</a></li><li><a href="#method.not">not</a></li><li><a href="#method.or">or</a></li></ul><h3><a href="#implementors">Implementors</a></h3></section><h2><a href="index.html">In tracing_subscriber::filter</a></h2></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Trait <a href="../index.html">tracing_subscriber</a>::<wbr><a href="index.html">filter</a>::<wbr><a class="trait" href="#">FilterExt</a><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><span class="out-of-band"><a class="src" href="../../src/tracing_subscriber/filter/layer_filters/mod.rs.html#167-441">source</a> · <button id="toggle-all-docs" title="collapse all docs">[<span>&#x2212;</span>]</button></span></div><pre class="rust item-decl"><code>pub trait FilterExt&lt;S&gt;: <a class="trait" href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter">Filter</a>&lt;S&gt; {
// Provided methods
fn <a href="#method.and" class="fn">and</a>&lt;B&gt;(self, other: B) -&gt; <a class="struct" href="combinator/struct.And.html" title="struct tracing_subscriber::filter::combinator::And">And</a>&lt;Self, B, S&gt;
<span class="where">where Self: <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,
B: <a class="trait" href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter">Filter</a>&lt;S&gt;</span> { ... }
<span class="item-spacer"></span> fn <a href="#method.or" class="fn">or</a>&lt;B&gt;(self, other: B) -&gt; <a class="struct" href="combinator/struct.Or.html" title="struct tracing_subscriber::filter::combinator::Or">Or</a>&lt;Self, B, S&gt;
<span class="where">where Self: <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,
B: <a class="trait" href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter">Filter</a>&lt;S&gt;</span> { ... }
<span class="item-spacer"></span> fn <a href="#method.not" class="fn">not</a>(self) -&gt; <a class="struct" href="combinator/struct.Not.html" title="struct tracing_subscriber::filter::combinator::Not">Not</a>&lt;Self, S&gt;
<span class="where">where Self: <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span> { ... }
<span class="item-spacer"></span> fn <a href="#method.boxed" class="fn">boxed</a>(self) -&gt; <a class="struct" href="https://doc.rust-lang.org/1.80.0/alloc/boxed/struct.Box.html" title="struct alloc::boxed::Box">Box</a>&lt;dyn <a class="trait" href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter">Filter</a>&lt;S&gt; + <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> + <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> + 'static&gt;
<span class="where">where Self: <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> + <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> + 'static</span> { ... }
}</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Extension trait adding <a href="combinator/index.html" title="mod tracing_subscriber::filter::combinator">combinators</a> for combining <a href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter"><code>Filter</code></a>.</p>
</div></details><h2 id="provided-methods" class="section-header">Provided Methods<a href="#provided-methods" class="anchor">§</a></h2><div class="methods"><details class="toggle method-toggle" open><summary><section id="method.and" class="method"><a class="src rightside" href="../../src/tracing_subscriber/filter/layer_filters/mod.rs.html#209-215">source</a><h4 class="code-header">fn <a href="#method.and" class="fn">and</a>&lt;B&gt;(self, other: B) -&gt; <a class="struct" href="combinator/struct.And.html" title="struct tracing_subscriber::filter::combinator::And">And</a>&lt;Self, B, S&gt;<div class="where">where
Self: <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,
B: <a class="trait" href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter">Filter</a>&lt;S&gt;,</div></h4></section></summary><div class="docblock"><p>Combines this <a href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter"><code>Filter</code></a> with another <a href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter"><code>Filter</code></a> s so that spans and
events are enabled if and only if <em>both</em> filters return <code>true</code>.</p>
<h5 id="examples"><a class="doc-anchor" href="#examples">§</a>Examples</h5>
<p>Enabling spans or events if they have both a particular target <em>and</em> are
above a certain level:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::<span class="kw-2">*</span>,
};
<span class="comment">// Enables spans and events with targets starting with `interesting_target`:
</span><span class="kw">let </span>target_filter = filter_fn(|meta| {
meta.target().starts_with(<span class="string">"interesting_target"</span>)
});
<span class="comment">// Enables spans and events with levels `INFO` and below:
</span><span class="kw">let </span>level_filter = LevelFilter::INFO;
<span class="comment">// Combine the two filters together, returning a filter that only enables
// spans and events that *both* filters will enable:
</span><span class="kw">let </span>filter = target_filter.and(level_filter);
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
<span class="comment">// This event will *not* be enabled:
</span><span class="macro">tracing::info!</span>(<span class="string">"an event with an uninteresting target"</span>);
<span class="comment">// This event *will* be enabled:
</span><span class="macro">tracing::info!</span>(target: <span class="string">"interesting_target"</span>, <span class="string">"a very interesting event"</span>);
<span class="comment">// This event will *not* be enabled:
</span><span class="macro">tracing::debug!</span>(target: <span class="string">"interesting_target"</span>, <span class="string">"interesting debug event..."</span>);</code></pre></div>
</div></details><details class="toggle method-toggle" open><summary><section id="method.or" class="method"><a class="src rightside" href="../../src/tracing_subscriber/filter/layer_filters/mod.rs.html#291-297">source</a><h4 class="code-header">fn <a href="#method.or" class="fn">or</a>&lt;B&gt;(self, other: B) -&gt; <a class="struct" href="combinator/struct.Or.html" title="struct tracing_subscriber::filter::combinator::Or">Or</a>&lt;Self, B, S&gt;<div class="where">where
Self: <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,
B: <a class="trait" href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter">Filter</a>&lt;S&gt;,</div></h4></section></summary><div class="docblock"><p>Combines two <a href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter"><code>Filter</code></a>s so that spans and events are enabled if <em>either</em> filter
returns <code>true</code>.</p>
<h5 id="examples-1"><a class="doc-anchor" href="#examples-1">§</a>Examples</h5>
<p>Enabling spans and events at the <code>INFO</code> level and above, and all spans
and events with a particular target:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::<span class="kw-2">*</span>,
};
<span class="comment">// Enables spans and events with targets starting with `interesting_target`:
</span><span class="kw">let </span>target_filter = filter_fn(|meta| {
meta.target().starts_with(<span class="string">"interesting_target"</span>)
});
<span class="comment">// Enables spans and events with levels `INFO` and below:
</span><span class="kw">let </span>level_filter = LevelFilter::INFO;
<span class="comment">// Combine the two filters together so that a span or event is enabled
// if it is at INFO or lower, or if it has a target starting with
// `interesting_target`.
</span><span class="kw">let </span>filter = level_filter.or(target_filter);
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();
<span class="comment">// This event will *not* be enabled:
</span><span class="macro">tracing::debug!</span>(<span class="string">"an uninteresting event"</span>);
<span class="comment">// This event *will* be enabled:
</span><span class="macro">tracing::info!</span>(<span class="string">"an uninteresting INFO event"</span>);
<span class="comment">// This event *will* be enabled:
</span><span class="macro">tracing::info!</span>(target: <span class="string">"interesting_target"</span>, <span class="string">"a very interesting event"</span>);
<span class="comment">// This event *will* be enabled:
</span><span class="macro">tracing::debug!</span>(target: <span class="string">"interesting_target"</span>, <span class="string">"interesting debug event..."</span>);</code></pre></div>
<p>Enabling a higher level for a particular target by using <code>or</code> in
conjunction with the <a href="trait.FilterExt.html#method.and" title="method tracing_subscriber::filter::FilterExt::and"><code>and</code></a> combinator:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::<span class="kw-2">*</span>,
};
<span class="comment">// This filter will enable spans and events with targets beginning with
// `my_crate`:
</span><span class="kw">let </span>my_crate = filter_fn(|meta| {
meta.target().starts_with(<span class="string">"my_crate"</span>)
});
<span class="kw">let </span>filter = my_crate
<span class="comment">// Combine the `my_crate` filter with a `LevelFilter` to produce a
// filter that will enable the `INFO` level and lower for spans and
// events with `my_crate` targets:
</span>.and(LevelFilter::INFO)
<span class="comment">// If a span or event *doesn't* have a target beginning with
// `my_crate`, enable it if it has the `WARN` level or lower:
</span>.or(LevelFilter::WARN);
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();</code></pre></div>
</div></details><details class="toggle method-toggle" open><summary><section id="method.not" class="method"><a class="src rightside" href="../../src/tracing_subscriber/filter/layer_filters/mod.rs.html#358-363">source</a><h4 class="code-header">fn <a href="#method.not" class="fn">not</a>(self) -&gt; <a class="struct" href="combinator/struct.Not.html" title="struct tracing_subscriber::filter::combinator::Not">Not</a>&lt;Self, S&gt;<div class="where">where
Self: <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h4></section></summary><div class="docblock"><p>Inverts <code>self</code>, returning a filter that enables spans and events only if
<code>self</code> would <em>not</em> enable them.</p>
<p>This inverts the values returned by the <a href="../layer/trait.Filter.html#tymethod.enabled" title="method tracing_subscriber::layer::Filter::enabled"><code>enabled</code></a> and <a href="../layer/trait.Filter.html#method.callsite_enabled" title="method tracing_subscriber::layer::Filter::callsite_enabled"><code>callsite_enabled</code></a>
methods on the wrapped filter; it does <em>not</em> invert <a href="../layer/trait.Filter.html#method.event_enabled" title="method tracing_subscriber::layer::Filter::event_enabled"><code>event_enabled</code></a>, as
filters which do not implement filtering on event field values will return
the default <code>true</code> even for events that their <a href="../layer/trait.Filter.html#tymethod.enabled" title="method tracing_subscriber::layer::Filter::enabled"><code>enabled</code></a> method disables.</p>
<p>Consider a normal filter defined as:</p>
<div class="example-wrap ignore"><a href="#" class="tooltip" title="This example is not tested"></a><pre class="rust rust-example-rendered"><code><span class="comment">// for spans
</span><span class="kw">match </span>callsite_enabled() {
ALWAYS =&gt; on_span(),
SOMETIMES =&gt; <span class="kw">if </span>enabled() { on_span() },
NEVER =&gt; (),
}
<span class="comment">// for events
</span><span class="kw">match </span>callsite_enabled() {
ALWAYS =&gt; on_event(),
SOMETIMES =&gt; <span class="kw">if </span>enabled() &amp;&amp; event_enabled() { on_event() },
NEVER =&gt; (),
}</code></pre></div>
<p>and an inverted filter defined as:</p>
<div class="example-wrap ignore"><a href="#" class="tooltip" title="This example is not tested"></a><pre class="rust rust-example-rendered"><code><span class="comment">// for spans
</span><span class="kw">match </span>callsite_enabled() {
ALWAYS =&gt; (),
SOMETIMES =&gt; <span class="kw">if </span>!enabled() { on_span() },
NEVER =&gt; on_span(),
}
<span class="comment">// for events
</span><span class="kw">match </span>callsite_enabled() {
ALWAYS =&gt; (),
SOMETIMES =&gt; <span class="kw">if </span>!enabled() { on_event() },
NEVER =&gt; on_event(),
}</code></pre></div>
<p>A proper inversion would do <code>!(enabled() &amp;&amp; event_enabled())</code> (or
<code>!enabled() || !event_enabled()</code>), but because of the implicit <code>&amp;&amp;</code>
relation between <code>enabled</code> and <code>event_enabled</code>, it is difficult to
short circuit and not call the wrapped <code>event_enabled</code>.</p>
<p>A combinator which remembers the result of <code>enabled</code> in order to call
<code>event_enabled</code> only when <code>enabled() == true</code> is possible, but requires
additional thread-local mutable state to support a very niche use case.</p>
</div></details><details class="toggle method-toggle" open><summary><section id="method.boxed" class="method"><a class="src rightside" href="../../src/tracing_subscriber/filter/layer_filters/mod.rs.html#435-440">source</a><h4 class="code-header">fn <a href="#method.boxed" class="fn">boxed</a>(self) -&gt; <a class="struct" href="https://doc.rust-lang.org/1.80.0/alloc/boxed/struct.Box.html" title="struct alloc::boxed::Box">Box</a>&lt;dyn <a class="trait" href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter">Filter</a>&lt;S&gt; + <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> + <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> + 'static&gt;<div class="where">where
Self: <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> + <a class="trait" href="https://doc.rust-lang.org/1.80.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> + 'static,</div></h4></section></summary><div class="docblock"><p><a href="https://doc.rust-lang.org/1.80.0/alloc/boxed/index.html" title="mod alloc::boxed">Boxes</a> <code>self</code>, erasing its concrete type.</p>
<p>This is equivalent to calling <a href="https://doc.rust-lang.org/1.80.0/alloc/boxed/struct.Box.html#method.new" title="associated function alloc::boxed::Box::new"><code>Box::new</code></a>, but in method form, so that
it can be used when chaining combinator methods.</p>
<h5 id="examples-2"><a class="doc-anchor" href="#examples-2">§</a>Examples</h5>
<p>When different combinations of filters are used conditionally, they may
have different types. For example, the following code wont compile,
since the <code>if</code> and <code>else</code> clause produce filters of different types:</p>
<div class="example-wrap compile_fail"><a href="#" class="tooltip" title="This example deliberately fails to compile"></a><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::<span class="kw-2">*</span>,
};
<span class="kw">let </span>enable_bar_target: bool = <span class="comment">// ...
</span><span class="kw">let </span>filter = <span class="kw">if </span>enable_bar_target {
filter_fn(|meta| meta.target().starts_with(<span class="string">"foo"</span>))
<span class="comment">// If `enable_bar_target` is true, add a `filter_fn` enabling
// spans and events with the target `bar`:
</span>.or(filter_fn(|meta| meta.target().starts_with(<span class="string">"bar"</span>)))
.and(LevelFilter::INFO)
} <span class="kw">else </span>{
filter_fn(|meta| meta.target().starts_with(<span class="string">"foo"</span>))
.and(LevelFilter::INFO)
};
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();</code></pre></div>
<p>By using <code>boxed</code>, the types of the two different branches can be erased,
so the assignment to the <code>filter</code> variable is valid (as both branches
have the type <code>Box&lt;dyn Filter&lt;S&gt; + Send + Sync + 'static&gt;</code>). The
following code <em>does</em> compile:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tracing_subscriber::{
filter::{filter_fn, LevelFilter, FilterExt},
prelude::<span class="kw-2">*</span>,
};
<span class="kw">let </span>enable_bar_target: bool = <span class="comment">// ...
</span><span class="kw">let </span>filter = <span class="kw">if </span>enable_bar_target {
filter_fn(|meta| meta.target().starts_with(<span class="string">"foo"</span>))
.or(filter_fn(|meta| meta.target().starts_with(<span class="string">"bar"</span>)))
.and(LevelFilter::INFO)
<span class="comment">// Boxing the filter erases its type, so both branches now
// have the same type.
</span>.boxed()
} <span class="kw">else </span>{
filter_fn(|meta| meta.target().starts_with(<span class="string">"foo"</span>))
.and(LevelFilter::INFO)
.boxed()
};
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().with_filter(filter))
.init();</code></pre></div>
</div></details></div><h2 id="implementors" class="section-header">Implementors<a href="#implementors" class="anchor">§</a></h2><div id="implementors-list"><section id="impl-FilterExt%3CS%3E-for-F" class="impl"><a class="src rightside" href="../../src/tracing_subscriber/filter/layer_filters/mod.rs.html#1026">source</a><a href="#impl-FilterExt%3CS%3E-for-F" class="anchor">§</a><h3 class="code-header">impl&lt;F, S&gt; <a class="trait" href="trait.FilterExt.html" title="trait tracing_subscriber::filter::FilterExt">FilterExt</a>&lt;S&gt; for F<div class="where">where
F: <a class="trait" href="../layer/trait.Filter.html" title="trait tracing_subscriber::layer::Filter">Filter</a>&lt;S&gt;,</div></h3></section></div><script src="../../trait.impl/tracing_subscriber/filter/layer_filters/trait.FilterExt.js" async></script></section></div></main></body></html>