The key difference to my question is the fact that request points to a nested object.
For simple fields whose values are literal values (string, boolean, int), any of the following would solve the simple case to find events where a top-level field, testField is null:
app="my_app" NOT testField="*"
app="my_app" | where isnull(testField)
However, as my original post explained, I am trying to test for all events where request is not present, where request normally pointed to an object, not a literal value.
If I query either:
app="my_app" NOT request="*"
app="my_app" | where isnull(request)
It returns all events, effectively treating an object value in request as equivalent to NULL. HOWEVER, if I query specifically on a field I know to always be non-null inside the request object, e.g. request.method , I can get what I wanted:
app="my_app" NOT request.method="*"
app="my_app" | where isnull('request.method')
NOTE THE SINGLE QUOTES in the isnull call. Inside where/eval statements, splunk does not handle complex field names, well, and requires you wrap them in SINGLE quotes.
Hopefully this answer makes sense and is helpful.
... View more