# EPF Cohort 6 – Week 15 Update
## Progress this week
The goal for this week was to enable dynamically changing the log level during runtime via an HTTP API.
The good news is that the feature is now implemented!
Through a new `POST` API endpoint, it is possible to manage the tracing log level dynamically.
**What’s possible now?**
- Accept a JSON body with target and level fields
- Apply changes immediately using the TracingHandle (without restarting the node)
- Return a JSON response confirming the update or reporting an error
Example request:
``` API
curl -X POST http://localhost:5052/eth/v2/debug/tracing/log_level \
-H "Content-Type: application/json" \
-d '{
"target": "fork_choice_control",
"level": "debug"
}'
```
<iframe width="560" height="315" src="https://www.youtube.com/embed/c8RrdKiOQno" frameborder="0" allowfullscreen></iframe>
> In this example, the log level for the `fork_choice_control` module is changed
from `info` → `debug` → back to `info` using a simple **POST** request.
---
### Technical Details
This task was a bit more challenging in Rust because the type of the `Handle` changes whenever new `.with()` directives are added to the `tracing_subscriber`.
Last week, it was easiest to just pass it around as an `impl Send + Sync`, since that hid the full underlying type.
But this week, I had to propagate the handle through the `Context` struct — and structs can’t store fields as `impl` (only concrete types).
That force carrying the full, long, ugly handle type through the program.
To keep this manageable, I wrapped it in a dedicated struct. Now, if new `.with()` directives ever change the underlying type, only the wrapper needs updating while the rest of the code stays unaffected.
``` Rust
#[derive(Clone)]
pub struct TracingHandle(
Handle<
EnvFilter,
Layered<
fmt::Layer<
tracing_subscriber::Registry,
fmt::format::DefaultFields,
fmt::format::Format<fmt::format::Compact>,
>,
tracing_subscriber::Registry,
>,
>,
);
impl TracingHandle {
pub fn modify<F>(&self, f: F) -> Result<(), reload::Error>
where
F: FnOnce(&mut EnvFilter) -> (),
{
self.0.modify(f)
}
}
```
The handle is then threaded through the application layers:
**main → runtime → HTTP API**
Implementation of this is in [PR: **Add runtime API endpoint for dynamic tracing log level control**](https://github.com/sntntn/grandine/pull/18)
## Next
The next focus is on smart instrumentation of the core logic. I’ve started with the **Validator Duties** from **validator** service, where I added tracing spans around its key functions like proposing, attesting, publishing aggregates, registering validators... (In [issue #19](https://github.com/sntntn/grandine/issues/19) )
All spans share the same name (`validator_duties`) and carry a `service = "validator"` field, which makes them easy to filter and query in tools like [**Jaeger**](https://grafana.com/docs/grafana/latest/datasources/jaeger/?utm_source=chatgpt.com).
The plan is to **wrap up this instrumentation** without diving too deep into extra research, so that tracing can make it into the next **release** as Saulius suggested. So after instrumentation I’ll move on to resolving **merge conflicts** between the current implementation and my fork, upgrading the consensus-spec-tests to the latest version, and re-running the **full test** suite.
## 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)
- [struct **Handle** - tracing subscriber](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/reload/struct.Handle.html)
- [**video example** - Runtime control of tracing log levels via API](https://www.youtube.com/watch?v=c8RrdKiOQno)
- [**PR**: Add runtime API endpoint for dynamic tracing log level control](https://github.com/sntntn/grandine/pull/18)
- [Validator Duties Instrumentation #19](https://github.com/sntntn/grandine/issues/19)
- [Jaeger](https://grafana.com/docs/grafana/latest/datasources/jaeger/?utm_source=chatgpt.com)