Verbosity Specifiers
Verbosity specifiers are the core mechanism for controlling which messages are emitted and at what level. They provide fine-grained control over different categories of output in your applications. These are not provided by the SciMLLogging package, but instead must be implemented by a package wishing to use the SciMLLogging interface.
Abstract Base Type
SciMLLogging.AbstractVerbositySpecifier — Type
`AbstractVerbositySpecifier`Base for types which specify which log messages are emitted at what level.
Creating Verbosity Specifiers
Package authors can define their own verbosity specifier types in two ways:
Using the @verbosity_specifier Macro (Recommended)
The @verbosity_specifier macro automatically generates a parametric struct with constructors, presets, and group support:
SciMLLogging.@verbosity_specifier — Macro
@verbosity_specifier name begin
toggles = (...)
sub_specifiers = (...) # optional
presets = (...)
groups = (...)
endGenerates a parametric struct and constructors for a verbosity specifier.
Input Format
toggles: Tuple of symbols for leaf verbosity toggles. Fields are typed as MessageLevel. Each toggle controls whether (and at what level) a category of log messages is emitted.
sub_specifiers: (optional) Tuple of symbols for fields that hold another AbstractVerbositySpecifier or AbstractVerbosityPreset (a sub-spec for some nested concern, e.g. a LinearVerbosity inside a DEVerbosity). Each declared sub-specifier becomes its own type parameter on the generated struct, so the field is concretely typed at the instance level. This preserves inference when the sub-specifier is forwarded to a downstream API (e.g. solve(...; verbose = outer.linear_verbosity)), and lets the outer-spec-defining package hold a sub-specifier type that it does not depend on at definition time (e.g. DiffEqBase holding a NonlinearVerbosity without depending on NonlinearSolve).
presets: Named tuple mapping preset names to field configurations. Each preset maps field names to message levels (for toggles) or to a preset/sub-spec instance (for sub_specifiers). Must include at least Standard. Can define custom presets beyond the standard five (None, Minimal, Standard, Detailed, All).
groups: Named tuple mapping group names to tuples of toggle symbols. Groups allow setting multiple toggles at once. Group fields must be toggles, not sub_specifiers.
Generated Code
Struct: Creates name{Enabled, S1, ..., Sk} <: AbstractVerbositySpecifier{Enabled}, where S1..Sk are the type parameters for each declared subspecifier (in order). Toggle fields are ::MessageLevel. If no `subspecifiersblock is given, the struct is justname{Enabled}`.
Constructors:
name(): Default constructor using Standard presetname(preset::AbstractVerbosityPreset): Constructor from preset (e.g.,name(Minimal()))name(; preset=nothing, groups..., kwargs...): Keyword constructor with precedence: individual > group > preset
Custom Preset Types: Generates struct definitions for non-standard presets.
Example
@verbosity_specifier SolverVerbosity begin
toggles = (:convergence, :step_rejected)
sub_specifiers = (:linear_verbosity,)
presets = (
Standard = (
convergence = InfoLevel,
step_rejected = WarnLevel,
linear_verbosity = LinearVerbosity(None()),
),
)
groups = (
solver = (:convergence, :step_rejected),
)
endManual Implementation
Alternatively, you can manually define verbosity specifier types by subtyping AbstractVerbositySpecifier{Enabled}. The Enabled type parameter lets the compiler eliminate logging branches entirely when the specifier is disabled:
using SciMLLogging
struct MyPackageVerbosity{Enabled} <: AbstractVerbositySpecifier{Enabled}
initialization::MessageLevel # Controls startup and setup messages
progress::MessageLevel # Controls progress and iteration updates
convergence::MessageLevel # Controls convergence-related messages
diagnostics::MessageLevel # Controls diagnostic messages
performance::MessageLevel # Controls performance-related messages
endNote: Concretely typing the fields as MessageLevel is recommended for performance:
- Type stability: Eliminates type instabilities that can hurt performance
- Compile-time optimization: Allows the compiler to constant-fold logging branches when the specifier is a constant
Configuring Message Categories
Each field in a verbosity specifier can be set to any MessageLevel:
# Create a custom configuration
custom_verbosity = MyPackageVerbosity(
initialization = InfoLevel, # Show startup information
progress = Silent, # Hide progress updates
convergence = InfoLevel, # Show convergence status
diagnostics = WarnLevel, # Show diagnostic messages
performance = InfoLevel # Show performance info
)Integration with Packages
Package authors should provide verbosity arguments in their main functions:
function solve_problem(problem; verbose = MyPackageVerbosity(Standard()), kwargs...)
@SciMLMessage("Starting computation", verbose, :initialization)
for i in 1:max_iterations
@SciMLMessage("Iteration $i", verbose, :progress)
# ... computation ...
if converged
@SciMLMessage("Converged after $i iterations", verbose, :convergence)
break
end
end
return result
end