GitHub - SchwarzIT/hypermatch: hypermatch is a high-performance ⚡ Go library designed for rapid matching of a large number of rules to events. It processes thousands of events per second 🚀 against extensive rule sets in-memory with minimal latency ⏱️. (original) (raw)

SIT CI Coverage Status Go Report Card Go Reference License GitHub go.mod Go version Mentioned in Awesome Go

hypermatch logo

Introduction

Hypermatch is a high-performance Go library that enables rapid matching of a large number of rules against events. Designed for speed and efficiency, hypermatch handles thousands of events per second with low latency, making it ideal for real-time systems.

An event consists of a list of fields, provided as name/value pairs. A rule links these event fields to patterns that determine whether the event matches.

example

Quick Start

import ( hypermatch "github.com/SchwarzIT/hypermatch" )

func main() { //Initialize hypermatch hm := hypermatch.NewHyperMatch()

//Add a rule
if err := hm.AddRule("markus_rule", hypermatch.ConditionSet{
    hypermatch.Condition{Path: "firstname", Pattern: hypermatch.Pattern{Type: hypermatch.PatternEquals, Value: "markus"}},
    hypermatch.Condition{Path: "lastname", Pattern: hypermatch.Pattern{Type: hypermatch.PatternEquals, Value: "troßbach"}},
    }); err != nil {
        panic(err)
}

//Test with match
matchedRules := hm.Match([]hypermatch.Property{
    {Path: "firstname", Values: []string{"markus"}},
    {Path: "lastname", Values: []string{"troßbach"}},
})
log.Printf("Following rules matches: %v", matchedRules)

//Test without match
matchedRules = hm.Match([]hypermatch.Property{
    {Path: "firstname", Values: []string{"john"}},
    {Path: "lastname", Values: []string{"doe"}},
})
log.Printf("Following rules matches: %v", matchedRules)

}

Documentation

Example Event

An event is represented as a JSON object with various fields. Here’s a sample event:

{ "name": "Too many parallel requests on system xy", "severity": "critical", "status": "firing", "message": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.", "team": "awesome-team", "application": "webshop", "component": "backend-service", "tags": [ "shop", "backend" ]
}

This example will be referenced throughout the documentation.

Matching Basics

Rules in Hypermatch are composed of conditions defined by the ConditionSet type.

Each condition includes:

Here’s an example rule that matches the event above:

ConditionSet{ { Path: "status", Pattern: Pattern{Type: PatternEquals, Value: "firing"}, }, { Path: "name", Pattern: Pattern{Type: PatternAnythingBut, Sub: []Pattern{ {Type: PatternWildcard, Value: "TEST*"}, }, }, }, { Path: "severity", Pattern: Pattern{ Type: PatternAnyOf, Sub: []Pattern{ {Type: PatternEquals, Value: "critical"}, {Type: PatternEquals, Value: "warning"}, }, }, }, { Path: "tags", Pattern: Pattern{ Type: PatternAllOf, Sub: []Pattern{ {Type: PatternEquals, Value: "shop"}, {Type: PatternEquals, Value: "backend"}, }, }, }, }

The rules and conditions are also expressible as JSON objects. The following JSON is the equivalent of the above Go notation for a ConditionSet:

{ "status": { "equals": "firing" }, "name": { "anythingBut": [ {"wildcard": "TEST*"} ] }, "severity": { "anyOf": [ {"equals": "critical"}, {"equals": "warning"} ] }, "tags": { "allOf": [ {"equals": "shop"}, {"equals": "backend"} ] } }

Note: For simplicity, all examples in this documentation will be presented in JSON format.

Matching syntax

"equals" matching

The equals condition checks if an attribute of the event matches a specified value, case-insensitively.

{ "status": { "equals": "firing" } }

If the attribute value is type of:

"prefix" matching

The prefix condition checks if an attribute starts with a specified prefix, case-insensitively.

{ "status": { "prefix": "fir" } }

If the attribute value is type of:

"suffix" matching

The suffix condition checks if an attribute ends with a specified suffix, case-insensitively.

{ "status": { "suffix": "ing" } }

If the attribute value is type of:

"wildcard" matching

The wildcard condition uses wildcards to match the value of an attribute, ignoring case.

{ "name": { "wildcard": "parallel requests" } }

If the attribute value is type of:

"anythingBut" matching

The anythingBut condition negates the match, triggering only if the specified condition is not met.

{ "status": { "anythingBut": [ {"equals": "firing"} ] } }

If the attribute value is type of:

"anyOf" matching

anyOf does correspond to a boolean "inclusive-or". It checks multiple conditions and matches if any of the conditions are true.

{ "status": { "anyOf": [ {"equals": "firing"}, {"equals": "resolved"} ] } }

If the attribute value is type of:

"allOf" matching

allOf does correspond to a boolean "and". It checks multiple conditions and matches if all the conditions are true.

{ "tags": { "allOf": [ {"equals": "shop"}, {"equals": "backend"} ] } }

If the attribute value is type of:

Performance

hypermatch is designed to be blazing fast with very large numbers of rules. Nevertheless, there are a few things to consider to get maximum performance: