Two Panels, Two Kinds of Invisible
A service desk dashboard has two broken panels. Panel one enriches tickets: index=itsm sourcetype=ticket | lookup asset_owners host OUTPUT owner, criticality. Only 62% of tickets get an owner. The lookup CSV holds 9,400 rows keyed on host, and manual inspection suggests about 91% of ticket hosts are present. Failures cluster in two groups: DMZ hosts, which log fully qualified (WEB07.corp.example.com) while the CSV uses short names, and a batch of hosts whose host value carries trailing spaces from a text-expanded field. Panel two is tag=critical, which returned rows until last month's app update and is now empty. The desk needs both fixed today; lookups already replicate across the search head cluster.
1. Diagnose panel one and write the corrected search.
Read the worked answer
Lookup matching is exact, whole-value, and case-sensitive. A CSV key of WEB07 does not match WEB07.corp.example.com or web07 or WEB07 - there is no implicit wildcard, and trailing whitespace is enough to break a match.
That accounts for both clusters precisely: the DMZ hosts fail on the FQDN/short-name mismatch, the second batch fails on whitespace.
Normalize both sides, not just the search:
index=itsm sourcetype=ticket
| eval host=lower(trim(host))
| eval host_short=mvindex(split(host,"."),0)
| lookup asset_owners host_short OUTPUT owner, criticality
| fillnull value="unassigned" owner
And rebuild the CSV so keys are already normalized:
| inputlookup asset_owners.csv
| eval host=lower(trim(host))
| eval host_short=mvindex(split(host,"."),0)
| fields - host | rename host_short AS host
| outputlookup asset_owners.csv
Notes:
- Normalize at ingest of the lookup, or every consumer must remember to do it. One forgotten
lower()recreates this ticket. fillnullruns after the lookup, so"unassigned"becomes a visible, countable state instead of a silent null.- CIDR-style
match_typeoptions exist for IP keys; they do not solve hostname fuzziness. Normalization is the only general fix. - Confirm the miss rate is real, not a field-name mismatch (
hostvsHost), by checking| inputlookup asset_owners.csv | head 1for exact column names.
2. Panel two went from returning rows to returning none after an app update. What distinguishes a tag problem from a data problem here, and how do you triage it?
Read the worked answer
tag=critical is a knowledge-object search, not a data search. It matches events whose field-value pair (or event type) has been tagged critical in the current app context, for a role that has permission to see it. An app update can remove any link in that chain while the underlying events are untouched.
Triage order - cheapest first:
- Prove the data is still there:
index=itsm sourcetype=ticket | stats countover the same window. If counts are normal, data is not the cause. - Test the tag definition directly: Settings → Tags, find
critical, and note which field-value pairs or event types it decorates and which app owns it. - Test the equivalent without the tag: search
index=itsm sourcetype=ticket severity=critical. If that returns rows, the tag or its scope is the problem; if it does not, the field-value the tag was built on no longer extracts - check the field in the sidebar on a known-good event. - Check app context and permissions: run the panel's search in the app that owns the tag, and confirm the role has read access. Tags created in one app are invisible elsewhere unless shared to All apps.
Common root causes: the tag was attached to an event type that the update disabled or renamed, the tag was created against a field extraction that the new props.conf no longer produces, or the tag was scoped to the app that just got a new version and lost its default context.
Fix at the knowledge-object layer (re-scope or re-tag), not by rewriting the panel to hardcode severity=critical - otherwise you have two definitions of "critical" that will drift.
3. The desk wants to also add a workflow action on `owner` that opens the asset record in a third-party tool. What must be true for it to appear?
Read the worked answer
Workflow actions are field-bound UI objects; they only render when their prerequisites are satisfied in the search results being viewed:
- The field must exist in that result set. A lookup-derived
owneronly appears if the lookup ran in that search. If some panelsfillnullit tounassigned, decide whetherunassignedshould open the tool at all - configure the action to require a non-empty, non-sentinel value. - App context and permissions matter, as with tags. The action must be shared to the app the user is searching in and be readable by their role. Actions defined in one app are invisible elsewhere by default.
- Field name must match exactly, including case, and the action is attached to a specific field - not to "whatever the table happens to show".
- Dynamic URLs must be built safely. The target URL is assembled from the field value; if values can contain spaces or special characters your
lower()/trim()normalization must also be applied, or the link will 404 for the same DMZ hosts that broke the lookup.
Verification: implement, then test with a search that returns both a matched and an unmatched host, in the app, as the target role - not as admin. Admin-visible-therefore-works is the standard way these ship broken.