Lookups and tstats
Lookups
Lookups add data from a reference table to your results: a team for each user, an owner for each service, a description for each error code. Reference tables are the CSV tables under Settings → Reference Tables, the same ones log pipeline Lookup rules use (see Reference Tables). A table is named when you upload it; use that name in SPL. A Splunk-style name with .csv also works: users.csv finds the table users.
lookup
Adds a table's columns to each row whose fields match a table row.
Syntax:
lookup <table> <column> [AS <field>] [, ...] [OUTPUT | OUTPUTNEW <column> [AS <field>], ...]<column> AS <field>matches the table column against a field with another name. WithoutAS, the field has the column's name.OUTPUTlists the columns to add, and replaces fields of the same name. Without it, every other column of the table is added.OUTPUTNEWonly fills fields that are empty or that the rows do not have yet.- Matching is exact and case-sensitive. When several table rows match, the first is used. A row with no match gets empty values.
Examples:
stats count by user
| lookup users user OUTPUT team, manager
| stats sum(count) as logs by teamlevel=error
| lookup services service_name AS service OUTPUT owner AS service_owner
| table _time, service, service_owner, bodyinputlookup
Returns a table's rows. It must be the first command of a query or a subsearch.
Syntax:
inputlookup [start=<N>] [max=<N>] <table> [where <condition>]start= skips the table's first N rows and max= reads at most N rows, both before where.
Examples:
inputlookup users where team = "payments"Search the logs of the users a table lists:
search [inputlookup vip_users | fields user]
| stats count by userAccess and Limits
- Table values are text. Compare them with quoted values, or convert with
tonumber(). - A lookup reads at most 8 MiB of table data.
- Lookups read reference tables; they cannot change them.
outputlookupis not supported: edit tables under Settings → Reference Tables. - A query that uses
lookuporinputlookupneeds Log Pipeline access, the same access that shows reference tables under Settings → Reference Tables. Without it, the query fails with a message saying so. For a Query Job, the access of the user creating the job is checked when it is created, and the access of the user retrying it when it is retried. - A Query Job runs later, with no user, so its access is checked on the query as written.
lookupandinputlookupinside amaporforeachsearch, whose text comes from the data, are therefore not available in a Query Job; run that query from the Log Explorer, or move the lookup outside themaporforeach. - Reference tables are not time-based:
lookup event_time_field=is not supported.
tstats
tstats counts logs from the pre-aggregated log tables, the same ones the log dashboards read, instead of reading every log line. Over days or weeks it answers in a fraction of the time stats takes.
Syntax:
tstats <aggregation> [as <alias>] ... [where <search>] [by <field> ...] [span=<span>]Examples:
tstats count by workload
tstats count where level=error namespace=prod by service, _time span=1h
tstats count, sum(log_size_bytes) as bytes by namespace | sort -bytes
tstats dc(pod_name) as pods, values(level) as levels by workload
tstats count by pattern | sort 20 -countWhat tstats can read
The pre-aggregated tables keep a count and a size for every combination of the logs' dimension fields, so tstats works only with those:
- Fields (in
whereandby):cluster,namespace,workload,pod_name,container_name,service,level,source,format,env_type,env,instance,host/node_name,region,app_version,customer_identifier,pattern, and_timeinby. - Aggregations:
count,sum(log_size_bytes),avg(log_size_bytes),dc(<field>)andvalues(<field>).log_size_bytesis the length of the log messages. wheretakes search syntax on those fields:level=error host=web-*,OR,NOT,IN (…). Values match as typed, in lower case, in upper case or capitalized, as insearch.
Attributes, text search and other aggregations need stats, and tstats says so when a query asks for them.
pattern is the log's message template, so tstats count by pattern shows which kinds of messages are most common.
Time buckets
by _time buckets by span= (seconds to weeks, in whole multiples of 5 seconds), or, without one, by a span that gives at most 100 buckets over the time range. tstats reads the coarsest pre-aggregated table that fits the span: 5-second, 1-minute, 1-hour or 1-day.
info: Counts are kept per bucket of those tables, so the first bucket of your time range counts in full. For example, with a time range starting at 10:17, a count from the 1-hour table includes the logs from 10:00. For exact counts at the edges, use stats.
The pre-aggregated tables are kept longer than raw logs, so for older time ranges tstats can return counts after the logs themselves have expired, and its counts can then differ from stats.
tstats returns its results like stats, so prestats=true, append=true and local=true are not supported; use fillnull after it instead of fillnull_value=. Options that tune how Splunk reads its summaries (summariesonly=, allow_old_summaries=, chunk_size=) are accepted and change nothing.
tstats is a generating command: it must come first, or first in a subsearch. Anything can follow it:
tstats count by _time span=1h
| predict count future_timespan=24