Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
abb1e24
add combinations from parser branch
ipmach Jul 27, 2026
9368328
add deep learning dependencies
ipmach Jul 27, 2026
d68081e
add deeplog
ipmach Jul 27, 2026
4baaf35
add deeplog main class
ipmach Jul 27, 2026
2c0ee34
deeplog ready in deep_learning utils
ipmach Jul 27, 2026
ff55d3a
add logbert model
ipmach Jul 27, 2026
d811a76
add logbert
ipmach Jul 27, 2026
952d177
add logbert
ipmach Jul 27, 2026
991f090
add logbert tests
ipmach Jul 27, 2026
ae4c3d7
optimize tests, only run slow tests in github action
ipmach Jul 27, 2026
642ecad
Merge branch 'development' into feat/deep_detectors
ipmach Jul 27, 2026
ee27836
mark as ignored test with sleep method
ipmach Jul 27, 2026
282d8c3
add DeepModel class
ipmach Jul 27, 2026
0feadb9
add first version deeplog and logbert detectors
ipmach Jul 27, 2026
431d0e3
minor cleaning
ipmach Jul 27, 2026
9215836
final touches
ipmach Jul 27, 2026
7794798
unittest test deep learning
ipmach Jul 27, 2026
343400f
add finetune epochs in DLDetector
ipmach Jul 28, 2026
b5e71c1
adding deeplog tests
ipmach Jul 28, 2026
b1df3a4
add tests for logbert
ipmach Jul 28, 2026
a626f89
add deeplog detector
ipmach Jul 28, 2026
81ecfd2
add logbert documentation
ipmach Jul 28, 2026
9473d9f
add end to end in deeplog
ipmach Aug 5, 2026
a34b0ec
add logbert end to end test
ipmach Aug 5, 2026
861b1bf
Fix grammatical error in deeplog documentation
ipmach Aug 5, 2026
d6d5425
Fix grammar in LogBERT description
ipmach Aug 5, 2026
9170b24
Update comments for clarity in detectors.md
ipmach Aug 5, 2026
0b443ea
Merge branch 'development' into feat/deep_detectors
viktorbeck98 Aug 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
run: uv run --dev prek run -a

- name: Test with pytest
run: uv run --dev pytest -s
run: uv run pytest -s --run-ignored

# integration tests for DetectMateService
- name: Checkout DetectMateService
Expand Down
4 changes: 4 additions & 0 deletions docs/detectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ List of detectors:
* [Rule Based](detectors/rule_based.md): Detect anomalies based in a set of rules.
* [Bigram Frequency](detectors/bigram_frequency.md): Detect bigram-frequency-based anomalies in the logs.
* [Charset](detectors/charset.md): Detect new characters in the variables in the logs.
* [Deeplog](detectors/deeplog.md): Detect anomalies of a sequence of evend IDs with a LSTM.
* [LogBert](detectors/logbert.md): Detect anomalies of a sequence of evend IDs with a Transformer.
* [SCVS Detector](detectors/scvs_detector.md): Detect anomalies by looking at different sequence count vectors.
* [ECVC Detector](detectors/ecvc_detector.md): Detect anomalies by calculating the distance between different sequence count vectors.

Expand All @@ -104,6 +106,8 @@ detectors:
NewValueDetector:
method_type: new_value_detector
auto_config: False
data_use_configure: None # Data used for configuration
data_use_training: 199 # Data used for training
params: {} # global parameters
events: # event-specific configuration
1: # event_id
Expand Down
63 changes: 63 additions & 0 deletions docs/detectors/deeplog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Deeplog Detector

