Skip to content
All posts
June 18, 20265 min read

Scanning Logs Locally For Obvious Security Risks

A practical look at RustThreatLensAI, a small Rust CLI for local security log triage, brute-force detection, secret spotting, and JSON risk reports.

RustCLISecurityAutomationDebugging
Share:

Security work often starts with a messy text file.

An auth log, an nginx access log, a docker runtime log, or a pasted support snippet can contain the first useful signal. The problem is that raw logs are hard to review when you are tired, rushed, or trying to ship as a solo developer.

RustThreatLensAI is my small Rust CLI for that first pass. The binary is called

code
threatlens
, and its job is intentionally narrow: scan local log files, detect obvious suspicious patterns, and return a risk report in terminal or JSON format.

It is not a SIEM. It is not incident response automation. It is the small flashlight before you bring in heavier tools.

What The Tool Looks For

RustThreatLensAI focuses on high-signal rules that are easy to explain:

  • Failed login bursts from the same IP.
  • Secret-like strings inside logs.
  • Suspicious IP patterns from built-in checks.
  • Basic auth, nginx, docker, or auto-detected log input.
  • A risk level based on the most severe finding.

The normal command is direct:

bash
threatlens analyze examples/auth.sample

The sample auth log is intentionally small:

text
May 18 10:01:01 server sshd[1234]: Failed password for root from 10.0.0.1 port 22
May 18 10:01:02 server sshd[1234]: Failed password for root from 10.0.0.1 port 22
May 18 10:01:03 server sshd[1234]: Failed password for root from 10.0.0.1 port 22
May 18 10:01:04 server sshd[1234]: Failed password for root from 10.0.0.1 port 22
May 18 10:01:05 server sshd[1234]: Failed password for root from 10.0.0.1 port 22
May 18 10:02:00 server sshd[1234]: Accepted password for admin from 10.0.0.2 port 22
2026-05-18 curl -H 'Authorization: Bearer example-token-value' https://api.example.com

The report tells me what matters first:

text
ThreatLens Report
File: examples/auth.sample
Log Type: auto
Total Events: 7
Risk: Critical
Summary: 2 threat(s) detected. Immediate review recommended.

Findings:
  BRUTE_FORCE - 1 IP(s) with 5+ failed login attempts detected
    10.0.0.1: 5 failed attempts
  SECRET_IN_LOGS - 1 line(s) may contain exposed secrets
    2026-05-18 curl -H 'Authorization: Bearer example-token-value' https://api.example.com

That is the kind of output I want from a local triage tool: short, direct, and easy to act on.

Brute-Force Thresholds Need Context

The default brute-force threshold is

code
5
failed logins from the same IP.

That is useful for a small service or local fixture, but real environments vary. A noisy staging box might need a higher threshold. A sensitive admin surface might need a stricter one.

RustThreatLensAI v1.1.0 added a configurable threshold:

bash
threatlens analyze auth.log --brute-force-threshold 10

The detector keeps the behavior simple. It groups failed login events by IP and reports a

code
BRUTE_FORCE
finding when any IP reaches the configured threshold.

rust
fn detect_brute_force(events: &[LogEvent], threshold: usize) -> Option<Finding> {
    let mut ip_failures: HashMap<String, Vec<String>> = HashMap::new();

    for event in events {
        if event.action.as_deref() == Some("failed_login") {
            if let Some(ip) = &event.ip {
                ip_failures
                    .entry(ip.clone())
                    .or_default()
                    .push(event.line.clone());
            }
        }
    }

    let offenders: Vec<(String, Vec<String>)> = ip_failures
        .into_iter()
        .filter(|(_, lines)| lines.len() >= threshold)
        .collect();

    if offenders.is_empty() {
        return None;
    }

    Some(Finding {
        rule: "BRUTE_FORCE".to_string(),
        severity: Severity::Critical,
        description: format!(
            "{} IP(s) with {}+ failed login attempts detected",
            offenders.len(),
            threshold
        ),
        evidence,
    })
}

The important part is not cleverness. The important part is predictability. If the threshold is 10, the report says 10. If you lower it to 3 for a strict check, the rule becomes stricter in a way that is obvious.

Secret-Like Logs Are A Production Bug

One of the fastest security wins is catching secrets that accidentally land in logs.

RustThreatLensAI looks for simple secret-like patterns:

PatternWhy It Matters
code
password=
Credentials should not be logged
code
token=
Tokens may grant access
code
api_key=
API keys often reach third-party services
code
secret=
Generic but high-risk signal
code
Authorization: Bearer
Bearer tokens are commonly copied into debug output

This is intentionally conservative. A rule-based scanner will have false positives and false negatives. But even a basic warning is useful if it catches one real token before the log is shared in a ticket, pasted into a chat, or committed into a fixture.

[!WARNING] Do not casually upload raw production logs to AI tools, public issue trackers, or third-party paste services. Redact secrets, emails, IPs, user IDs, and account identifiers first.

JSON For Automation

Terminal output is useful when I am reading the result. JSON is useful when a script needs to make a decision.

bash
threatlens analyze auth.log --json

Example shape:

json
{
  "file": "auth.log",
  "log_type": "auto",
  "total_events": 7,
  "risk": "Critical",
  "summary": "2 threat(s) detected. Immediate review recommended.",
  "findings": [
    {
      "rule": "BRUTE_FORCE",
      "severity": "Critical",
      "description": "1 IP(s) with 5+ failed login attempts detected",
      "evidence": ["10.0.0.1: 5 failed attempts"]
    }
  ]
}

That makes the tool useful in small release or support workflows:

bash
threatlens analyze auth.log --json > threat-report.json

The JSON can be attached to a local investigation note, stored with a smoke-test artifact, or used by a script that blocks a release when risk is

code
High
or
code
Critical
.

Where It Fits

For a solo developer, the value is speed. You can run one local command before sharing logs, before opening a longer investigation, or before deciding whether a failure is normal noise.

Good use cases:

  • Checking a sample auth log for repeated failed SSH attempts.
  • Reviewing nginx access logs for basic suspicious patterns.
  • Scanning docker logs before sharing them in a support thread.
  • Adding a lightweight security check to a local release checklist.

Bad use cases:

  • Replacing centralized logging.
  • Replacing incident response.
  • Treating rule matches as legal or compliance proof.
  • Uploading sensitive logs without redaction.

The boundary is important. RustThreatLensAI is a triage tool. It should make the next action clearer, not pretend to finish the whole security job.

Key Takeaways

  • Local log scanning is useful when you need a fast first security signal.
  • Configurable brute-force thresholds make the same tool work across quiet and noisy environments.
  • Secret-like strings in logs should be treated as production bugs.
  • JSON output turns the scanner into a small automation building block.
  • A lightweight scanner should complement real security monitoring, not replace it.

RustThreatLensAI works because it stays small. It reads logs locally, surfaces obvious risks, and gives me a compact report before I decide whether deeper investigation is needed.

Share:
S

Sudarshan Chaudhari

AI Systems Builder / Product Engineer

Bangkok, Thailand

Solo Android developer with 13+ years in QA, building Android apps, AI automation systems, and developer tools at SudarshanTechLabs.

Stay updated

Get new posts on Android, Kotlin, and solo dev straight to your inbox.

Newsletter preferences

Building something? Available for Android dev and QA consulting.

Work with me

Comments — powered by Giscus