Skip to content

Customization

Laritor is built to be highly configurable, so you can adapt it to your exact requirements.

FeatureEnvironment VariableDefaultDescription
Backend API KeyLARITOR_BACKEND_KEYIngest API key used by Laritor’s backend to authenticate event submissions.
Ingest Endpoint URLLARITOR_INGEST_ENDPOINTFull URL where events are sent for ingestion.
Enable / Disable LaritorLARITOR_ENABLEDfalseTemporarily pause all event collection without uninstalling.
Environment NameLARITOR_ENVAPP_ENV valueOverride the detected environment name.
Server NameLARITOR_SERVER_NAMEHostnameSet a custom server name (useful for serverless environments).
Max Events Per OccurrenceLARITOR_MAX_EVENTS_PER_OCCURRENCE5000Limit events per request/command to control usage.
Laravel ContextLARITOR_RECORD_CONTEXTtrueCapture Laravel 11+ context.
Database Schema TrackingLARITOR_RECORD_DB_SCHEMAtrueTrack schema for visualization & AI-based query optimization.
Log LevelLARITOR_LOG_LEVELdebugMinimum log level to capture (debug, info, error, etc.).
Record Query BindingsLARITOR_RECORD_QUERY_BINDINGStrueInclude SQL query parameter values.
Record Query StringsLARITOR_RECORD_QUERY_STRINGfalseCapture HTTP query string parameters.
Request HeadersLARITOR_RECORD_REQUEST_HEADERSfalseCapture inbound request headers.
Request BodyLARITOR_RECORD_REQUEST_BODYfalseCapture inbound request body.
Response HeadersLARITOR_RECORD_REQUEST_RESPONSE_HEADERSfalseCapture inbound response headers.
Response BodyLARITOR_RECORD_REQUEST_RESPONSE_BODYfalseCapture inbound response body.
Outbound Request HeadersLARITOR_RECORD_OUTBOUND_REQUEST_HEADERSfalseCapture outbound request headers.
Outbound Request BodyLARITOR_RECORD_OUTBOUND_REQUEST_BODYfalseCapture outbound request body.
Outbound Response HeadersLARITOR_RECORD_OUTBOUND_REQUEST_RESPONSE_HEADERSfalseCapture outbound response headers.
Outbound Response BodyLARITOR_RECORD_OUTBOUND_REQUEST_RESPONSE_BODYfalseCapture outbound response body.
Rate Limit RequestsLARITOR_RATE_LIMIT_REQUESTSfalseEnable per-URL request sampling.
Requests per URL per MinuteLARITOR_RATE_LIMIT_REQUESTS_ATTEMPTSNumber of requests to record per URL per minute when rate limiting is enabled.

By default, Laritor records every supported event. If you’d like to skip certain events like specific routes, jobs, or queries, you can define a custom filter class.

This gives you full control over what gets tracked and helps reduce noise, save storage, and stay compliant.

Create a new file app/LaritorFilterOverride.php:

<?php
namespace App;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Http\Request;
use Illuminate\Notifications\Notification;
use Symfony\Component\Mime\Email;
use BinaryBuilds\LaritorClient\Override\DefaultOverride;
class LaritorFilterOverride extends DefaultOverride
{
/**
* @param string $cacheKey
* @return bool
*/
public function recordCacheHit($cacheKey): bool
{
return parent::recordCacheHit($cacheKey);
}
/**
* @param \Throwable $exception
* @return bool
*/
public function recordException($exception): bool
{
return parent::recordException($exception);
}
/**
* @param string $url
* @return bool
*/
public function recordOutboundRequest($url): bool
{
return parent::recordOutboundRequest($url);
}
/**
* @param string $query
* @param int $duration
* @return bool
*/
public function recordQuery($query, $duration): bool
{
return parent::recordQuery($query, $duration);
}
/**
* @param Job $job
* @return bool
*/
public function recordQueuedJob($job): bool
{
return parent::recordQueuedJob($job);
}
/**
* @param Request $request
* @return bool
*/
public function recordRequest($request): bool
{
return parent::recordRequest($request);
}
/**
* @param string $command
* @return bool
*/
public function recordCommandOrScheduledTask($command): bool
{
return parent::recordCommandOrScheduledTask($command);
}
/**
* @return bool
*/
public function recordTaskScheduler(): bool
{
return parent::recordTaskScheduler();
}
/**
* @param Email $message
* @return bool
*/
public function recordMail($message): bool
{
return parent::recordMail($message);
}
/**
* @param mixed $notifiable
* @param Notification $notification
* @return bool
*/
public function recordNotification($notifiable, $notification): bool
{
return parent::recordNotification($notifiable, $notification);
}
/**
* @param Request $request
* @return bool
*/
public function isBot($request): bool
{
return parent::isBot($request);
}
}

