Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions assets/parser_fixture_matrix_journalctl_short_full.log
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Tue 2026-03-10 09:03:39 UTC example-host sshd[3020]: maximum authentication atte
Tue 2026-03-10 09:03:39 UTC example-host sshd[3021]: Failed password for illegal user legacy-admin from 203.0.113.48 port 52017 ssh2
Tue 2026-03-10 09:03:39 UTC example-host sshd[3022]: Illegal user legacy-backup from 203.0.113.49 port 52018
Tue 2026-03-10 09:03:39 UTC example-host sshd[3025]: Failed none for invalid user svc-none from 203.0.113.59 port 52021 ssh2
Tue 2026-03-10 09:03:39 UTC example-host sshd[3026]: Failed none for illegal user legacy-none from 203.0.113.60 port 52022 ssh2
Tue 2026-03-10 09:03:40 UTC example-host sshd[3003]: Connection closed by user alice 203.0.113.50 port 52010 [preauth]
Tue 2026-03-10 09:04:05 UTC example-host sshd[3004]: Connection closed by authenticating user carol 203.0.113.51 port 52011 [preauth]
Tue 2026-03-10 09:04:28 UTC example-host sshd[3005]: Connection closed by invalid user deploy 203.0.113.52 port 52012 [preauth]
Expand Down
1 change: 1 addition & 0 deletions assets/parser_fixture_matrix_syslog.log
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Mar 10 09:03:39 example-host sshd[2020]: maximum authentication attempts exceede
Mar 10 09:03:39 example-host sshd[2021]: Failed password for illegal user legacy-admin from 203.0.113.48 port 52017 ssh2
Mar 10 09:03:39 example-host sshd[2022]: Illegal user legacy-backup from 203.0.113.49 port 52018
Mar 10 09:03:39 example-host sshd[2025]: Failed none for invalid user svc-none from 203.0.113.59 port 52021 ssh2
Mar 10 09:03:39 example-host sshd[2026]: Failed none for illegal user legacy-none from 203.0.113.60 port 52022 ssh2
Mar 10 09:03:40 example-host sshd[2003]: Connection closed by user alice 203.0.113.50 port 52010 [preauth]
Mar 10 09:04:05 example-host sshd[2004]: Connection closed by authenticating user carol 203.0.113.51 port 52011 [preauth]
Mar 10 09:04:28 example-host sshd[2005]: Connection closed by invalid user deploy 203.0.113.52 port 52012 [preauth]
Expand Down
40 changes: 30 additions & 10 deletions tests/test_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ void test_failed_none_invalid_user_is_normalized_as_invalid_user() {
"expected failed-none invalid-user to normalize to invalid-user type");
}

void test_failed_none_illegal_user_is_normalized_as_invalid_user() {
const auto parser = make_syslog_parser();
const auto event = parser.parse_line(
"Mar 10 08:11:27 example-host sshd[1239]: Failed none for illegal user legacy-none from 203.0.113.15 port 51027 ssh2",
1);

expect(event.has_value(), "expected failed-none illegal-user event");
expect(event->username == "legacy-none", "expected failed-none illegal username");
expect(event->source_ip == "203.0.113.15", "expected failed-none illegal source ip");
expect(event->event_type == loglens::EventType::SshInvalidUser,
"expected failed-none illegal-user to normalize to invalid-user type");
}

