<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Alek&#x27;s Blog - gitlab-ci</title>
    <subtitle>Production notes on Kubernetes, OpenShift, and OVHcloud: observability, log archiving, service mesh, LLM inference, and digital sovereignty.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://blog.none.at/tags/gitlab-ci/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://blog.none.at"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-03-12T00:00:00+00:00</updated>
    <id>https://blog.none.at/tags/gitlab-ci/atom.xml</id>
    <entry xml:lang="en">
        <title>AWFFull 4.0.0 — Modernising a 2008 Web Log Analyser</title>
        <published>2026-03-12T00:00:00+00:00</published>
        <updated>2026-03-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              aleks
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.none.at/blog/2026/2026-03-12-blog-awffull/"/>
        <id>https://blog.none.at/blog/2026/2026-03-12-blog-awffull/</id>
        
        <content type="html" xml:base="https://blog.none.at/blog/2026/2026-03-12-blog-awffull/">&lt;h1 id=&quot;awffull-4-0-0-modernising-a-2008-web-log-analyser&quot;&gt;AWFFull 4.0.0 — Modernising a 2008 Web Log Analyser&lt;a class=&quot;zola-anchor&quot; href=&quot;#awffull-4-0-0-modernising-a-2008-web-log-analyser&quot; aria-label=&quot;Anchor link for: awffull-4-0-0-modernising-a-2008-web-log-analyser&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;a class=&quot;zola-anchor&quot; href=&quot;#background&quot; aria-label=&quot;Anchor link for: background&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;aleks001&#x2F;awfull&quot;&gt;AWFFull 4.0.0&lt;&#x2F;a&gt; is a web server log analyser. It
