<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lenny</title>
    <description>The latest articles on DEV Community by Lenny (@lenny-ts).</description>
    <link>https://dev.to/lenny-ts</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2173087%2Fe04bf1a0-6a0e-45bc-ab52-536e344f1eca.jpg</url>
      <title>DEV Community: Lenny</title>
      <link>https://dev.to/lenny-ts</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lenny-ts"/>
    <language>en</language>
    <item>
      <title>caddy-analyzer: The security-first log analyzer Caddy has been missing</title>
      <dc:creator>Lenny</dc:creator>
      <pubDate>Thu, 27 Aug 2026 02:22:12 +0000</pubDate>
      <link>https://dev.to/lenny-ts/caddy-analyzer-the-security-first-log-analyzer-caddy-has-been-missing-4mml</link>
      <guid>https://dev.to/lenny-ts/caddy-analyzer-the-security-first-log-analyzer-caddy-has-been-missing-4mml</guid>
      <description>&lt;p&gt;If you're running Caddy v2 in production, you've probably noticed something: &lt;strong&gt;the standard log analysis tools don't work&lt;/strong&gt;. GoAccess, lnav, even &lt;code&gt;grep&lt;/code&gt; — they all choke on Caddy's nested JSON schema. You end up writing brittle one-off scripts to parse TLS versions, nested request headers, and float durations.&lt;/p&gt;

&lt;p&gt;I got tired of that. So I built &lt;strong&gt;&lt;a href="https://github.com/lenny-ts/caddy-analyzer" rel="noopener noreferrer"&gt;caddy-analyzer&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpundoe1lc02yin1020rm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpundoe1lc02yin1020rm.gif" width="720" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is it?
&lt;/h2&gt;

&lt;p&gt;caddy-analyzer is a CLI tool (written in Go) that &lt;strong&gt;natively parses Caddy v2 structured JSON logs&lt;/strong&gt; and layers a full security detection engine on top. Think of it as &lt;code&gt;goaccess&lt;/code&gt; + &lt;code&gt;fail2ban&lt;/code&gt; + threat intelligence, purpose-built for Caddy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with Caddy logs
&lt;/h2&gt;

&lt;p&gt;Caddy doesn't use Common/Combined Log Format. It outputs structured JSON like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/search?id=1' OR '1'='1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"remote_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"192.0.2.42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"proto"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HTTP/2.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0023&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tls1.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cipher_suite"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TLS_AES_256_GCM_SHA384"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Existing tools expect flat log lines. They can't handle nested maps, so you're stuck writing custom parsers. And more importantly: &lt;strong&gt;none of them detect attacks&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What caddy-analyzer does
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Security detection — 26 categories
&lt;/h3&gt;

