Security Analytics - v1.0.0
Custom SIEM Exporters
SiemExporterInterface:
interface SiemExporterInterface
{
public function export( array $events ): bool;
public function isAvailable(): bool;
public function getName(): string;
}
$events is an array of SecurityEvent model rows, already formatted by EventFormatter for the exporter's target shape.
Example: Sumo Logic exporter
namespace App\SecurityAnalytics\Exporters;
use ArtisanPackUI\SecurityAnalytics\Analytics\Siem\Contracts\SiemExporterInterface;
use Illuminate\Support\Facades\Http;
class SumoLogicExporter implements SiemExporterInterface
{
public function __construct(
protected string $collectorUrl,
) {}
public function export( array $events ): bool
{
$payload = implode( "\n", array_map( fn ( $event ) => json_encode( $event ), $events ) );
$response = Http::withBody( $payload, 'application/json' )
->post( $this->collectorUrl );
return $response->successful();
}
public function isAvailable(): bool
{
return rescue(
fn () => Http::timeout(2)->get( $this->collectorUrl . '/ping' )->successful(),
false,
);
}
public function getName(): string
{
return 'sumologic';
}
}
Registering
$this->app->bind(
\ArtisanPackUI\SecurityAnalytics\Analytics\Siem\Contracts\SiemExporterInterface::class,
fn () => new \App\SecurityAnalytics\Exporters\SumoLogicExporter(
collectorUrl: config('services.sumologic.collector_url'),
),
);
Single active exporter — bind your class to override the default.
Conventions
- Batch where possible. Most SIEMs prefer fewer larger requests. The framework batches events before calling
export()— your exporter receives the whole batch in one call. - Don't throw. Same as channels — return false for failures, throw only for truly unrecoverable errors (auth misconfiguration, etc.).
- Handle rate limits. Many SIEMs return 429. Use Laravel's
Http::retry()with exponential backoff in your exporter for resilience.