ES|QL examplesedit

Aggregating and enriching windows event logsedit

FROM logs-*
| WHERE event.code IS NOT NULL
| STATS event_code_count = COUNT(event.code) BY event.code,
| ENRICH win_events ON event.code WITH event_description
| WHERE event_description IS NOT NULL and IS NOT NULL
| RENAME event_description AS event.description
| SORT event_code_count DESC
| KEEP event_code_count,event.code,,event.description
  • It starts by querying logs from indices that match the pattern "logs-*".
  • Filters events where the "event.code" field is not null.
  • Aggregates the count of events by "event.code" and ""
  • Enriches the events with additional information using the "EVENT_DESCRIPTION" field.
  • Filters out events where "EVENT_DESCRIPTION" or "" is null.
  • Renames "EVENT_DESCRIPTION" as "event.description."
  • Sorts the result by "event_code_count" in descending order.
  • Keeps only selected fields: "event_code_count," "event.code," "," and "event.description."

Summing outbound traffic from a process curl.exeedit

FROM logs-endpoint
| WHERE == "curl.exe"
| STATS bytes = SUM(destination.bytes) BY destination.address
| EVAL kb =  bytes/1024
| LIMIT 10
| KEEP kb,destination.address
  • Queries logs from the "logs-endpoint" source.
  • Filters events where the "" field is "curl.exe."
  • Calculates the sum of bytes sent to destination addresses and converts it to kilobytes (KB).
  • Sorts the results by "kb" (kilobytes) in descending order.
  • Limits the output to the top 10 results.
  • Keeps only the "kb" and "destination.address" fields.

Manipulating DNS logs to find a high number of unique dns queries per registered domainedit

FROM logs-*
| GROK "%{DATA}\\.%{GREEDYDATA:dns.question.registered_domain:string}"
| STATS unique_queries = COUNT_DISTINCT( BY dns.question.registered_domain,
| WHERE unique_queries > 10
| SORT unique_queries DESC
| RENAME unique_queries AS `Unique Queries`, dns.question.registered_domain AS `Registered Domain`, AS `Process`
  • Queries logs from indices matching "logs-*."
  • Uses the "grok" pattern to extract the registered domain from the "" field.
  • Calculates the count of unique DNS queries per registered domain and process name.
  • Filters results where "unique_queries" are greater than 10.
  • Sorts the results by "unique_queries" in descending order.
  • Renames fields for clarity: "unique_queries" to "Unique Queries," "dns.question.registered_domain" to "Registered Domain," and "" to "Process."

Identifying high-numbers of outbound user connectionsedit

FROM logs-*
| WHERE NOT CIDR_MATCH(destination.ip, "", "", "")
| STATS destcount = COUNT(destination.ip) BY,
| ENRICH ldap_lookup_new ON
| EVAL follow_up = CASE(destcount >= 100, "true","false")
| SORT destcount DESC
| KEEP destcount,,,, follow_up
  • Queries logs from indices matching "logs-*."
  • Filters out events where the destination IP address falls within private IP address ranges (e.g.,,,
  • Calculates the count of unique destination IPs by "" and ""
  • Enriches the "" field with LDAP group information.
  • Filters out results where "" is not null.
  • Uses a "CASE" statement to create a "follow_up" field, setting it to "true" when "destcount" is greater than or equal to 100 and "false" otherwise.
  • Sorts the results by "destcount" in descending order.
  • Keeps selected fields: "destcount," "," "," "," and "follow_up."