--- /dev/null
+-- Copyright (c) 2024 Jakub Czajka <jakub@ekhem.eu.org>
+-- License: 0BSD.
+
+CREATE TABLE IF NOT EXISTS access_logs (
+ access_log TEXT NOT NULL,
+ created_at DATE NOT NULL
+);
+
+DO $$
+BEGIN
+ IF NOT EXISTS (SELECT * FROM pg_user WHERE usename = 'rsyslog')
+ THEN
+ CREATE ROLE rsyslog LOGIN;
+
+ GRANT INSERT
+ ON access_logs
+ TO rsyslog;
+
+ /* Execute for the current database. */
+ EXECUTE FORMAT('GRANT CONNECT
+ ON DATABASE %I
+ TO rsyslog', current_database());
+ END IF;
+END$$;
--- /dev/null
+-- Copyright (c) 2024 Jakub Czajka <jakub@ekhem.eu.org>
+-- License: 0BSD.
+
+DO $$
+BEGIN
+ IF EXISTS (SELECT * FROM pg_user WHERE usename = 'rsyslog')
+ THEN
+ REVOKE INSERT
+ ON access_logs
+ FROM rsyslog;
+
+ EXECUTE
+ FORMAT('REVOKE CONNECT
+ ON DATABASE %I
+ FROM rsyslog;', current_database());
+
+ DROP ROLE rsyslog;
+ END IF;
+END$$;
+
+DROP TABLE IF EXISTS access_logs;
local mail_db dovecot trust
host mail_db dovecot ::1/128 trust
host mail_db dkim ::1/128 trust
+host analytics_db rsyslog ::1/128 trust
local gym_db gym_tracker trust
local matrix_db synapse_user trust
local metrics_db metrics_tracker trust
--- /dev/null
+# Copyright (c) 2024 Jakub Czajka <jakub@ekhem.eu.org>
+# License: GPL-3.0 or later.
+
+# Based on https://www.rsyslog.com/doc/configuration/modules/ompgsql.html and
+# https://blog.supersetinc.com/2018/04/09/high-performance-logging-nginx-postgres-using-rsyslog.
+
+module(load="imfile")
+
+input(type="imfile"
+ File="${website_log_file}"
+ Tag="website:")
+
+template(name="insert_access_log" type="list" option.sql="on") {
+ constant(value="INSERT INTO access_logs (access_log, created_at) values ('")
+ property(name="msg")
+ constant(value="','")
+ property(name="timereported" dateformat="pgsql" date.inUTC="on")
+ constant(value="')")
+}
+
+# Load the ompgsql output module
+module(load="ompgsql")
+
+if ( ${dollar}syslogtag == 'website:' ) then {
+ action(type="ompgsql"
+ server="localhost"
+ user="rsyslog"
+ db="${analytics_db}"
+ template="insert_access_log"
+ queue.type="linkedList")
+}
--- /dev/null
+rsyslog
+========
+
+Create database `analytics_db`.
+
+```
+CREATE DATABASE analytics_db;
+```
+
+Execute `analytics_db_create.sql`.
+
+```
+psql --dbname=mail_db --file=databases/analytics/analytics_db_create.sql
+```