Skip to content

feat: rewrite ClamAV exporter in Go - #3

Open
tharinfernando wants to merge 1 commit into
OpenGovMail:mainfrom
tharinfernando:291-clamav-exporter-go
Open

feat: rewrite ClamAV exporter in Go#3
tharinfernando wants to merge 1 commit into
OpenGovMail:mainfrom
tharinfernando:291-clamav-exporter-go

Conversation

@tharinfernando

Copy link
Copy Markdown

Description

Go port of clamav-exporter/exporter.py with identical metrics and endpoints.


Changes Made

  • Add clamav-exporter/main.go: stdlib HTTP server, Unix socket probe with TCP clamav:3310 fallback, z<CMD> null-terminated protocol with 5s timeout, STATS/VERSION parsing, clamd and freshclam log parsing, Prometheus exposition for all 13 metrics
  • Add clamav-exporter/main_test.go: 9 unit tests (STATS, VERSION, log parsing, freshclam status, golden exposition output, down-state)
  • Add clamav-exporter/go.mod (go 1.21, stdlib only), Makefile (build, test, vet, docker-build), README.md (build/run docs, env vars, memory comparison)
  • Replace clamav-exporter/Dockerfile Python base with multi-stage Go build on alpine, non-root user, same EXPOSE 9810
  • Keep exporter.py in place until the Go version is verified in deployment

Checklist (Email System)

  • Core services tested (SMTP, IMAP, mail storage, end-to-end delivery) - N/A, exporter only, no mail path change
  • Security and compliance verified (auth via Thunder IDP, TLS, DKIM/SPF/DMARC, spam/virus filtering) - N/A, metrics only; Dockerfile runs as non-root appuser
  • Configuration and deployment checked (configs generated, Docker/Compose updated) - same build context and port, compose unchanged
  • Reliability confirmed (error handling, logging, monitoring) - fail-soft clamav_up 0 when ClamAV unreachable, sanitized logs, 5s timeouts
  • Documentation and usage notes updated (README, deployment, API) - README with build, run, env, and memory numbers

Testing Instructions

  1. cd clamav-exporter && go test ./... && go vet ./...
  2. STARTUP_DELAY_SECONDS=0 go run main.go, then curl -s localhost:9810/health returns OK
  3. Against a stub ClamAV TCP server replying canned STATS and VERSION: curl -s localhost:9810/metrics shows clamav_up 1 and all 13 metrics with correct values
  4. docker build -t opengovmail-clamav-exporter . succeeds, image 27.1MB vs python:3.11-slim base 198MB

Screenshots / Logs

 clamav_up 1
 clamav_state 1
 clamav_pools_total 2
 clamav_threads_live 10
 clamav_threads_idle 8
 clamav_queue_items 3
 clamav_memory_heap_mb 100.5
 clamav_memory_used_mb 80.25
 clamav_signature_version 26853
 clamav_version{version="1.0.0"} 1
 clamav_viruses_found_total 0
 clamav_files_scanned_total 0
 clamav_database_updated 0

Memory (host RSS, no backend reachable): Python 23,512 KB idle and after 50 scrapes; Go 10,084 KB idle and 10,912 KB after 50 scrapes.


Notes for Reviewers

  • One intentional behavior difference: Python always reports clamav_up 1 because log stats are merged into the stats map before the truthiness check, so it never detects a down daemon. The Go version reports clamav_up 0 when STATS and VERSION both fail. Flagging for approval or I can match the old behavior.
  • exporter.py deletion is deferred to a follow-up after this is verified live, per the issue.
  • No compose or prometheus config changes needed: same directory, same port 9810, same scrape target.

Ports clamav-exporter/exporter.py to Go with identical metrics and
endpoints. Adds unit tests, Makefile, README with build/run docs and
memory comparison. Keeps exporter.py until the Go version is verified
in deployment.

Refs OpenGovMail/OpenGovMail#291
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[TASK] Write ClamAV exporter in Go.

1 participant