void test_failed_none_without_invalid_user_stays_unsupported() {
const auto parser = make_syslog_parser();
std::string error;
Expand Down Expand Up @@ -736,12 +749,12 @@ void test_syslog_fixture_matrix_file() {
const auto parser = make_syslog_parser();
const auto result = parser.parse_file(asset_path("parser_fixture_matrix_syslog.log"));

expect(result.events.size() == 21, "expected twenty-one recognized syslog fixture events");
expect(result.events.size() == 22, "expected twenty-two recognized syslog fixture events");
expect(result.warnings.size() == 9, "expected nine syslog fixture warnings");
expect(result.quality.total_lines == 30, "expected thirty syslog fixture lines");
expect(result.quality.parsed_lines == 21, "expected twenty-one parsed syslog fixture lines");
expect(result.quality.total_lines == 31, "expected thirty-one syslog fixture lines");
expect(result.quality.parsed_lines == 22, "expected twenty-two parsed syslog fixture lines");
expect(result.quality.unparsed_lines == 9, "expected nine unparsed syslog fixture lines");
expect_close(result.quality.parse_success_rate, 21.0 / 30.0, 1e-9, "expected syslog fixture parse success rate");
expect_close(result.quality.parse_success_rate, 22.0 / 31.0, 1e-9, "expected syslog fixture parse success rate");

expect(result.events[0].event_type == loglens::EventType::SshInvalidUser, "expected invalid-user failed password");
expect(result.events[1].event_type == loglens::EventType::SshFailedPublicKey, "expected failed publickey variant");
Expand Down Expand Up @@ -792,8 +805,11 @@ void test_syslog_fixture_matrix_file() {
"expected failed-none invalid-user variant");
expect(result.events[19].username == "svc-none", "expected failed-none invalid username");
expect(result.events[20].event_type == loglens::EventType::SshInvalidUser,
"expected failed-none illegal-user variant");
expect(result.events[20].username == "legacy-none", "expected failed-none illegal username");
expect(result.events[21].event_type == loglens::EventType::SshInvalidUser,
"expected error-prefixed max-auth-tries invalid-user variant");
expect(result.events[20].username == "svc-error-maxauth",
expect(result.events[21].username == "svc-error-maxauth",
"expected error-prefixed max-auth-tries invalid username");

expect(result.quality.top_unknown_patterns.size() == 4, "expected four unknown syslog buckets");
Expand All @@ -817,12 +833,12 @@ void test_journalctl_fixture_matrix_file() {
std::nullopt});
const auto result = parser.parse_file(asset_path("parser_fixture_matrix_journalctl_short_full.log"));

expect(result.events.size() == 21, "expected twenty-one recognized journalctl fixture events");
expect(result.events.size() == 22, "expected twenty-two recognized journalctl fixture events");
expect(result.warnings.size() == 9, "expected nine journalctl fixture warnings");
expect(result.quality.total_lines == 30, "expected thirty journalctl fixture lines");
expect(result.quality.parsed_lines == 21, "expected twenty-one parsed journalctl fixture lines");
expect(result.quality.total_lines == 31, "expected thirty-one journalctl fixture lines");
expect(result.quality.parsed_lines == 22, "expected twenty-two parsed journalctl fixture lines");
expect(result.quality.unparsed_lines == 9, "expected nine unparsed journalctl fixture lines");
expect_close(result.quality.parse_success_rate, 21.0 / 30.0, 1e-9, "expected journalctl fixture parse success rate");
expect_close(result.quality.parse_success_rate, 22.0 / 31.0, 1e-9, "expected journalctl fixture parse success rate");

expect(result.events[0].event_type == loglens::EventType::SshInvalidUser, "expected journalctl invalid-user failed password");
expect(result.events[1].event_type == loglens::EventType::SshFailedPublicKey, "expected journalctl failed publickey variant");
Expand Down Expand Up @@ -863,8 +879,11 @@ void test_journalctl_fixture_matrix_file() {
"expected journalctl failed-none invalid-user variant");
expect(result.events[19].username == "svc-none", "expected journalctl failed-none invalid username");
expect(result.events[20].event_type == loglens::EventType::SshInvalidUser,
"expected journalctl failed-none illegal-user variant");
expect(result.events[20].username == "legacy-none", "expected journalctl failed-none illegal username");
expect(result.events[21].event_type == loglens::EventType::SshInvalidUser,
"expected journalctl error-prefixed max-auth-tries invalid-user variant");
expect(result.events[20].username == "svc-error-maxauth",
expect(result.events[21].username == "svc-error-maxauth",
"expected journalctl error-prefixed max-auth-tries invalid username");

expect(result.quality.top_unknown_patterns.size() == 4, "expected four unknown journalctl buckets");
Expand All @@ -888,6 +907,7 @@ int main() {
test_invalid_user_failure();
test_illegal_user_failure_is_normalized_as_invalid_user();
test_failed_none_invalid_user_is_normalized_as_invalid_user();
test_failed_none_illegal_user_is_normalized_as_invalid_user();
test_failed_none_without_invalid_user_stays_unsupported();
test_illegal_user_message_is_normalized_as_invalid_user();
test_standard_failure();
Expand Down
Loading