The Deeplog Detector is inspired from [Deeplog paper](https://dl.acm.org/doi/10.1145/3133956.3134015).

| | Schema | Description |
|------------|----------------------------|--------------------|
| **Input** | [ParserSchema](../schemas.md) | Structured log |
| **Output** | [DetectorSchema](../schemas.md) | Combined alert / finding |

## Description
Deep learning method that looks at the event ID sequence

## Configuration

```yaml
detectors:
DeeplogDetector:
method_type: deeplog_detector
auto_config: False
data_use_training: 10
window_size: 3
hyperparameters:
Model:
hidden_dim: 64
n_layers: 2
Train:
seed: 0
batch_size: 2048
learning_rate: 0.01
epochs: 10
patience: 3
Finetune:
- ["Model", "hidden_dim", [128, 256, 512]]
- ["Model", "n_layers", [1, 2, 3]]
- ["Train", "learning_rate", [0.01, 0.02, 0.03]]
```

## Example usage

```python
from detectmatelibrary.detectors.deeplog_detector import DeeplogDetector

import detectmatelibrary.schemas as schemas

detector = DeeplogDetector(name="DeeplogDetector", config=cfg)

test_data = schemas.ParserSchema({
"parserType": "test",
"EventID": 12,
"template": "test template",
"variables": ["adsasd", "asdasd"],
"logID": "2",
"parsedLogID": "2",
"parserID": "test_parser",
"log": "test log message",
"logFormatVariables": {"level": "CRITICAL"}
})
output = schemas.DetectorSchema()

result = detector.detect(test_data, output)

```
Go back [Index](../index.md)
68 changes: 68 additions & 0 deletions docs/detectors/logbert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# LogBert Detector

The LogBert Detector is inspired from [LogBert paper](https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=9534113).

| | Schema | Description |
|------------|----------------------------|--------------------|
| **Input** | [ParserSchema](../schemas.md) | Structured log |
| **Output** | [DetectorSchema](../schemas.md) | Combined alert / finding |

## Description
Deep learning method that looks at the event ID sequence

## Configuration

```yaml
detectors:
LogBertDetector:
method_type: logbert_detector
auto_config: False
data_use_training: 10
window_size: 4
hyperparameters:
Model:
hidden: 32
num_heads: 2
n_layers: 1
dropout: 0.0
max_len: 1000
Train:
seed: 0
batch_size: 256
learning_rate: 0.01
epochs: 10
mask_per: 0.4
alpha: 0.0
patience: 3
Finetune:
- ["Model", "hidden", [64, 128, 256]]
- ["Model", "n_layers", [1, 2, 3]]
- ["Train", "learning_rate", [0.002, 0.001, 0.005]]
```

## Example usage

```python
from detectmatelibrary.detectors.logbert_detector import LogBertDetector

import detectmatelibrary.schemas as schemas

detector = LogBertDetector(name="LogBertDetector", config=cfg)

test_data = schemas.ParserSchema({
"parserType": "test",
"EventID": 12,
"template": "test template",
"variables": ["adsasd", "asdasd"],
"logID": "2",
"parsedLogID": "2",
"parserID": "test_parser",
"log": "test log message",
"logFormatVariables": {"level": "CRITICAL"}
})
output = schemas.DetectorSchema()

result = detector.detect(test_data, output)

```
Go back [Index](../index.md)
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ nav:
- BiGram Frequency: detectors/bigram_frequency.md
- CharSet: detectors/charset.md
- Value Range: detectors/value_range.md
- Deeplog Detector: detectors/deeplog.md
- LogBert Detector: detectors/logbert.md
- SCVS Detector: detectors/scvs_detector.md
- ECVC Detector: detectors/ecvc_detector.md
- Alert Aggregation Methods:
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ dependencies = [
"msgpack>=1.0.0",
"fsspec>=2024.1.0",
"pyarrow>=24.0.0",
"jax>=0.11.0",
"flax>=0.12.8",
"optax>=0.2.8",
]

[dependency-groups]
Expand Down
5 changes: 5 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[pytest]
# You can use addopts to change the default terminal behavior globally
addopts = --strict-markers
markers =
ignored: tests that should only run on demand
2 changes: 1 addition & 1 deletion src/detectmatelibrary/common/_core_op/_fit_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class FitLogicState(Enum):
def describe(self) -> str:
descriptions = [
"Configuring",
"Training.",
"Training",
"Default"
]
return descriptions[self.value]
Expand Down
90 changes: 90 additions & 0 deletions src/detectmatelibrary/common/deeplearning_detector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@

from detectmatelibrary.common.detector import CoreDetector, CoreDetectorConfig

from detectmatelibrary.utils.deep_learning.imodel import DeepModel
from detectmatelibrary.utils.data_buffer import BufferMode

from detectmatelibrary import schemas

from typing import Any


class DeepLearningDetectorConfig(CoreDetectorConfig):
window_size: int = 10
validation_per: float = 0.2
finetune_epochs: int = 2

hyperparameters: dict[str, Any] = {
"Model": {

},
"Train": {

},
"Finetune": [],
}


def build_seq(input_: list[schemas.ParserSchema]) -> tuple[int]:
return tuple([in_["EventID"] for in_ in input_])


class DeepLearningDetector(CoreDetector):
def __init__(
self,
model_cls: DeepModel,
name: str = "CoreDetector",
config: DeepLearningDetectorConfig = DeepLearningDetectorConfig()
) -> None:

if isinstance(config, dict):
config = DeepLearningDetectorConfig.from_dict(config, name)

super().__init__(
name=name,
buffer_mode=BufferMode.WINDOW,
buffer_size=config.window_size,
config=config
)
self.config: DeepLearningDetectorConfig
self.model: DeepModel = model_cls(config=self.config.hyperparameters) # type: ignore

self.train_seqs: list[tuple[int]] = []
self.config_seqs: list[tuple[int]] = []
self.stats: dict[str, float | int] = {}
self.top_k: int = 0

def train(self, input_: list[schemas.ParserSchema]) -> None: # type: ignore
self.train_seqs.append(build_seq(input_))

def configure(self, input_: list[schemas.ParserSchema]) -> None: # type: ignore
self.config_seqs.append(build_seq(input_))

def set_configuration(self) -> None:
self.model.finetune(
self.config_seqs, var_per=self.config.validation_per, epochs=self.config.finetune_epochs
)
self.config_seqs = []

def post_train(self) -> None:
self.stats = self.model.train(self.train_seqs, var_per=self.config.validation_per)
self.train_seqs = []

if "top_k" in self.stats:
self.top_k = int(self.stats["top_k"])
print(self.model)
print("Top k assigned", self.top_k)

def detect(
self,
input_: list[schemas.ParserSchema], # type: ignore
output_: schemas.DetectorSchema,
) -> bool:

alert = self.model.check_anomaly(build_seq(input_), top_k=self.top_k)
if alert:
output_["score"] = 1.0
output_["description"] = f"{self.name} found an anomaly in the sequence"
return True

return False
46 changes: 46 additions & 0 deletions src/detectmatelibrary/detectors/deeplog_detector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from detectmatelibrary.common.deeplearning_detector import (
DeepLearningDetectorConfig, DeepLearningDetector
)

from detectmatelibrary.utils.deep_learning.deeplog import DeepLog


from typing import Any


class DeeplogDetectorConfig(DeepLearningDetectorConfig):
method_type: str = "deeplog_detector"

hyperparameters: dict[str, Any] = { # type: ignore
"Model": {
"hidden_dim": 64,
"n_layers": 2,
},
"Train": {
"seed": 0,
"batch_size": 2048,
"learning_rate": 0.01,
"epochs": 10,
"patience": 3,
},
"Finetune": [
["Model", "hidden_dim", [128, 256, 512]],
["Model", "n_layers", [1, 2, 3]],
["Train", "learning_rate", [0.01, 0.02, 0.03]],
],
}


class DeeplogDetector(DeepLearningDetector):
def __init__(
self,
name: str = "DeeplogDetector",
config: DeeplogDetectorConfig | dict[str, Any] = DeeplogDetectorConfig(),
) -> None:

if isinstance(config, dict):
config = DeeplogDetectorConfig.from_dict(config, name)

super().__init__(
name=name, model_cls=DeepLog, config=config
)
52 changes: 52 additions & 0 deletions src/detectmatelibrary/detectors/logbert_detector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from detectmatelibrary.common.deeplearning_detector import (
DeepLearningDetectorConfig, DeepLearningDetector
)

from detectmatelibrary.utils.deep_learning.logbert import LogBert


from typing import Any


class LogBertDetectorConfig(DeepLearningDetectorConfig):
method_type: str = "logbert_detector"

hyperparameters: dict[str, Any] = { # type: ignore
"Model": {
"n_embed": 10,
"hidden": 32,
"num_heads": 2,
"n_layers": 1,
"dropout": 0.0,
"max_len": 1000,
},
"Train": {
"seed": 0,
"batch_size": 256,
"learning_rate": 0.01,
"epochs": 10,
"mask_per": 0.4,
"alpha": 0.0,
"patience": 3,
},
"Finetune": [
["Model", "hidden", [64, 128, 256]],
["Model", "n_layers", [1, 2, 3]],
["Train", "learning_rate", [0.002, 0.001, 0.005]],
]
}


class LogBertDetector(DeepLearningDetector):
def __init__(
self,
name: str = "LogBertDetector",
config: LogBertDetectorConfig | dict[str, Any] = LogBertDetectorConfig(),
) -> None:

if isinstance(config, dict):
config = LogBertDetectorConfig.from_dict(config, name)

super().__init__(
name=name, model_cls=LogBert, config=config
)
Loading
Loading