Skip to main content
Solved

Ingestion time vs MTTD: avg() works in search but not in detection rules

  • January 14, 2026
  • 1 reply
  • 45 views

PanosMtln
Forum|alt.badge.img+4

Hello Community,


I successfully calculated average ingestion time using a SIEM search by comparing metadata.ingested_timestamp and metadata.event_timestamp, and aggregation functions like avg(), min(), and max() worked as expected.
 

metadata.ingested_timestamp.seconds > metadata.event_timestamp.seconds //excluding logs that have not Time in UTC
metadata.log_type = "OFFICE_365"
$Timestamps = timestamp.get_timestamp(metadata.event_timestamp.seconds, "DATE")

match:
$Timestamps,metadata.log_type, metadata.event_type, principal.namespace // we can add or remove fields here to make it more specific or broad

outcome:
$eventsCount = count(metadata.id)
$avg_delay_minutes = avg((metadata.ingested_timestamp.seconds - metadata.event_timestamp.seconds) / 60)
$max_delay_minutes = max((metadata.ingested_timestamp.seconds - metadata.event_timestamp.seconds) / 60)
$min_delay_minutes = min((metadata.ingested_timestamp.seconds - metadata.event_timestamp.seconds) / 60)
$bool = if($avg_delay_minutes > 15, 1, 0) //optional control

However, when I try to calculate MTTD using detection-level fields that are only available in the rule-writing context (for example detection.created_time and detection.time_window.start_time), I run into an issue.

Specifically, min() and max() are accepted, but avg() is not recognized when used on detection.* fields inside the rule outcome. The same function works correctly in  SIEM searches, but fails in this context.
 

rule MTTD {

meta:
author = ""

events:
$Rule_Name = $d.detection.detection.rule_name
$Rule_Name = /AnyRuleName/
$CreatedTime = timestamp.get_timestamp($d.detection.created_time.seconds, "SECOND")
$WStartTime = timestamp.get_timestamp($d.detection.time_window.start_time.seconds, "SECOND")
$WEndTime = timestamp.get_timestamp($d.detection.time_window.end_time.seconds, "SECOND")
match:
$Rule_Name over 1h //, $CreatedTime, $Timing_details, $WStartTime, $WEndTime
outcome:

$max_delay_minutes = max(($d.detection.created_time.seconds - $d.detection.time_window.start_time.seconds) / 60)
$min_delay_minutes = min(($d.detection.created_time.seconds - $d.detection.time_window.start_time.seconds) / 60)
$avg2_delay_minutes = avg(($d.detection.created_time.seconds - $d.detection.time_window.start_time.seconds) / 60)

condition:
$d
}

I am also not confident that detection.time_window.start_time.* is the most appropriate field to subtract from detection.created_time.* when calculating MTTD, so any guidance on the correct fields to use would be welcome.


Is this a known limitation of Chronicle rules ?
If so, what is the recommended approach for calculating MTTD in Chronicle?
should this be done outside the YARA engine (for example via exports or dashboards), or is there a supported workaround within rules/search?

Any guidance would be appreciated.

Best answer by jstoner

You’ve encountered one of the thing that we are needing to smooth out as we bring rules, search and dashboards together.

 

The first bit around the rule not recognizing avg. Use window.avg as the function https://docs.cloud.google.com/chronicle/docs/yara-l/functions#windowavg When we added average and standard deviation initially to search, we had search specific functions. We have since been enhancing our function game and a full list of supported functions can be found here https://docs.cloud.google.com/chronicle/docs/yara-l/functions 

 

This is the search specific information for reference as well: https://docs.cloud.google.com/chronicle/docs/investigation/statistics-aggregations-in-udm-search

 

I will mention that you can build a search that references the detection data set within a dashboard query. We are working to get that same functionality into search so you don’t have to go somewhere else but if you would rather do this data exploration somewhere other than rules, a dashboard query is another tool available. The caveat is that it needs to be a statistical search of some sort.

 

I am going to use a curated detection O365 Add Mailbox Delegate Permission as an example to address the time window question. As I look at my instance, I have a detection for this with the following values:

detection.created_time - 2025-12-17T08:21:38.923

detection.time_window.start_time - 2025-12-16T23:12:00.000

detection.time_window.end_time - 2025-12-17T07:12:00.000

detection.detection_time - 2025-12-17T07:12:00.000

This rule has a match window of 8 hours on it which is consistent with the start/end time having an 8 hour difference between them. The detection_time is the value that will appear in the detections view under timestamp. In this case, notice that there is about an our lag between the detection_time and the created_time in my example. I will also mention that my O365 data was also 549 minutes delayed. 

 

So, start/end time are the match window interval and using that probably isn’t a tool to measure MTTD since a match window has to close before the detection can be triggered. So, if you have a rule with a match window of 48 hours, you are immediately baking in that amount of time for the detection to trigger. Perhaps looking at the detection time and the creation time is a better approach of using the start time but also the end time to understand that range would be helpful.

 

Hope some of this helps.

1 reply

jstoner
Staff
Forum|alt.badge.img+23
  • Staff
  • Answer
  • January 14, 2026

You’ve encountered one of the thing that we are needing to smooth out as we bring rules, search and dashboards together.

 

The first bit around the rule not recognizing avg. Use window.avg as the function https://docs.cloud.google.com/chronicle/docs/yara-l/functions#windowavg When we added average and standard deviation initially to search, we had search specific functions. We have since been enhancing our function game and a full list of supported functions can be found here https://docs.cloud.google.com/chronicle/docs/yara-l/functions 

 

This is the search specific information for reference as well: https://docs.cloud.google.com/chronicle/docs/investigation/statistics-aggregations-in-udm-search

 

I will mention that you can build a search that references the detection data set within a dashboard query. We are working to get that same functionality into search so you don’t have to go somewhere else but if you would rather do this data exploration somewhere other than rules, a dashboard query is another tool available. The caveat is that it needs to be a statistical search of some sort.

 

I am going to use a curated detection O365 Add Mailbox Delegate Permission as an example to address the time window question. As I look at my instance, I have a detection for this with the following values:

detection.created_time - 2025-12-17T08:21:38.923

detection.time_window.start_time - 2025-12-16T23:12:00.000

detection.time_window.end_time - 2025-12-17T07:12:00.000

detection.detection_time - 2025-12-17T07:12:00.000

This rule has a match window of 8 hours on it which is consistent with the start/end time having an 8 hour difference between them. The detection_time is the value that will appear in the detections view under timestamp. In this case, notice that there is about an our lag between the detection_time and the created_time in my example. I will also mention that my O365 data was also 549 minutes delayed. 

 

So, start/end time are the match window interval and using that probably isn’t a tool to measure MTTD since a match window has to close before the detection can be triggered. So, if you have a rule with a match window of 48 hours, you are immediately baking in that amount of time for the detection to trigger. Perhaps looking at the detection time and the creation time is a better approach of using the start time but also the end time to understand that range would be helpful.

 

Hope some of this helps.