cachy-workstation

Log | Files | Refs | README

commit 4b0559579e14a551d096665938f8dab6ae826046
parent f79470f43b47ee9727e2f18a4d584aa1517f9b2d
Author: Chris Roberts <chris.roberts@learningunix.net>
Date:   Thu, 13 Aug 2026 06:05:43 -0500

added role to fetch server logs and view them

Diffstat:
Aroles/log-sync/defaults/main.yml | 8++++++++
Aroles/log-sync/meta/main.yml | 6++++++
Aroles/log-sync/tasks/main.yml | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroles/log-sync/templates/log-sync.service.j2 | 6++++++
Aroles/log-sync/templates/log-sync.timer.j2 | 9+++++++++
Aroles/log-sync/templates/pull-logs.sh.j2 | 24++++++++++++++++++++++++
Aroles/log-sync/vars/Archlinux.yml | 4++++
Aroles/log-sync/vars/Debian.yml | 4++++
8 files changed, 118 insertions(+), 0 deletions(-)

diff --git a/roles/log-sync/defaults/main.yml b/roles/log-sync/defaults/main.yml @@ -0,0 +1,8 @@ +--- +log_sync_remote_host: learningunix.net +log_sync_remote_user: cjr +log_sync_ssh_key: "{{ ansible_facts['user_dir'] }}/.ssh/id_ed25519_logsync" +log_sync_remote_paths: + - /var/log/nginx/ +log_sync_local_dest: "{{ ansible_facts['user_dir'] }}/learningunix-logs" +log_sync_interval: daily diff --git a/roles/log-sync/meta/main.yml b/roles/log-sync/meta/main.yml @@ -0,0 +1,6 @@ +--- +galaxy_info: + author: cjr + description: Periodically pull learningunix.net server logs to this workstation + license: BSD-3-Clause + min_ansible_version: "2.1" diff --git a/roles/log-sync/tasks/main.yml b/roles/log-sync/tasks/main.yml @@ -0,0 +1,57 @@ +--- +- name: Load OS-specific package names + ansible.builtin.include_vars: "{{ ansible_facts['os_family'] }}.yml" + +- name: Install rsync and an SSH client + ansible.builtin.package: + name: "{{ log_sync_packages }}" + state: present + become: true + +- name: Ensure local bin directory exists + ansible.builtin.file: + path: "{{ ansible_facts['user_dir'] }}/.local/bin" + state: directory + mode: "0755" + +- name: Ensure log destination directory exists + ansible.builtin.file: + path: "{{ log_sync_local_dest }}" + state: directory + mode: "0700" + +- name: Deploy log pull script + ansible.builtin.template: + src: pull-logs.sh.j2 + dest: "{{ ansible_facts['user_dir'] }}/.local/bin/pull-learningunix-logs.sh" + mode: "0755" + +- name: Ensure systemd user directory exists + ansible.builtin.file: + path: "{{ ansible_facts['user_dir'] }}/.config/systemd/user" + state: directory + mode: "0755" + +- name: Deploy systemd user service + ansible.builtin.template: + src: log-sync.service.j2 + dest: "{{ ansible_facts['user_dir'] }}/.config/systemd/user/log-sync.service" + mode: "0644" + +- name: Deploy systemd user timer + ansible.builtin.template: + src: log-sync.timer.j2 + dest: "{{ ansible_facts['user_dir'] }}/.config/systemd/user/log-sync.timer" + mode: "0644" + +- name: Reload systemd user units + ansible.builtin.systemd: + scope: user + daemon_reload: true + +- name: Enable and start the log-sync timer + ansible.builtin.systemd: + scope: user + name: log-sync.timer + enabled: true + state: started diff --git a/roles/log-sync/templates/log-sync.service.j2 b/roles/log-sync/templates/log-sync.service.j2 @@ -0,0 +1,6 @@ +[Unit] +Description=Pull learningunix.net server logs + +[Service] +Type=oneshot +ExecStart=%h/.local/bin/pull-learningunix-logs.sh diff --git a/roles/log-sync/templates/log-sync.timer.j2 b/roles/log-sync/templates/log-sync.timer.j2 @@ -0,0 +1,9 @@ +[Unit] +Description=Run learningunix.net log pull ({{ log_sync_interval }}) + +[Timer] +OnCalendar={{ log_sync_interval }} +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/roles/log-sync/templates/pull-logs.sh.j2 b/roles/log-sync/templates/pull-logs.sh.j2 @@ -0,0 +1,24 @@ +#!/bin/sh +# Pulls learningunix.net server logs down to this workstation. +# This machine is the rsync destination only — never writes back to the server. +set -e + +mkdir -p "{{ log_sync_local_dest }}" + +{% for path in log_sync_remote_paths %} +rsync -az -e "ssh -i {{ log_sync_ssh_key }} -o StrictHostKeyChecking=accept-new" \ + "{{ log_sync_remote_user }}@{{ log_sync_remote_host }}:{{ path }}" \ + "{{ log_sync_local_dest }}/" +{% endfor %} + +# Regenerate the goaccess report from all available nginx access logs (current + rotated). +# Normalized through zcat -f first: this goaccess build doesn't decompress .gz itself, +# and zcat -f transparently handles both compressed and plain files. +if command -v goaccess >/dev/null 2>&1; then + zcat -f {{ log_sync_local_dest }}/access.log* > {{ log_sync_local_dest }}/.combined-access.log 2>/dev/null + goaccess {{ log_sync_local_dest }}/.combined-access.log \ + --log-format=COMBINED \ + -o {{ log_sync_local_dest }}/report.html \ + 2>/dev/null || true + rm -f {{ log_sync_local_dest }}/.combined-access.log +fi diff --git a/roles/log-sync/vars/Archlinux.yml b/roles/log-sync/vars/Archlinux.yml @@ -0,0 +1,4 @@ +--- +log_sync_packages: + - rsync + - openssh diff --git a/roles/log-sync/vars/Debian.yml b/roles/log-sync/vars/Debian.yml @@ -0,0 +1,4 @@ +--- +log_sync_packages: + - rsync + - openssh-client