Appearance
Logging
Since essence v0.9.0, all TBE packages log through a single PSR-3 helper, tbeLog(), with a shared level policy and automatic webhook context. This page defines the convention every package (and host app) follows.
Level Policy
| Level | Meaning | Examples |
|---|---|---|
info | Business event — something that is supposed to happen, happened | invoice paid, wallet credited, service provisioned, campaign completed |
warning | Expected user friction or misconfiguration — no stack trace needed | validation failure, stale callback button, gateway rejected a request, unregistered state answer |
error | Genuine bug — always with ['exception' => $e] | unhandled exception, failed Telegram API init, failed webhook setup |
debug | High-volume diagnostics, off in production | per-message campaign send failures, backup-restore file progress |
With production at LOG_LEVEL=info, the error count becomes a real alarm signal: errors are bugs, warnings are friction, info is the business ledger.
tbeLog()
php
tbeLog('billing')->info('Invoice paid', [
'invoice_id' => $invoice->getKey(),
'price' => $invoice->price,
]);
tbeLog('essence')->error('Failed to create bot: ' . $e->getMessage(), ['exception' => $e]);The helper returns a TbeLogger (PSR-3 LoggerInterface). Every entry automatically gains:
package— the tag you pass totbeLog()(omit for none; each package uses its own name:essence,billing,user-wallet,gateway-card,gateway-zibal,affiliates,announcements,settings,user-management, host apps use their app name, e.g.vshop)bot_id,update_id,update_type,chat_id,user_id,state— pulled from the currentwHook()context when a webhook is active; silently omitted otherwise
Logging never throws: any failure inside the logger is swallowed so it can never break bot flow.
Rules
- One entry per event. Never split one failure across multiple log calls.
- Identifiers, not payloads. Log
invoice_id,chat_id, amounts — never full update JSON or message text. The full update already goes to the bug-report Telegram chat as a document. - Traces only for bugs. Expected exceptions log at
warningwith no trace; the catch-all path logserrorwith['exception' => $e](Laravel's formatter appends the stack trace). - Sensitive values are redacted. e.g.
settingslogs[redacted]forSENSITIVE-type setting values.
Configuration
php
// config/tbe-essence.php
'logging' => [
// Log channel for all TBE packages; null uses the app's default channel.
'channel' => env('TBE_LOG_CHANNEL'),
// Also push debug/bug reports to the bug_report Telegram chat.
'telegram_notify' => env('TBE_LOG_TELEGRAM_NOTIFY', true),
],channel: null(default) — everything goes to the app's default channel; existing bots need no changes.telegram_notify— controls whetherdebugMessage(),mixedDebugMessage()andexceptionReport()also send to thebug_report.telegram_chat_idchat.
Host App Setup (Reference: vshop)
vshop separates bot traffic from app/framework logs with two rotated daily channels:
php
// config/logging.php
'telegram' => [
'driver' => 'daily',
'path' => storage_path('logs/telegram.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => env('LOG_DAILY_DAYS', 14),
'replace_placeholders' => true,
],dotenv
LOG_CHANNEL=stack
LOG_STACK=daily # app log, rotated, 14 days
LOG_LEVEL=info # debug only while actively diagnosing
TBE_LOG_CHANNEL=telegram # bot traffic → telegram-YYYY-MM-DD.logBoth files show up in Log Viewer automatically; filter bot entries by the package context key.
Bug Reports via Telegram
exceptionReport($e) (used by the catch-all in ExceptionHandler) does two things:
- Logs one
errorentry with the exception. - If
bug_report.telegram_chat_idis set andtelegram_notifyis on, sends a summary message plus.traceand.updatedocuments to that chat.
debugMessage() / mixedDebugMessage() log a single warning and (optionally) mirror it to the same chat.