Alert Key
The notion of a key is fundamental to alert processing. A key defines to which "entity" an alert relates. For example, a DoS alert may observe packet rate originating from IP addresses and be raised if the rate from an IP address exceeds a threshold. Here, we choose the IP address as the key for the alert. Incoming events are mapped into multiple streams. Each stream belongs to one distinct IP address, and each stream is measured individually against the rate threshold. Every stream identified by the IP address maintains its own "profile" with aggregated event history, as well as information needed for alert management: is alerting for the key throttled or suppressed?
The basic alert types have the key name configurable. For frafos telephony events, source IP address from our example can be configured as "attrs.source". Events can also be keyed by source trunk AKA Call Agent ("attrs.src_ca_id"), originating user as in From header field ("attrs.from"), or any other attribute present in incoming JSON events. Choosing "tls-cn" as key places all tenant's events into a single stream. Some attributes have synonymical shortcuts, such as "uri" for "attrs.from", empty key name stands for all tenant's events.
Each stream identified by its key name-value pair (say "attrs.source" - "10.0.0.1" here) stores its internal status for every active alert in its "profile." Our example would contain information about past packet rate measurements. It also includes some overhead information, such as when an alert was raised the last time and its throttling status. While alert processing uses the profiles internally, the profiles may also be inspected using the `getprofile` API.
Sometimes, a reference to a simple attribute in an event may generate insufficient uniqueness. You may need, for example, to raise a separate alert for each user's device. In this case, you identify the key by joining From URI representing the user and source IP representing each device. (Using only From would not differentiate the user's multiple devices, whereas using only the source IP address would treat all events from all users behind the same IP as a single stream.) Therefore, you can form a "joint key" where the key value is concatenated from multiple attribute values. You denote such joint keys by respective attribute names joined by the "+" symbol like in "attrs.from+attrs.source". The joint key value is similarly concatenated using the "+" character. For example, the joint key name could yield the value "sip:foo@bar.com+10.0.0.1".
Another particular case is when you are concerned with a key value occurring in multiple attributes. For example, you may be interested in aggregated packet rates from AND to a URI. Such a URI, like "john@doe.com" appears in "attrs.from" attribute for outgoing calls and "attrs.to" for incoming calls. Such a case requires the aggregation of processing results of the two streams into a single profile. To do so, define a "multi-key" over multiple attribute names joined together using the "|" symbol like in "attrs.from|attrs.to". As a convention, data from both streams are merged in a profile identified by the first attribute name, "attrs.from". Then alerts are processed twice, and so are the profile updated twice: once for the value of attrs.from and once for the value of attrs.to. The results are merged in the first attribute's profile.