*We're building a plugin for Obsidian called [Relay](https://system3.md/relay). Relay makes Obsidian real-time collaborative. We love Obsidian, and hope to make it a competitive tool in the workplace.* *We use pocketbase as our auth backend, so I'm sharing some of the novel modifications we made to run it on fly.io.* This middleware outputs server logs in Combined Log Format, enabling powerful analytics through GoAccess - an elegant tool that turns raw logs into real-time traffic visualizations and insights without requiring JavaScript injection or third-party services. ## The Middleware ``` func logMiddleware(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { // Process the request err := next(c) // Get request and response details req := c.Request() res := c.Response() // Get client IP clientIP := c.RealIP() // Get user identifier (- if not authenticated) userIdentifier := "-" // Get username (- if not authenticated) username := "-" // Format timestamp in apache format timestamp := time.Now().Format("02/Jan/2006:15:04:05 -0700") // Get request size requestSize := req.Header.Get("Content-Length") if requestSize == "" { requestSize = "0" } // Format log entry in COMBINED format // Format: %h %l %u [%t] "%r" %>s %b "%{Referer}i" "%{User-agent}i" logEntry := fmt.Sprintf(`%s %s %s [%s] "%s %s %s" %d %s "%s" "%s"`, clientIP, userIdentifier, username, timestamp, req.Method, req.RequestURI, req.Proto, res.Status, requestSize, req.Referer(), req.UserAgent(), ) fmt.Printf("%s\n", logEntry) return err } } ``` The middleware wraps your HTTP handlers to log each request, capturing key metrics like timestamp, method, path, status code, and client details. Just pipe these logs into GoAccess to transform this raw data into an interactive dashboard of traffic patterns, user behavior, and potential issues - all while maintaining complete control over your analytics data. ## Getting the GeoIP Database 1. Visit https://db-ip.com/db/download/ip-to-country-lite 2. Scroll down to "Free Download" and download the mmdb file (will be named something like `dbip-country-lite-2024-01.mmdb`) 3. Place it in the same directory as your goaccess.conf file ## GoAccess Configuration ``` # Log format - matches our middleware output log-format COMBINED # Time format - matches our UTC timestamp format time-format %H:%M:%S date-format %d/%b/%Y # Output options html-report-title Analytics geoip-database dbip-country-lite-2024-11.mmdb # UI Options no-color false no-progress false no-parsing-spinner false # Enable all panels enable-panel VISITORS enable-panel REQUESTS enable-panel REQUESTS_STATIC enable-panel NOT_FOUND enable-panel HOSTS enable-panel OS enable-panel BROWSERS enable-panel VISIT_TIMES enable-panel VIRTUAL_HOSTS enable-panel REFERRERS enable-panel REFERRING_SITES enable-panel KEYPHRASES enable-panel GEO_LOCATION enable-panel STATUS_CODES ``` ## How to Run It ``` fly logs -c fly.toml --json | jq '.message' -r | goaccess -p goaccess.conf ``` This setup gives you: - Real-time traffic visualization - Geographic visitor distribution - Most accessed endpoints - Error rates and status codes - Traffic patterns and peak times - Browser and OS statistics All without any client-side code or third-party services!