QueryLogObserver
Logs every failed query by who must act on it:
a rejection the caller can fix (an error-catalog violation, a missing authenticated scope) at DEBUG, by its message alone: it is the client's error, answered 4xx, and logging it louder lets callers flood the log;
a server fault the core states (QueryExecutionException) at ERROR, by its message and its cause chain with every message redacted: a cause can hold record values (a failing mask strategy sees the raw value, a storage driver echoes the query), so only each cause's class name and stack trace reach the log;
any other failure at ERROR with its stack trace.