|
5 | 5 | namespace Cortex; |
6 | 6 |
|
7 | 7 | use Throwable; |
8 | | -use Monolog\Logger; |
9 | 8 | use Cortex\LLM\LLMManager; |
10 | 9 | use Cortex\Agents\Registry; |
11 | 10 | use Cortex\Console\AgentChat; |
12 | 11 | use Cortex\LLM\Contracts\LLM; |
13 | 12 | use Cortex\Mcp\McpServerManager; |
14 | | -use Monolog\Handler\StreamHandler; |
15 | | -use Monolog\Formatter\LineFormatter; |
16 | 13 | use Illuminate\Support\Facades\Blade; |
17 | 14 | use Cortex\ModelInfo\ModelInfoFactory; |
18 | 15 | use Spatie\LaravelPackageTools\Package; |
19 | 16 | use Cortex\Embeddings\EmbeddingsManager; |
20 | 17 | use Cortex\Prompts\PromptFactoryManager; |
| 18 | +use OpenTelemetry\Contrib\Otlp\Protocols; |
21 | 19 | use Cortex\Embeddings\Contracts\Embeddings; |
22 | 20 | use Cortex\Prompts\Contracts\PromptFactory; |
| 21 | +use OpenTelemetry\Contrib\Otlp\SpanExporter; |
| 22 | +use OpenTelemetry\SDK\Resource\ResourceInfo; |
23 | 23 | use Illuminate\Contracts\Container\Container; |
24 | 24 | use Cortex\Support\Events\InternalEventDispatcher; |
| 25 | +use OpenTelemetry\SDK\Common\Attribute\Attributes; |
| 26 | +use OpenTelemetry\SDK\Common\Util\ShutdownHandler; |
| 27 | +use OpenTelemetry\SDK\Trace\TracerProviderBuilder; |
| 28 | +use OpenTelemetry\SDK\Resource\ResourceInfoFactory; |
25 | 29 | use Spatie\LaravelPackageTools\PackageServiceProvider; |
26 | | -use Cortex\Support\Events\Subscribers\LoggingSubscriber; |
| 30 | +use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory; |
| 31 | +use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor; |
| 32 | +use Cortex\Support\Events\Subscribers\Otel\OpenTelemetrySubscriber; |
27 | 33 |
|
28 | 34 | class CortexServiceProvider extends PackageServiceProvider |
29 | 35 | { |
@@ -55,6 +61,7 @@ public function packageBooted(): void |
55 | 61 | $this->registerBladeDirectives(); |
56 | 62 |
|
57 | 63 | $this->setupLogging(); |
| 64 | + $this->setupTracing(); |
58 | 65 | } |
59 | 66 |
|
60 | 67 | protected function registerBladeDirectives(): void |
@@ -163,12 +170,67 @@ protected function setupLogging(): void |
163 | 170 | } |
164 | 171 |
|
165 | 172 | // TODO: This will be configurable. |
166 | | - $logger = new Logger('cortex'); |
167 | | - $handler = new StreamHandler('php://stdout'); |
168 | | - $handler->setFormatter(new LineFormatter()); |
| 173 | + // $logger = new Logger('cortex'); |
| 174 | + // $handler = new StreamHandler('php://stdout'); |
| 175 | + // $handler->setFormatter(new LineFormatter()); |
169 | 176 |
|
170 | | - $logger->pushHandler($handler); |
| 177 | + // $logger->pushHandler($handler); |
171 | 178 |
|
172 | | - InternalEventDispatcher::instance()->subscribe(new LoggingSubscriber($logger)); |
| 179 | + // InternalEventDispatcher::instance()->subscribe(new LoggingSubscriber($logger)); |
| 180 | + } |
| 181 | + |
| 182 | + protected function setupTracing(): void |
| 183 | + { |
| 184 | + if ($this->app->runningUnitTests()) { |
| 185 | + return; |
| 186 | + } |
| 187 | + |
| 188 | + if (! config('cortex.tracing.enabled', false)) { |
| 189 | + return; |
| 190 | + } |
| 191 | + |
| 192 | + $endpoint = (string) config('cortex.tracing.exporter.endpoint', 'http://localhost:4318/v1/traces'); |
| 193 | + $protocol = (string) config('cortex.tracing.exporter.protocol', Protocols::HTTP_PROTOBUF); |
| 194 | + $serviceName = (string) config('cortex.tracing.service_name', 'cortex'); |
| 195 | + $rawHeaders = config('cortex.tracing.exporter.headers', ''); |
| 196 | + $headers = []; |
| 197 | + |
| 198 | + foreach (explode(',', $rawHeaders) as $header) { |
| 199 | + $header = trim($header); |
| 200 | + |
| 201 | + if ($header === '') { |
| 202 | + continue; |
| 203 | + } |
| 204 | + |
| 205 | + $parts = explode('=', $header, 2); |
| 206 | + |
| 207 | + if (count($parts) === 2) { |
| 208 | + [$key, $value] = $parts; |
| 209 | + $headers[trim($key)] = trim($value, " \t\n\r\0\x0B\"'"); |
| 210 | + } |
| 211 | + } |
| 212 | + |
| 213 | + $resource = ResourceInfoFactory::emptyResource()->merge( |
| 214 | + ResourceInfo::create(Attributes::create([ |
| 215 | + 'service.name' => $serviceName, |
| 216 | + ])), |
| 217 | + ); |
| 218 | + |
| 219 | + $transport = new OtlpHttpTransportFactory()->create( |
| 220 | + $endpoint, |
| 221 | + Protocols::contentType($protocol), |
| 222 | + $headers, |
| 223 | + ); |
| 224 | + |
| 225 | + $exporter = new SpanExporter($transport); |
| 226 | + |
| 227 | + $tracerProvider = new TracerProviderBuilder() |
| 228 | + ->addSpanProcessor(new SimpleSpanProcessor($exporter)) |
| 229 | + ->setResource($resource) |
| 230 | + ->build(); |
| 231 | + |
| 232 | + ShutdownHandler::register($tracerProvider->shutdown(...)); |
| 233 | + |
| 234 | + InternalEventDispatcher::instance()->subscribe(new OpenTelemetrySubscriber($tracerProvider)); |
173 | 235 | } |
174 | 236 | } |
0 commit comments