Skip to content

Commit

Permalink
add processing warning tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ekneg54 committed Aug 16, 2024
1 parent ce7d1e5 commit 9404ade
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 6 deletions.
3 changes: 3 additions & 0 deletions logprep/abc/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,9 @@ def _handle_warning_error(self, event, rule, error, failure_tags=None):
else:
add_and_overwrite(event, "tags", sorted(list({*tags, *failure_tags})))
if isinstance(error, ProcessingWarning):
if error.tags:
tags = tags if tags else []
add_and_overwrite(event, "tags", sorted(list({*error.tags, *tags, *failure_tags})))
self.result.warnings.append(error)
else:
self.result.warnings.append(ProcessingWarning(str(error), rule, event))
Expand Down
3 changes: 2 additions & 1 deletion logprep/processor/base/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ def __init__(self, message: str, rule: "Rule", event: dict):
class ProcessingWarning(Warning):
"""A warning occurred - log the warning, but continue processing the event."""

def __init__(self, message: str, rule: "Rule", event: dict):
def __init__(self, message: str, rule: "Rule", event: dict, tags: List[str] = None):
self.tags = tags if tags else []
rule.metrics.number_of_warnings += 1
message = f"{message}, {rule.id=}, {rule.description=}, {event=}"
super().__init__(f"{self.__class__.__name__}: {message}")
Expand Down
17 changes: 12 additions & 5 deletions logprep/processor/pre_detector/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,19 @@ def normalize_timestamp(self, rule: PreDetectorRule, timestamp: str) -> str:
parsed_datetime = TimeParser.parse_datetime(
timestamp, rule.source_format, rule.source_timezone
)
except TimeParserException:
self.result.warnings.append(
ProcessingWarning(str("Could not parse timestamp"), rule, self.result.event)
return (
parsed_datetime.astimezone(rule.target_timezone).isoformat().replace("+00:00", "Z")
)

return parsed_datetime.astimezone(rule.target_timezone).isoformat().replace("+00:00", "Z")
except TimeParserException as error:
error_message = "Could not parse timestamp"
raise (
ProcessingWarning(
error_message,
rule,
self.result.event,
tags=["_pre_detector_timeparsing_failure"],
)
) from error

def _apply_rules(self, event: dict, rule: PreDetectorRule):
if not (
Expand Down
4 changes: 4 additions & 0 deletions logprep/processor/pre_detector/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ class PreDetectorRule(Rule):
"source_timezone",
"target_timezone",
"timestamp_field",
"failure_tags",
}

@define(kw_only=True)
Expand Down Expand Up @@ -182,6 +183,9 @@ class Config(Rule.Config): # pylint: disable=too-many-instance-attributes
validator=[validators.instance_of(ZoneInfo)], converter=ZoneInfo, default="UTC"
)
""" timezone for target_field defaults to :code:`UTC`"""
failure_tags: list = field(
validator=validators.instance_of(list), default=["pre_detector_failure"]
)

def __eq__(self, other: "PreDetectorRule") -> bool:
return all(
Expand Down
26 changes: 26 additions & 0 deletions tests/unit/processor/pre_detector/test_pre_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,29 @@ def test_custom_timestamp_field_can_be_used(self):
assert (
detection_results.data[0][0].get("@timestamp") is None
), "should not be in detection data"

def test_appends_processing_warning_if_timestamp_could_not_be_parsed(self):
rule = {
"filter": "*",
"pre_detector": {
"id": "ac1f47e4-9f6f-4cd4-8738-795df8bd5d4f",
"title": "RULE_ONE",
"severity": "critical",
"mitre": ["attack.test1", "attack.test2"],
"case_condition": "directly",
},
"description": "Test rule one",
}
document = {
"@timestamp": "this is not a timestamp",
}
self._load_specific_rule(rule)
detection_results = self.object.process(document)
assert detection_results.warnings
assert len(detection_results.warnings) == 1
assert "Could not parse timestamp" in str(detection_results.warnings[0])
assert document, "should not be cleared"
assert document.get("@timestamp") == "this is not a timestamp", "should not be modified"
assert "tags" in document
assert "_pre_detector_failure" in document["tags"]
assert "_pre_detector_timeparsing_failure" in document["tags"]

0 comments on commit 9404ade

Please sign in to comment.