You can override any of these methods to return false for events you want to skip.

Step 2: Register the Override in AppServiceProvider
Section titled “Step 2: Register the Override in AppServiceProvider”

In your App\Providers\AppServiceProvider.php, register the override class in the boot() method:

use BinaryBuilds\LaritorClient\Override\LaritorOverride;
use App\LaritorFilterOverride;
public function boot(): void
{
$this->app->bind(LaritorOverride::class, LaritorFilterOverride::class);
}

✅ Done! Laritor will now call your custom filter class before recording each event.

MethodDescription
recordRequest(Request $request)return false to ignore specific requests
recordQuery(string $query, int $duration)return false to ignore specific queries
recordException(Throwable $e)return false to ignore specific exceptions
recordQueuedJob(Job $job)return false to ignore specific queued jobs
recordMail(Email $message)return false to ignore specific mails
recordNotification(mixed $notifiable, Notification $notification)return false to ignore specific notifications
recordCommandOrScheduledTask(string $command)return false to ignore specific command
recordOutboundRequest(string $url)return false to ignore specific outbound request
recordCacheHit(string $cacheKey)return false to ignore specific cache keys
recordTaskScheduler()return false to ignore tracking health of task scheduler
isBot(Request $request)return true or false to determine whether a request is from bot
public function recordRequest(Request $request): bool
{
$path = $request->path();
if (
$path === 'health' ||
str_starts_with($path, 'telescope') ||
str_starts_with($path, 'horizon') ||
preg_match('/\.(js|css|jpg|jpeg|png|svg|gif|ico)$/i', $path)
) {
return false;
}
return true;
}
public function recordQuery(string $query, int $duration): bool
{
// Skip queries faster than 5ms
if ($duration < 5) {
return false;
}
// Ignore Telescope and Horizon-related queries
if (preg_match('/\b(telescope_entries|horizon_jobs|horizon_tags)\b/i', $query)) {
return false;
}
return true;
}
public function recordQueuedJob(Job $job): bool
{
if ($job instanceof BroadcastEvent)) {
return false;
}
return true;
}
public function isBot(Request $request): bool
{
$ua = strtolower($request->userAgent());
if (str_contains($ua, 'internal-bot')) {
return false;
}
return parent::isBot($request);
}

If your application generates high traffic, you may not need to track every single one. Laritor allows per-URL sampling using built-in rate limiting. This helps reduce event volume, control costs, and keep your dashboards focused.

You can configure Laritor to only capture up to N requests per URL per minute. Any extra requests beyond the limit are dropped automatically.

When sampling is enabled:

  • Laritor tracks how many times each unique URL (e.g., /api/users, /checkout) has been recorded in the current minute.
  • Once the limit for a specific URL is reached, additional events for that URL are discarded until the next minute begins.
  • Limits apply independently per URL, so critical endpoints are not throttled.

To enable request sampling, add the following environment variables to your .env file:

LARITOR_RATE_LIMIT_REQUESTS=true
LARITOR_RATE_LIMIT_REQUESTS_ATTEMPTS=5

In the example above:

  • Laritor will record up to five requests per URL per minute.
  • If your app receives 20 requests to /api/orders in one minute, only the first 5 are recorded.
URLRequests Received (1 min)Sampling LimitRequests Recorded
/api/users1055
/api/orders353
/checkout1555

Laritor automatically redacts sensitive data before it leaves your servers. You can further customize the redaction logic by overriding the default redactor. This allows you to mask, replace, or remove data like email addresses, user information, IPs, and more tailored to your app’s privacy requirements.

Create app/LaritorDataRedactor.php:

