- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
254 lines
7.7 KiB
PHP
254 lines
7.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Framework\Telemetry;
|
|
|
|
use App\Framework\CircuitBreaker\CircuitBreaker;
|
|
use App\Framework\DateTime\SystemClock;
|
|
use App\Framework\Logging\DefaultLogger;
|
|
use App\Framework\Performance\EnhancedPerformanceCollector;
|
|
use App\Framework\Telemetry\Config\TelemetryConfig;
|
|
use App\Framework\Telemetry\Exporters\FileExporter;
|
|
use App\Framework\Telemetry\Exporters\PrometheusExporter;
|
|
use App\Framework\Telemetry\UnifiedTelemetryService;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
/**
|
|
* Tests for the Telemetry module
|
|
*/
|
|
class TelemetryTest extends TestCase
|
|
{
|
|
private UnifiedTelemetryService $telemetryService;
|
|
|
|
private FileExporter $fileExporter;
|
|
|
|
private PrometheusExporter $prometheusExporter;
|
|
|
|
private string $tempDir;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
// Create a temporary directory for telemetry files
|
|
$this->tempDir = sys_get_temp_dir() . '/telemetry-test-' . uniqid();
|
|
mkdir($this->tempDir, 0755, true);
|
|
|
|
// Create dependencies
|
|
$clock = new SystemClock();
|
|
$logger = new DefaultLogger();
|
|
$performanceCollector = new EnhancedPerformanceCollector($clock);
|
|
$circuitBreaker = new CircuitBreaker($logger);
|
|
|
|
// Create exporters
|
|
$this->fileExporter = new FileExporter($this->tempDir, true);
|
|
$this->prometheusExporter = new PrometheusExporter();
|
|
|
|
// Create config
|
|
$config = new TelemetryConfig(
|
|
serviceName: 'test-service',
|
|
serviceVersion: '1.0.0',
|
|
environment: 'test',
|
|
enabled: true,
|
|
samplingRatio: 1.0
|
|
);
|
|
|
|
// Create telemetry service
|
|
$this->telemetryService = new UnifiedTelemetryService(
|
|
$performanceCollector,
|
|
$circuitBreaker,
|
|
$logger,
|
|
$clock,
|
|
$config
|
|
);
|
|
|
|
// Add exporters
|
|
$this->telemetryService->addExporter($this->fileExporter);
|
|
$this->telemetryService->addExporter($this->prometheusExporter);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
// Clean up temporary directory
|
|
$this->removeDirectory($this->tempDir);
|
|
|
|
parent::tearDown();
|
|
}
|
|
|
|
/**
|
|
* Test that operations can be created and exported
|
|
*/
|
|
public function testOperations(): void
|
|
{
|
|
// Start an operation
|
|
$operation = $this->telemetryService->startOperation(
|
|
'test_operation',
|
|
'test',
|
|
['test_attribute' => 'test_value']
|
|
);
|
|
|
|
// Add an attribute
|
|
$operation->addAttribute('another_attribute', 'another_value');
|
|
|
|
// End the operation
|
|
$operation->end('success');
|
|
|
|
// Flush exporters
|
|
$this->telemetryService->flush();
|
|
|
|
// Check that the operation was exported to the file
|
|
$date = date('Y-m-d');
|
|
$operationsFile = "{$this->tempDir}/operations-{$date}.jsonl";
|
|
$this->assertFileExists($operationsFile);
|
|
|
|
$content = file_get_contents($operationsFile);
|
|
$this->assertStringContainsString('test_operation', $content);
|
|
$this->assertStringContainsString('test_attribute', $content);
|
|
$this->assertStringContainsString('another_attribute', $content);
|
|
$this->assertStringContainsString('success', $content);
|
|
}
|
|
|
|
/**
|
|
* Test that metrics can be recorded and exported
|
|
*/
|
|
public function testMetrics(): void
|
|
{
|
|
// Record a metric
|
|
$this->telemetryService->recordMetric(
|
|
'test_metric',
|
|
42.0,
|
|
'units',
|
|
['test_attribute' => 'test_value']
|
|
);
|
|
|
|
// Flush exporters
|
|
$this->telemetryService->flush();
|
|
|
|
// Check that the metric was exported to the file
|
|
$date = date('Y-m-d');
|
|
$metricsFile = "{$this->tempDir}/metrics-{$date}.jsonl";
|
|
$this->assertFileExists($metricsFile);
|
|
|
|
$content = file_get_contents($metricsFile);
|
|
$this->assertStringContainsString('test_metric', $content);
|
|
$this->assertStringContainsString('42', $content);
|
|
$this->assertStringContainsString('units', $content);
|
|
$this->assertStringContainsString('test_attribute', $content);
|
|
|
|
// Check Prometheus output
|
|
$prometheusOutput = $this->prometheusExporter->getMetricsOutput();
|
|
$this->assertStringContainsString('test_metric', $prometheusOutput);
|
|
$this->assertStringContainsString('42', $prometheusOutput);
|
|
}
|
|
|
|
/**
|
|
* Test that events can be recorded and exported
|
|
*/
|
|
public function testEvents(): void
|
|
{
|
|
// Record an event
|
|
$this->telemetryService->recordEvent(
|
|
'test_event',
|
|
['test_attribute' => 'test_value'],
|
|
'info'
|
|
);
|
|
|
|
// Flush exporters
|
|
$this->telemetryService->flush();
|
|
|
|
// Check that the event was exported to the file
|
|
$date = date('Y-m-d');
|
|
$eventsFile = "{$this->tempDir}/events-{$date}.jsonl";
|
|
$this->assertFileExists($eventsFile);
|
|
|
|
$content = file_get_contents($eventsFile);
|
|
$this->assertStringContainsString('test_event', $content);
|
|
$this->assertStringContainsString('info', $content);
|
|
$this->assertStringContainsString('test_attribute', $content);
|
|
|
|
// Check Prometheus output (events are exported as counters)
|
|
$prometheusOutput = $this->prometheusExporter->getMetricsOutput();
|
|
$this->assertStringContainsString('events_info_total', $prometheusOutput);
|
|
}
|
|
|
|
/**
|
|
* Test the trace method
|
|
*/
|
|
public function testTrace(): void
|
|
{
|
|
// Use the trace method
|
|
$result = $this->telemetryService->trace(
|
|
'test_trace',
|
|
'test',
|
|
function () {
|
|
return 'test_result';
|
|
},
|
|
['test_attribute' => 'test_value']
|
|
);
|
|
|
|
// Check the result
|
|
$this->assertEquals('test_result', $result);
|
|
|
|
// Flush exporters
|
|
$this->telemetryService->flush();
|
|
|
|
// Check that the operation was exported to the file
|
|
$date = date('Y-m-d');
|
|
$operationsFile = "{$this->tempDir}/operations-{$date}.jsonl";
|
|
$this->assertFileExists($operationsFile);
|
|
|
|
$content = file_get_contents($operationsFile);
|
|
$this->assertStringContainsString('test_trace', $content);
|
|
$this->assertStringContainsString('test_attribute', $content);
|
|
$this->assertStringContainsString('success', $content);
|
|
}
|
|
|
|
/**
|
|
* Test error handling in operations
|
|
*/
|
|
public function testErrorHandling(): void
|
|
{
|
|
// Start an operation
|
|
$operation = $this->telemetryService->startOperation(
|
|
'error_operation',
|
|
'test',
|
|
['test_attribute' => 'test_value']
|
|
);
|
|
|
|
// Mark as failed
|
|
$operation->fail('Test error message');
|
|
|
|
// Flush exporters
|
|
$this->telemetryService->flush();
|
|
|
|
// Check that the operation was exported to the file
|
|
$date = date('Y-m-d');
|
|
$operationsFile = "{$this->tempDir}/operations-{$date}.jsonl";
|
|
$this->assertFileExists($operationsFile);
|
|
|
|
$content = file_get_contents($operationsFile);
|
|
$this->assertStringContainsString('error_operation', $content);
|
|
$this->assertStringContainsString('error', $content);
|
|
$this->assertStringContainsString('Test error message', $content);
|
|
}
|
|
|
|
/**
|
|
* Helper method to recursively remove a directory
|
|
*/
|
|
private function removeDirectory(string $dir): void
|
|
{
|
|
if (! is_dir($dir)) {
|
|
return;
|
|
}
|
|
|
|
$files = array_diff(scandir($dir), ['.', '..']);
|
|
foreach ($files as $file) {
|
|
$path = "$dir/$file";
|
|
is_dir($path) ? $this->removeDirectory($path) : unlink($path);
|
|
}
|
|
|
|
rmdir($dir);
|
|
}
|
|
}
|