# EPF Cohort 6 – Week 14 Update >Additional: create a [wiki PR](https://github.com/eth-protocol-fellows/protocol-studies/pull/460) for the **Consensus-spec-tests recommendation** mentioned in the previous update. ## Progress this week I tackled a new task: researching and implementing a way to **dynamically change the tracing log level during runtime**. --- Previously, the [tracing subscriber](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/index.html) was initialized directly with a static EnvFilter. This meant that the log levels were fixed at startup and could not be changed dynamically during program execution: ``` fmt() .with_env_filter(filter) .compact() .with_thread_ids(true) .with_target(true) .with_file(false) .with_line_number(true) .with_ansi(enable_ansi) .init(); ``` > The variable **filter** holds the initial log configuration for each specific crate, either defined through hardcoded defaults or provided via environment variables. --- While digging through the tracing-subscriber documentation, I explored two key modules: - [registry](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/registry/index.html) - provides the Registry type, which acts as the base Subscriber and allows stacking multiple layers. This is the default mechanism for storing spans and events that other layers can query. - [reload](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/reload/index.html) - provides a Layer wrapper that allows another layer or filter to be dynamically reloaded at runtime. By combining these, I was able to set up the tracing subscriber with reload layers, which means that the log level can now be changed dynamically during execution. --- Now, the initialization uses `reload::Layer`, which wraps the **filter** in a reloadable layer and returns a handle. This handle can later be used at runtime to update log directives dynamically: ``` let (filter_layer, handle) = reload::Layer::new(filter); tracing_subscriber::registry() .with(fmt::layer() .compact() .with_thread_ids(true) .with_target(true) .with_file(false) .with_line_number(true) .with_ansi(enable_ansi)) .with(filter_layer) .init(); Ok(handle) ``` > Returned **handle** allows calling **`.modify(...)`** at any point to adjust directives dynamically. I tackled this problem in [issue](https://github.com/sntntn/grandine/issues/16) ## Next Steps Next, I am working on implementing an **API** to **trigger** log level changes at runtime. Also, I considered exposing this via console commands, but since Grandine’s client often runs inside Docker, the console is not practical. Following Saulious’ suggestion, the API approach is the most suitable. ## Resources - [Grandine forked repo](https://github.com/sntntn/grandine/tree/feature/dynamic-tracing-config) - [Roadmap through phases](https://github.com/eth-protocol-fellows/cohort-six/blob/master/projects/Grandine-Implementing-Tokio-Tracing-For-Debugging-And-Performance-Analysis.md#roadmap) - [registry - tracing_subscriber](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/registry/index.html) - [reload - tracing_subscriber](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/reload/index.html)