Audience: support engineers, admins Difficulty: admin only
What this covers
Where the platform records what happened, what each log gives you, and how to find the row that matches a user complaint.
Quick reference
| Channel | URL | Best for |
|---|---|---|
| System Event Logs | /admin/system-event-logs |
Cross-app audit trail (parent ⇄ finance) |
| Form Monitor | /admin/form-monitor |
"User clicked submit but nothing happened" |
| User Monitor | /admin/user-monitor |
"Who is online right now?" |
| Admin Errors | /admin/errors |
Captured runtime exceptions surfaced to users |
| Beta Reports (admin queue) | /admin/beta-reports |
User-submitted feedback / bug reports |
| Telegram error notifier | (chat) | Real-time push on uncaught exceptions |
| Laravel logs | storage/logs/laravel.log (each app) |
Stack traces, raw exceptions |
| Apache logs | /var/log/apache2/{access,error}.log |
HTTP-level failures, 5xx |
| Solabooks Activity Logs | /finance/admin/activity-logs (in-tenant) |
Per-document edit trail |
| Portal Access Logs | tenant DB portal_access_logs |
Customer-portal opens |
System Event Logs (/admin/system-event-logs)
Three routes:
index— list with filters (event type, source app, organization, date).show— single event detail.ingest—POST /api/system-events/ingest— receives events from the finance app via HMAC.
What it captures. Events the finance app emits to the parent for audit. Examples:
- Tenant provisioning started/completed.
- A user's role changed in finance.
- A subscription was applied/cancelled.
- A workspace handoff happened.
What it does NOT capture. Per-document edits inside the tenant DB (see Solabooks Activity Logs for those).
How to use. Filter by organization_id (or client_id), pick a
narrow time window. Each row links back to the user and the source
controller.
Note. The audit flagged this ingest endpoint as having only api
middleware (no HMAC) — confirm the controller verifies the signature.
Form Monitor (/admin/form-monitor)
Captures form-submit telemetry. The finance app's FormEventController
forwards submit_attempt, submit_success, submit_failure events to
the parent.
Best ticket type. "I clicked Save and nothing happened."
What you get. For each tracked form:
- The form name (route name).
- User and organization.
- Validation errors (when the failure was a 422).
- Server response time.
If the user reports a hang, look for matching submit_attempt rows
without a paired submit_success or submit_failure — that's the
classic broken-form signature.
User Monitor (/admin/user-monitor)
Live presence ping. Each authenticated request from a user updates
their last_seen_at. The page tails the table.
Best ticket type. "Did anyone make this change in the last hour?"
What you get. Email, role, last URL, last activity timestamp, client.
Admin Errors (/admin/errors)
The parent app exposes POST /error-report (open) and
POST /api/errors/ingest (HMAC). Either path writes a row to the
errors table.
What you get. Stack class, message, file, line, request URL, timestamp, organization (if available).
Best ticket type. A user reports a 500. Filter by their email and the timestamp; find the matching row; pull the stack.
The Telegram error notifier (configurable in
config/telegram.php or similar) pushes the same rows to a Telegram
chat in real time. Useful for catching outages.
Beta Reports (/admin/beta-reports)
User-submitted feedback. The flow:
- User clicks Send Beta Feedback (top right of finance UI when
tracker.feedback_widgetor similar is on). - Solabooks app forwards to parent via
POST /api/beta-reports(HMAC-signed). - Admin queue at
/admin/beta-reports.
Each report has: title, description, screenshot URL, user, org, app. Admin can mark resolved or wont-fix.
Best ticket type. "I submitted feedback last week and never heard back" — find their row.
Laravel logs (storage/logs/laravel.log)
Both apps write here. Daily rotation. Look in:
/var/www/html/solavel/storage/logs/laravel.log(parent)/var/www/html/solavel-finance/storage/logs/laravel.log(finance)
Tail commands.
tail -200 /var/www/html/solavel/storage/logs/laravel.log
tail -200 /var/www/html/solavel-finance/storage/logs/laravel.log
grep -A 5 "<email>" /var/www/html/solavel/storage/logs/laravel.log
Search by: email, organization id, exception class, request URL.
Apache logs
For 5xx responses or strange redirect behaviour, Laravel may not have captured anything (Apache rejected before PHP). Look in:
/var/log/apache2/access.log— every request (status, URI, IP)./var/log/apache2/error.log— virtual-host errors, fcgi crashes.
The vhost config is at ops/apache/solavel.com.conf — useful when
debugging mounting issues for the /finance/ path.
Solabooks Activity Logs (in-tenant)
Inside the finance app at /finance/admin/activity-logs. Per-document
edit trail kept by Activity/ActionLogController.
What you get. Every CRUD on invoices, bills, journal entries, payments, etc. Plus posting/unposting events. Plus deletes (soft and hard).
This is the only log that surfaces per-tenant document history. The parent-side System Event Logs do not see inside the tenant DB.
Search by: user, document type, document id, date range.
Portal Access Logs (in-tenant)
Tenant DB table portal_access_logs. One row per customer-portal
open. Fields: customer id, document id, IP, user agent, opened_at.
Best ticket type. "Customer says they never received the link" or "Customer says the link doesn't work."
If the table is empty for that document: customer never clicked. Otherwise: each open is timestamped — you can see if and when they got in.
Putting it together
Walking from a complaint to a row:
- Capture timestamp.
- Apache
access.log— confirms the request hit the server. - Laravel log — captures any exception.
- Admin Errors — same exception, indexed by user.
- Form Monitor — only if a form submit was involved.
- System Event Logs — only if it was a cross-app event.
- Activity Log (in finance) — only for per-document edits.
If none of those have a row, you're looking at a problem outside the captured surface — likely client-side (browser, network, browser extension blocking JS).