Skip to content

[Feat] [4.x] Site Stats#1132

Draft
RichardAnderson wants to merge 4 commits into
vitodeploy:4.xfrom
RichardAnderson:feat/site-stats
Draft

[Feat] [4.x] Site Stats#1132
RichardAnderson wants to merge 4 commits into
vitodeploy:4.xfrom
RichardAnderson:feat/site-stats

Conversation

@RichardAnderson
Copy link
Copy Markdown
Member

@RichardAnderson RichardAnderson commented May 26, 2026

Introduces a new "Service" -> GoAccess.
When installed, "Stats" appear per site.

CleanShot 2026-05-26 at 08 46 51

Server -> Services -> Install (GoAccess)
Site -> Site Stats -> Refresh
Site -> Settings -> Statistics -> Enable/Disable

Stats updated every hour using GoAccess. Manual refresh via the stats page. Disabling stats on a site stops the logs from being analysed.

@RichardAnderson RichardAnderson changed the title [Feat] [4.x [Feat] [4.x] Site Stats May 26, 2026
@RichardAnderson RichardAnderson marked this pull request as draft May 26, 2026 07:56
@RichardAnderson RichardAnderson marked this pull request as ready for review May 26, 2026 08:59
@RichardAnderson RichardAnderson requested a review from Copilot May 26, 2026 09:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new GoAccess-based "log_analysis" service that produces per-site web statistics. When installed on a server, a hidden hourly root cron runs GoAccess against per-site Nginx/Caddy access logs, writes JSON reports to /var/lib/goaccess/data/{site_id}/{YYYY-MM}/, and exposes them through a new Site → Stats page with charts, top pages, referrers, status codes, and 404s. Sites get an enable/disable toggle in Settings; site lifecycle events write/cleanup per-site GoAccess configs automatically.

Changes:

  • New GoAccess service handler (install/uninstall/version + cron-based manage()), plus generic canBeManaged()/manage() on ServiceInterface/AbstractService and a Re-sync action in the services list.
  • New SiteStats actions/jobs/events/listeners (SyncGoAccessServer, RenderSiteStatsConf, GetSiteStats, WriteSiteStatsConfJob, RefreshSiteStatsJob, CleanupSiteStatsJob, ResyncGoAccessJob, SiteCreated/DeletedEvent), a UpdateSiteStats enable/disable action, and new controllers/routes (SiteStatsController, LogAnalysisController, stats toggle endpoints).
  • Frontend stats page with TanStack Query, socket-driven refresh, charts, and a settings toggle dialog; Nginx vhost template now writes a per-primary-domain access log; cron-jobs UI/API/policy now exclude hidden cron jobs while SyncCronJobs leaves them alone.

Reviewed changes

Copilot reviewed 43 out of 47 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
app/Services/LogAnalysis/GoAccess/GoAccess.php New GoAccess service handler with cron-based management.
app/Services/AbstractService.php, ServiceInterface.php Adds canBeManaged()/manage() defaults using systemd.
app/Actions/Service/Manage.php Uses canBeManaged() instead of unit() check; error message updated.
app/Jobs/Service/ManageJob.php Delegates start/stop logic to the service handler.
app/Providers/ServiceTypeServiceProvider.php Registers GoAccess as a log_analysis service.
app/Actions/SiteStats/SyncGoAccessServer.php Provisions GoAccess dirs, scripts, per-site configs, and hidden cron.
app/Actions/SiteStats/RenderSiteStatsConf.php Renders shell-var per-site config; rejects unsafe domains.
app/Actions/SiteStats/GetSiteStats.php Reads/parses GoAccess JSON via SSH; caches on status token.
app/Actions/Site/UpdateSiteStats.php Enables/disables stats and dispatches cleanup/write jobs.
app/Actions/Site/DeleteSite.php Dispatches SiteDeletedEvent after row delete.
app/Jobs/Site/{WriteSiteStatsConf,RefreshSiteStats,CleanupSiteStats,ResyncGoAccess}Job.php New queued jobs for stats lifecycle.
app/Jobs/Site/CreateJob.php Dispatches SiteCreatedEvent post-install.
app/Events/SiteCreatedEvent.php, SiteDeletedEvent.php New events.
app/Listeners/HandleSiteCreatedStats.php, HandleSiteDeletedStats.php Wire stats write/cleanup on site lifecycle.
app/Providers/AppServiceProvider.php Registers the new listeners.
app/Models/Site.php statsEnabled() helper.
app/Http/Resources/SiteResource.php Exposes stats_enabled.
app/Http/Controllers/SiteStatsController.php, LogAnalysisController.php, SiteSettingController.php New stats routes + enable/disable endpoints.
app/Http/Controllers/CronJobController.php, API/CronJobController.php Hide hidden cron jobs from listings.
app/Policies/CronJobPolicy.php Denies view/update/delete on hidden cron jobs.
app/Actions/CronJob/SyncCronJobs.php Excludes hidden crons from server-level sync logic.
resources/views/ssh/services/log_analysis/goaccess/*.blade.php GoAccess install/uninstall + run.sh/process.sh Blade templates.
resources/views/ssh/services/webserver/nginx/vhost.mustache Enables per-primary-domain Nginx access log.
resources/js/pages/sites/stats.tsx + components/{use-site-stats,stats-chart}.tsx New stats page, query hook, and chart component.
resources/js/pages/site-settings/{index.tsx, components/stats-toggle.tsx} Settings entry + enable/disable dialog.
resources/js/pages/services/components/{columns.tsx, resync-stats.tsx} Adds Re-sync action for log_analysis services.
resources/js/layouts/server/layout.tsx Adds Site → Stats nav item (gated).
resources/js/types/site.d.ts, site-stats.d.ts Types for new fields/response shape.
tests/Feature/SiteStatsTest.php Comprehensive feature tests for stats.
tests/Feature/ServicesTest.php Adds GoAccess to install data provider.

Comment thread app/Services/LogAnalysis/GoAccess/GoAccess.php Outdated
Comment thread app/Actions/SiteStats/SyncGoAccessServer.php
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 47 out of 51 changed files in this pull request and generated 2 comments.

Comment thread resources/views/ssh/services/webserver/nginx/vhost.mustache
Comment on lines +84 to +85
} elseif ($cron->status !== CronjobStatus::READY) {
$cron->update(['status' => CronjobStatus::READY]);
@RichardAnderson RichardAnderson marked this pull request as draft May 28, 2026 20:08
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.

2 participants