I am implementing a DMN Feel language interpreter as part of a rules engine. The expression compiler and evaluator will be available either as a library for inline use or via a REST API, embedded in Actix Web. The Feel language suppresses errors by converting each operation failure into a null value and bubbling these nulls through the expression processing. Sometimes that null is not an error, such as handling missing data.
I want to return a log of every operation that produces a null (like division by zero, mismatch of argument types, list index out of bounds, etc) and was encountered during the execution of the entire rule. Since this might occur in an Actix Web application, multiple calls for different expressions may occur in separate threads. I do not want to have to pass a logger around.
slog logging framework has a crate called
slog_scope. Under the covers it uses
thread_local! to associate a different logger with each thread. That would seem to be ideal, except for this warning by the creator of the slog_scope library:
It is generally advised NOT to use
slog_scope in libraries.
Since I am writing a rust library, that warning would apply to my situation. What would be a sound way to implement scoped logging in Rust, such that each thread gets its own logger and I don't have to pass a logger object around?
I want to capture all the errors, grab them when I am about to exit the evaluator so I can add them to the result structure, and clear the logger on exiting the thread.