<?php
namespace App;
use BinaryBuilds\LaritorClient\Redactor\DefaultRedactor;
use Illuminate\Support\Facades\Auth;
class LaritorDataRedactor extends DefaultRedactor
{
public function redactEmailAddress(string $address): string
{
return parent::redactEmailAddress($address);
}
public function redactString(string $text): string
{
return parent::redactString($text);
}
public function redactArrayValue(string $key, string $text): string
{
return parent::redactArrayValue($key, $text);
}
public function redactAuthenticatedUser() : array
{
// $user = Auth::user();
// return [
// 'id' => !empty($user->id) ? $user->id : null,
// 'name' => !empty($user->name) ? 'Logged in user '.$user->id : '',
// 'email' => !empty($user->email) ? 'user'.$user->id.'@gmail.com' : '',
// ];
return parent::redactAuthenticatedUser();
}
public function redactIPAddress($ip): string
{
return parent::redactIPAddress($ip);
}
public function redactUserAgent($userAgent): string
{
return parent::redactUserAgent($userAgent);
}
}

In your App\Providers\AppServiceProvider.php, register the redactor in the boot() method:

use BinaryBuilds\LaritorClient\Redactor\DataRedactor;
use App\LaritorDataRedactor;
public function boot(): void
{
$this->app->bind(DataRedactor::class, LaritorDataRedactor::class);
}

✅ Once registered, Laritor will use your custom redactor for all outgoing data.

Redactor MethodWhat it redactsUse case
redactEmailAddress(string $email)Email addressesReplace or mask user emails
redactString(string $text)Generic string valuesRedact log lines, message bodies, etc.
redactArrayValue(string $key, string $value)Array key-value pairsRedact keys like password, token, etc.
redactAuthenticatedUser(): arrayAuthenticated user detailsReturn only anonymized or partial data
redactIPAddress(string $ip)IP addressesMask or remove client/server IPs
redactUserAgent(string $ua)User-Agent headerStrip or normalize browser/device info
public function redactEmailAddress(string $address): string
{
[$user, $domain] = explode('@', $address);
return str_repeat('*', strlen($user)) . '@' . $domain;
}
public function redactString(string $text): string
{
// Redact common tokens or credentials in text
$patterns = [
'/Bearer\s+[A-Za-z0-9\-_\.=]+/i' => '[REDACTED_TOKEN]',
'/password\s*=\s*["\']?.+?["\']?/i' => 'password=[REDACTED]',
];
return preg_replace(array_keys($patterns), array_values($patterns), $text);
}

Redact specific array keys from request payloads, query params, headers, etc.

public function redactArrayValue(string $key, string $value): string
{
$sensitiveKeys = [
'password', 'token', 'access_token', 'refresh_token',
'api_key', 'secret', 'authorization', 'auth_token',
];
if (in_array(strtolower($key), $sensitiveKeys, true)) {
return '*****';
}
return $value;
}

Customize / Redact the logged-in user’s personal data:

public function redactAuthenticatedUser(): array
{
$user = Auth::user();
return [
'id' => $user?->id,
'name' => $user?->id ? 'User #' . $user->id : null,
'email' => $user?->id ? 'user' . $user->id . '@redacted.com' : null,
];
}
public function redactString(string $text): string
{
if (app()->environment('production')) {
return '*REDACTED*';
}
return $text;
}

By default, Laritor captures basic information about Artisan commands such as their name, start and end times, exit code, and context. If you also want to record the command’s output, you can enable this on a per-command basis.

To do so, simply add the SendOutputToLaritor trait to your console command class:

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use BinaryBuilds\LaritorClient\SendOutputToLaritor;
class ImportUsers extends Command
{
use SendOutputToLaritor;
protected $signature = 'users:import';
protected $description = 'Import users from external service';
public function handle()
{
$this->info('Starting import...');
// Import logic here
$this->info('Import complete!');
}
}

When this trait is included, Laritor will automatically capture and transmit all output generated by the command (including info, warn, error, comment, table, and other console messages) as part of the event data.

  • ✅ Useful for debugging failed or complex long-running commands.
  • ✅ Helps correlate command logs with system events.

With these configuration options, you can fine-tune Laritor’s behavior to align with your application’s requirements, performance goals, and privacy policies.

If you need help with advanced customization or have a specific use case not covered in this guide, feel free to reach out. We’re happy to help!

Email: [email protected]

Join: Laritor Discord