reads Apache&#x2F;nginx&#x2F;Squid access logs and produces HTML reports with graphs
showing traffic, top URLs, referrers, user agents, country statistics, and
more. It was originally forked from
&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.mrunix.net&#x2F;webalizer&#x2F;&quot;&gt;The Webalizer&lt;&#x2F;a&gt; by Bradford L. Barrett
(1997–2001), extended as AWFFull by Steve McInerney from 2004, and actively
developed until 2008, when it was last released as version 3.10.2.&lt;&#x2F;p&gt;
&lt;p&gt;It still works well in 2026 — the core log-parsing logic is solid and the
output is clean. But the codebase had accumulated 18 years of code: EOL
libraries, dead links, obsolete command-line flags, a broken GeoIP
implementation, and a very old &lt;code&gt;config.guess&lt;&#x2F;code&gt;. Time for a
proper cleanup.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers what changed in AWFFull 4.0.0 and why.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;is-a-static-web-log-analyser-still-useful&quot;&gt;Is a Static Web Log Analyser Still Useful?&lt;a class=&quot;zola-anchor&quot; href=&quot;#is-a-static-web-log-analyser-still-useful&quot; aria-label=&quot;Anchor link for: is-a-static-web-log-analyser-still-useful&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Good question. The short answer is: yes — and arguably more so than before.&lt;&#x2F;p&gt;
&lt;p&gt;Modern web analytics platforms — Google Analytics, Matomo, Plausible, Grafana
with Loki, ELK stacks — are excellent for live dashboards and drill-down
exploration. But they share a common weakness: &lt;strong&gt;they are slow when you need to
process large volumes of historical log data and render the results as a
complete set of graphs and tables&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Feed a year of Apache logs (say, 500 million lines across 50 GB of gzipped
files) into an ELK pipeline and you’ll be waiting a long time for the data to
be ingested, indexed, and ready to query. Then wait again each time you open a
dashboard. Grafana rendering a year’s worth of nginx traffic across 30 panels?
Expect seconds of load time per page, per query.&lt;&#x2F;p&gt;
&lt;p&gt;AWFFull’s approach is different: it processes the raw log files directly, keeps
all state in a compact binary history file, and writes &lt;strong&gt;static HTML + PNG
output&lt;&#x2F;strong&gt; that loads instantly in any browser — even on a machine from 2010,
over a slow connection, or offline entirely. There is no query layer, no index,
no database, no running server. The report is just files.&lt;&#x2F;p&gt;
&lt;p&gt;For the typical use case — a sysadmin or developer who wants a monthly
overview of who accessed their server, from where, with what agents, hitting
which URLs — this is exactly the right trade-off:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fast to generate&lt;&#x2F;strong&gt;: processing a month of logs takes seconds, not minutes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Instant to view&lt;&#x2F;strong&gt;: static HTML, no round-trips, no query engine&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Self-contained&lt;&#x2F;strong&gt;: the report directory can be archived, moved, or served
from any static file server&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Privacy-friendly&lt;&#x2F;strong&gt;: no third-party JavaScript, no tracking pixels, no data
leaving your infrastructure — the raw IP addresses stay in your own logs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Works on air-gapped systems&lt;&#x2F;strong&gt;: nothing requires internet access at runtime&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It also complements rather than replaces live monitoring. You would typically
use Prometheus&#x2F;Grafana (or similar) to watch your infrastructure in real time,
and AWFFull to produce the monthly historical report that goes into a ticket or
a management summary.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shipping-access-logs-to-object-storage-and-running-in-containers&quot;&gt;Shipping Access Logs to Object Storage and Running in Containers&lt;a class=&quot;zola-anchor&quot; href=&quot;#shipping-access-logs-to-object-storage-and-running-in-containers&quot; aria-label=&quot;Anchor link for: shipping-access-logs-to-object-storage-and-running-in-containers&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The operational details — how to ship access logs to S3 or Azure Blob with
Fluent Bit, Vector, or Filebeat&#x2F;Logstash, how to handle concurrent writes and
log loss at high traffic, and how to run AWFFull as a stateless container
against object storage — are covered in the companion post:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.none.at&#x2F;blog&#x2F;2026&#x2F;2026-03-12-blog-log-shipping&#x2F;&quot;&gt;AWFFull in the Cloud: Shipping Logs to Object Storage and Running in Containers&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-big-ticket-items&quot;&gt;The Big Ticket Items&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-big-ticket-items&quot; aria-label=&quot;Anchor link for: the-big-ticket-items&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pcre-pcre2&quot;&gt;PCRE → PCRE2&lt;a class=&quot;zola-anchor&quot; href=&quot;#pcre-pcre2&quot; aria-label=&quot;Anchor link for: pcre-pcre2&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;AWFFull used libpcre (PCRE version 1) for log-line regex parsing. PCRE 1 has
been officially end-of-life since 2012 and is being dropped by distributions.
We migrated to &lt;strong&gt;PCRE2&lt;&#x2F;strong&gt;, the current maintained successor with a cleaner API
and better Unicode support. The change touched &lt;code&gt;parser.c&lt;&#x2F;code&gt;, &lt;code&gt;common.h&lt;&#x2F;code&gt;, and
&lt;code&gt;configure.ac&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;geoip-from-legacy-dat-to-libmaxminddb&quot;&gt;GeoIP: From Legacy &lt;code&gt;.dat&lt;&#x2F;code&gt; to libmaxminddb&lt;a class=&quot;zola-anchor&quot; href=&quot;#geoip-from-legacy-dat-to-libmaxminddb&quot; aria-label=&quot;Anchor link for: geoip-from-legacy-dat-to-libmaxminddb&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The old code used &lt;strong&gt;libGeoIP&lt;&#x2F;strong&gt; with a proprietary binary &lt;code&gt;.dat&lt;&#x2F;code&gt; format that
MaxMind deprecated in 2019. Country lookups were broken for anyone who hadn’t
kept a seven-year-old database around.&lt;&#x2F;p&gt;
&lt;p&gt;AWFFull 4.0.0 replaces this with &lt;strong&gt;libmaxminddb&lt;&#x2F;strong&gt;, the open standard MMDB
format used by both MaxMind (GeoLite2) and DB-IP. The migration is
transparent — IPv4 and IPv6 are both handled by a single &lt;code&gt;MMDB_lookup_string()&lt;&#x2F;code&gt;
call, with no separate code paths needed.&lt;&#x2F;p&gt;
&lt;p&gt;Free databases updated monthly:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Country&lt;&#x2F;strong&gt;: &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;db-ip.com&#x2F;db&#x2F;download&#x2F;ip-to-country-lite&quot;&gt;DB-IP Country Lite&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;ASN&lt;&#x2F;strong&gt;: &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;db-ip.com&#x2F;db&#x2F;download&#x2F;ip-to-asn-lite&quot;&gt;DB-IP ASN Lite&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;asn-statistics-new-table-and-pie-chart&quot;&gt;ASN Statistics: New Table and Pie Chart&lt;a class=&quot;zola-anchor&quot; href=&quot;#asn-statistics-new-table-and-pie-chart&quot; aria-label=&quot;Anchor link for: asn-statistics-new-table-and-pie-chart&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Once you have a MMDB-capable lookup layer, adding ASN (Autonomous System
Number) statistics is almost free. A second database (&lt;code&gt;GeoASNDatabase&lt;&#x2F;code&gt;) maps
IPs to their network operator — think “Cloudflare”, “Amazon AWS”,
“Deutsche Telekom”. The report now shows a &lt;strong&gt;Top ASNs&lt;&#x2F;strong&gt; table and pie chart,
answering the question &lt;em&gt;“which networks send the most traffic to my site?”&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;GeoASN          yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;GeoASNDatabase  &#x2F;usr&#x2F;share&#x2F;GeoIP&#x2F;dbip-asn-lite.mmdb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Performance note: both GeoIP and GeoASN lookups happen in the &lt;em&gt;output phase&lt;&#x2F;em&gt;,
once per unique IP address — not once per log line. On a typical site the
overhead is negligible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hyperscan-simd-pattern-matching&quot;&gt;Hyperscan: SIMD Pattern Matching&lt;a class=&quot;zola-anchor&quot; href=&quot;#hyperscan-simd-pattern-matching&quot; aria-label=&quot;Anchor link for: hyperscan-simd-pattern-matching&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;AWFFull supports extensive pattern lists for ignoring, grouping, and hiding
hosts, URLs, referrers, and agents. The original code used a
&lt;strong&gt;Boyer-Moore-Horspool&lt;&#x2F;strong&gt; linear scan: each log record was matched against every
pattern in turn.&lt;&#x2F;p&gt;
&lt;p&gt;When &lt;strong&gt;Intel Hyperscan&lt;&#x2F;strong&gt; (&lt;code&gt;libhyperscan&lt;&#x2F;code&gt;) is installed, AWFFull now compiles all
patterns from a given list into a single Hyperscan database and matches them in
one SIMD pass per record. For large pattern lists — say, 50+ bot&#x2F;spider agent
patterns — this is significantly faster. Hyperscan is auto-detected at
configure time and falls back to the existing BMH path if unavailable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; apt&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; libhyperscan-dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;.&#x2F;configure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;mimalloc-better-heap-performance&quot;&gt;mimalloc: Better Heap Performance&lt;a class=&quot;zola-anchor&quot; href=&quot;#mimalloc-better-heap-performance&quot; aria-label=&quot;Anchor link for: mimalloc-better-heap-performance&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;For large log files with millions of unique hosts, URLs, and referrers, heap
allocation overhead becomes measurable. Adding &lt;strong&gt;mimalloc&lt;&#x2F;strong&gt; (Microsoft’s
high-performance allocator) as an optional drop-in was straightforward via the
explicit &lt;code&gt;mi_calloc&lt;&#x2F;code&gt; API. Auto-detected at configure time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;xxh3-hash-function&quot;&gt;XXH3 Hash Function&lt;a class=&quot;zola-anchor&quot; href=&quot;#xxh3-hash-function&quot; aria-label=&quot;Anchor link for: xxh3-hash-function&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The internal hash table used djb2, a good general-purpose hash from 1991.
AWFFull 4.0.0 replaces it with &lt;strong&gt;XXH3&lt;&#x2F;strong&gt; (via the bundled &lt;code&gt;xxhash.h&lt;&#x2F;code&gt;), which
offers better distribution and significantly higher throughput on modern CPUs.
The table load-factor was also tuned to reduce collisions.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;user-visible-improvements&quot;&gt;User-Visible Improvements&lt;a class=&quot;zola-anchor&quot; href=&quot;#user-visible-improvements&quot; aria-label=&quot;Anchor link for: user-visible-improvements&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;date-stamp-on-graphs&quot;&gt;Date Stamp on Graphs&lt;a class=&quot;zola-anchor&quot; href=&quot;#date-stamp-on-graphs&quot; aria-label=&quot;Anchor link for: date-stamp-on-graphs&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Every generated PNG graph now shows the &lt;strong&gt;current date&lt;&#x2F;strong&gt; (&lt;code&gt;YYYY-MM-DD&lt;&#x2F;code&gt;) in the
top-right corner, aligned with the title baseline. Small but useful when you’re
looking at archived reports six months later.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;next-previous-month-navigation&quot;&gt;Next &#x2F; Previous Month Navigation&lt;a class=&quot;zola-anchor&quot; href=&quot;#next-previous-month-navigation&quot; aria-label=&quot;Anchor link for: next-previous-month-navigation&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Monthly report pages now show navigation links at the top:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;← February 2026  |  [Index]  |  April 2026 →&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Links are derived from the history file — only months that actually exist in
the database are linked.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;updated-browser-bot-detection&quot;&gt;Updated Browser&#x2F;Bot Detection&lt;a class=&quot;zola-anchor&quot; href=&quot;#updated-browser-bot-detection&quot; aria-label=&quot;Anchor link for: updated-browser-bot-detection&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;sample.conf&lt;&#x2F;code&gt; browser&#x2F;agent detection list dated from 2005 and contained
entries like “Netscape 4.5”, “Internet Explorer 3.0 (Win95)”, and
“MSNBot” — none of which have been seen in the wild for a decade or more. The
list has been completely rewritten:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Removed:&lt;&#x2F;strong&gt; Netscape 1–4.x, Internet Explorer 3–7, Firebird, Galeon, Camino,
msnbot (all entries)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Added:&lt;&#x2F;strong&gt; Chrome&#x2F;Chromium, Edge (Chromium), Brave, Samsung Browser, Firefox,
Safari, Opera (OPR&#x2F;), modern search bots (Bingbot, DuckDuckBot, YandexBot,
Baidu, Applebot, AhrefsBot, SemrushBot), AI crawlers (GPTBot, ClaudeBot,
PerplexityBot, Bytespider, CCBot, Amazonbot), and CLI tools (curl, Wget,
python-requests).&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;build-system-and-tooling&quot;&gt;Build System and Tooling&lt;a class=&quot;zola-anchor&quot; href=&quot;#build-system-and-tooling&quot; aria-label=&quot;Anchor link for: build-system-and-tooling&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;cli-cleanup-14-flags-removed&quot;&gt;CLI Cleanup: 14 Flags Removed&lt;a class=&quot;zola-anchor&quot; href=&quot;#cli-cleanup-14-flags-removed&quot; aria-label=&quot;Anchor link for: cli-cleanup-14-flags-removed&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;AWFFull inherited many single-letter flags from the original Webalizer. Flags
like &lt;code&gt;-G&lt;&#x2F;code&gt; (suppress hourly graph), &lt;code&gt;-L&lt;&#x2F;code&gt; (suppress legend), &lt;code&gt;-M&lt;&#x2F;code&gt; (mangle
agents), &lt;code&gt;-x&lt;&#x2F;code&gt; (HTML extension), and &lt;code&gt;-I&lt;&#x2F;code&gt; (index alias) had exact equivalents
in the config file. At version 4.0.0 — a major version bump — these were
removed from the CLI, along with three fully deprecated no-op flags (&lt;code&gt;-d&lt;&#x2F;code&gt;,
&lt;code&gt;-q&lt;&#x2F;code&gt;, &lt;code&gt;-Q&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;--help&lt;&#x2F;code&gt; output now documents the new verbosity levels (&lt;code&gt;-v&lt;&#x2F;code&gt; through
&lt;code&gt;-vvvvv&lt;&#x2F;code&gt;) and includes a note pointing config-file-only settings to
&lt;code&gt;awffull.conf(5)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;man-pages-docbook-xml-pandoc-markdown&quot;&gt;Man Pages: DocBook XML → Pandoc Markdown&lt;a class=&quot;zola-anchor&quot; href=&quot;#man-pages-docbook-xml-pandoc-markdown&quot; aria-label=&quot;Anchor link for: man-pages-docbook-xml-pandoc-markdown&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The existing man pages were written in DocBook XML 4.5 and built with
&lt;code&gt;xsltproc&lt;&#x2F;code&gt; — a tool that requires &lt;code&gt;xsltproc&lt;&#x2F;code&gt;, &lt;code&gt;docbook-xsl&lt;&#x2F;code&gt;, and several XML
schema packages, none of which are installed by default on most systems in
2026.&lt;&#x2F;p&gt;
&lt;p&gt;The man pages are now maintained as &lt;strong&gt;pandoc Markdown&lt;&#x2F;strong&gt; (&lt;code&gt;doc&#x2F;awffull.1.md&lt;&#x2F;code&gt;,
&lt;code&gt;doc&#x2F;awffull.conf.5.md&lt;&#x2F;code&gt;) and built with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;pandoc&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; man&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; awffull.1.md&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; awffull.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;configure.ac&lt;&#x2F;code&gt; auto-detects pandoc. Pre-built man pages remain in the
repository as a fallback for systems without pandoc. The DocBook XML sources
are retained in &lt;code&gt;doc&#x2F;&lt;&#x2F;code&gt; for historical reference.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;translations-quality-over-quantity&quot;&gt;Translations: Quality Over Quantity&lt;a class=&quot;zola-anchor&quot; href=&quot;#translations-quality-over-quantity&quot; aria-label=&quot;Anchor link for: translations-quality-over-quantity&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;AWFFull shipped with 33 language files, most of which were approximately 29% complete and
had not been updated since 2008. Rather than shipping incomplete translations
that silently fall back to English mid-report, we reduced to &lt;strong&gt;6 fully
complete languages&lt;&#x2F;strong&gt; (German, Finnish, Italian, Swedish, Brazilian Portuguese,
Indonesian) and brought all of them to &lt;strong&gt;100% (524&#x2F;524 strings)&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;.pot&lt;&#x2F;code&gt; template was regenerated with &lt;code&gt;xgettext&lt;&#x2F;code&gt; to include all new strings
added in 4.0.0 (GeoASN messages, MaxMind DB errors, pattern matching warnings).&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;repository-modernisation&quot;&gt;Repository Modernisation&lt;a class=&quot;zola-anchor&quot; href=&quot;#repository-modernisation&quot; aria-label=&quot;Anchor link for: repository-modernisation&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The project moved from a collection of legacy files to a cleaner structure:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Before&lt;&#x2F;th&gt;&lt;th&gt;After&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;README&lt;&#x2F;code&gt; + &lt;code&gt;README.FIRST&lt;&#x2F;code&gt; + &lt;code&gt;README.webalizer&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;README.md&lt;&#x2F;code&gt; (single entry point)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ChangeLog&lt;&#x2F;code&gt; (GNU format, frozen)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;CHANGELOG.md&lt;&#x2F;code&gt; (Keep a Changelog)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;COPYING&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;LICENSE&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;TODO&lt;&#x2F;code&gt; (plain text, 2008)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;TODO.md&lt;&#x2F;code&gt; (Markdown with &lt;code&gt;[x]&lt;&#x2F;code&gt; checkboxes)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;country-codes.txt&lt;&#x2F;code&gt; (2005, informational)&lt;&#x2F;td&gt;&lt;td&gt;removed&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;DNS.README&lt;&#x2F;code&gt; (dead link)&lt;&#x2F;td&gt;&lt;td&gt;removed&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;contrib&#x2F;&lt;&#x2F;code&gt; (Webalizer migration scripts)&lt;&#x2F;td&gt;&lt;td&gt;removed&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;config.guess&lt;&#x2F;code&gt; from 2008&lt;&#x2F;td&gt;&lt;td&gt;updated to automake 1.16 (2022)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;

&lt;link rel=&quot;stylesheet&quot; href=&quot;https:&#x2F;&#x2F;blog.none.at&#x2F;admonition.css?h=98c1477488c4b2c9d71a&quot; type=&quot;text&#x2F;css&quot;&gt;

&lt;div
  class=&quot;my-4 flex flex-col rounded-lg bg-(--admonition-bg)&quot;
  style=&quot;--admonition-bg: var(--admonition-tip);&quot;
&gt;
  &lt;div class=&quot;flex items-center rounded-t-lg bg-(--admonition-bg) p-1&quot;&gt;
    &lt;div
      class=&quot;mx-2 h-4 w-4 text-[0px] [background:var(--url)_center_center_no-repeat] dark:invert&quot;
      style=&quot;--url: url(icons&#x2F;tip.svg);&quot;
    &gt;
      tip
    &lt;&#x2F;div&gt;
    &lt;span&gt;&lt;strong&gt;tip&lt;&#x2F;strong&gt;&lt;&#x2F;span&gt;
  &lt;&#x2F;div&gt;
  &lt;div class=&quot;pl-4&quot;&gt;&lt;p&gt;The full list of technical changes is available in &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;aleks001&#x2F;awffull&#x2F;-&#x2F;blob&#x2F;main&#x2F;CHANGES.md&quot;&gt;CHANGES.md&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;ci-cd-pipeline&quot;&gt;CI&#x2F;CD Pipeline&lt;a class=&quot;zola-anchor&quot; href=&quot;#ci-cd-pipeline&quot; aria-label=&quot;Anchor link for: ci-cd-pipeline&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;A full GitLab CI pipeline was added covering:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Build verification&lt;&#x2F;strong&gt; on Debian 12&#x2F;13, Ubuntu 22.04&#x2F;24.04, AlmaLinux 8&#x2F;9&#x2F;10&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Source and binary tarballs&lt;&#x2F;strong&gt; on every push to &lt;code&gt;main&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;.deb&lt;&#x2F;code&gt; package&lt;&#x2F;strong&gt; (Ubuntu 24.04 amd64) on release tags&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;.rpm&lt;&#x2F;code&gt; package&lt;&#x2F;strong&gt; (AlmaLinux 9 amd64) on release tags&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Container image&lt;&#x2F;strong&gt; pushed to GitLab Container Registry (Ubuntu 24.04 base, all optional libs included)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;GitLab Release&lt;&#x2F;strong&gt; creation with all artifacts uploaded to the Generic Package Registry&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Releases are triggered by pushing a semver tag:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; tag&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; v4.0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; push&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-constant z-other&quot;&gt;-tags&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The container image is available as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pull&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; registry.gitlab.com&#x2F;aleks001&#x2F;awffull:v4.0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; pull&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; registry.gitlab.com&#x2F;aleks001&#x2F;awffull:latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The other artifacts are available on the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;aleks001&#x2F;awffull&#x2F;-&#x2F;releases&quot;&gt;Release Page&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;What’s Next&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Anchor link for: what-s-next&quot;&gt;🔗&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;TODO.md&lt;&#x2F;code&gt; tracks longer-term ideas: SVG graphs (replacing the aging
libgd dependency), weekly summaries, a templating system for the HTML output,
and better browser&#x2F;OS reporting. Contributions welcome.&lt;&#x2F;p&gt;
&lt;p&gt;The project is at &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;aleks001&#x2F;awfull&quot;&gt;https:&#x2F;&#x2F;gitlab.com&#x2F;aleks001&#x2F;awfull&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;em&gt;AWFFull is free software licensed under GPL v3 or later.&lt;&#x2F;em&gt;
&lt;em&gt;Based on The Webalizer by Bradford L. Barrett (1997–2001).&lt;&#x2F;em&gt;
&lt;em&gt;Extended by Steve McInerney (2004–2008) and Aleksandar Lazic (2026–present).&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