&lt;p&gt;Every request is scanned against &lt;strong&gt;26 attack categories&lt;/strong&gt; using a dual-pass engine (URL-unescaped + raw URI matching) to catch multibyte and double-encoded bypass attempts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;What it catches&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SQL Injection&lt;/td&gt;
&lt;td&gt;UNION SELECT, blind injection, DB fingerprinting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XSS&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, event handlers, &lt;code&gt;data:text/html&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSRF&lt;/td&gt;
&lt;td&gt;Cloud metadata (169.254.169.254), loopback IPs, protocol smuggling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RCE&lt;/td&gt;
&lt;td&gt;Shell injection, reverse shells, &lt;code&gt;eval()&lt;/code&gt;, deserialization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Path Traversal / LFI&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;../&lt;/code&gt;, null byte, &lt;code&gt;/etc/passwd&lt;/code&gt;, &lt;code&gt;php://input&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSTI&lt;/td&gt;
&lt;td&gt;Jinja2, Freemarker, ERB, Thymeleaf template injection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Log4j / JNDI&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;${jndi:ldap://&lt;/code&gt;, obfuscated variants&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XXE / XInclude&lt;/td&gt;
&lt;td&gt;XML entity expansion, external DTD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CRLF Injection&lt;/td&gt;
&lt;td&gt;Header injection, log poisoning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...and 17 more&lt;/td&gt;
&lt;td&gt;GraphQL, LDAP, XPath, JWT abuse, beaconing/C2, scanner detection&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every detection is tagged with &lt;strong&gt;MITRE ATT&amp;amp;CK technique IDs&lt;/strong&gt;. Results are grouped by offending IP with request details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-time IP blocking
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;guard&lt;/code&gt; subcommand monitors your log stream and &lt;strong&gt;auto-blocks malicious IPs via iptables&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;caddy-analyze guard docker://my-caddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sliding window&lt;/strong&gt; rate limiting (per-IP, per-second buckets)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 default blocklist feeds&lt;/strong&gt; (Spamhaus, FireHOL, CINS, Tor exit nodes, Emerging Threats, AbuseIPDB)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GeoIP country blocking&lt;/strong&gt;: &lt;code&gt;--country-block CN,RU,IR&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit logging&lt;/strong&gt; and &lt;strong&gt;state persistence&lt;/strong&gt; across restarts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnet limiting&lt;/strong&gt; for distributed scan defense&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Live threat highlighting
&lt;/h3&gt;

&lt;p&gt;Stream logs in real-time with inline threat detection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;caddy-analyze &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;--detect&lt;/span&gt; docker://my-caddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;21:06:07  404 WARN  GET /cms/gather/getArticle  (1.71 KB, 2.27ms) - 2.58.137.2 [macOS/Safari] → XSS · RCE
21:06:07  404 WARN  GET /wp-content/plugins/restropress/readme.txt  (9 B, 73µs) - 2.58.137.2 [Linux/Firefox] → WP
21:06:06  200 OK  GET /  (3.04 KB, 5.95ms) - 2.58.137.2 [macOS/Firefox]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IPs are colored by severity (red = critical, amber = medium, olive = low). Clean entries show no markers — zero visual noise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Everything else
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TUI dashboard&lt;/strong&gt; (&lt;code&gt;--watch&lt;/code&gt;) — 8-tab live interface with security alerts, GeoIP, operational events&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTML reports&lt;/strong&gt; — standalone dark-mode reports for sharing with your team&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diff engine&lt;/strong&gt; — compare two log files to detect 5xx spikes and latency regressions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GeoIP enrichment&lt;/strong&gt; — offline mmdb lookup, auto-download, no API key needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sigma export&lt;/strong&gt; — export detection rules as Sigma YAML for SIEM import&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-source&lt;/strong&gt; — files, Docker (&lt;code&gt;docker://&lt;/code&gt;), K8s (&lt;code&gt;k8s://&lt;/code&gt;), journalctl (&lt;code&gt;journalctl://&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-update&lt;/strong&gt; with cosign signature verification&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install (Linux/macOS)&lt;/span&gt;
curl &lt;span class="nt"&gt;-sSfL&lt;/span&gt; https://raw.githubusercontent.com/lenny-ts/caddy-analyzer/main/install.sh | bash

&lt;span class="c"&gt;# Set your Caddy log path&lt;/span&gt;
caddy-analyze config /var/log/caddy/access.log

&lt;span class="c"&gt;# Full security scan&lt;/span&gt;
caddy-analyze &lt;span class="nt"&gt;--detect&lt;/span&gt;

&lt;span class="c"&gt;# Real-time streaming with detection&lt;/span&gt;
caddy-analyze &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;--detect&lt;/span&gt; docker://my-caddy

&lt;span class="c"&gt;# Launch interactive dashboard&lt;/span&gt;
caddy-analyze &lt;span class="nt"&gt;--watch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or try it with the included sample logs (no live Caddy needed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/lenny-ts/caddy-analyzer.git
&lt;span class="nb"&gt;cd &lt;/span&gt;caddy-analyzer
caddy-analyze &lt;span class="nt"&gt;--detect&lt;/span&gt; testdata/sample.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why not just use goaccess/lnav/grep?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;caddy-analyzer&lt;/th&gt;
&lt;th&gt;goaccess&lt;/th&gt;
&lt;th&gt;lnav&lt;/th&gt;
&lt;th&gt;grep/awk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Caddy v2 JSON native&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security threat detection (26 categories)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time firewall guard (iptables)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dual-pass evasion-resistant detection&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comparative diff engine&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TUI dashboard&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-source (Docker, K8s, journalctl)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GeoIP enrichment (offline)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Tested on a single core with synthetic logs (10% attack traffic):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Log size&lt;/th&gt;
&lt;th&gt;&lt;code&gt;--detect&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;Parse only&lt;/th&gt;
&lt;th&gt;RAM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.5K lines (real)&lt;/td&gt;
&lt;td&gt;0.6s&lt;/td&gt;
&lt;td&gt;&amp;lt;0.1s&lt;/td&gt;
&lt;td&gt;21 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10K lines&lt;/td&gt;
&lt;td&gt;1.5s&lt;/td&gt;
&lt;td&gt;0.2s&lt;/td&gt;
&lt;td&gt;25 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100K lines&lt;/td&gt;
&lt;td&gt;14.3s&lt;/td&gt;
&lt;td&gt;1.4s&lt;/td&gt;
&lt;td&gt;53 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1M lines&lt;/td&gt;
&lt;td&gt;2m29s&lt;/td&gt;
&lt;td&gt;~14s&lt;/td&gt;
&lt;td&gt;138 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;~7,000 lines/sec with detection, ~70,000 lines/sec parse-only.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it out
&lt;/h2&gt;

&lt;p&gt;The repo ships sample logs with all 26 attack categories using TEST-NET IPs (RFC 5737) — no real hosts involved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;caddy-analyze &lt;span class="nt"&gt;--detect&lt;/span&gt; testdata/sample.log          &lt;span class="c"&gt;# curated sample&lt;/span&gt;
caddy-analyze &lt;span class="nt"&gt;--detect&lt;/span&gt; testdata/large.log           &lt;span class="c"&gt;# 50K lines, ~27MB&lt;/span&gt;
caddy-analyze &lt;span class="nt"&gt;-f&lt;/span&gt; html &lt;span class="nt"&gt;-o&lt;/span&gt; report.html &lt;span class="nt"&gt;--detect&lt;/span&gt; testdata/sample.log  &lt;span class="c"&gt;# HTML report&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Contributing
&lt;/h2&gt;

&lt;p&gt;PRs and issues welcome! See &lt;a href="https://github.com/lenny-ts/caddy-analyzer/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;CONTRIBUTING.md&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;strong&gt;&lt;a href="https://github.com/lenny-ts/caddy-analyzer" rel="noopener noreferrer"&gt;github.com/lenny-ts/caddy-analyzer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you find it useful, a ⭐ on GitHub would mean a lot. It helps other Caddy users discover the tool.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written with ❤️ for the Caddy community&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
      <category>go</category>
      <category>security</category>
    </item>
  </channel>
</rss>
