JaravelServiceProvider::boot()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 19
rs 9.9
c 1
b 0
f 0
eloc 11
cc 2
nc 2
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Umbrellio\Jaravel;
6
7
use Illuminate\Console\Events\CommandFinished;
8
use Illuminate\Console\Events\CommandStarting;
9
use Illuminate\Contracts\Bus\Dispatcher;
10
use Illuminate\Log\Events\MessageLogged;
11
use Illuminate\Support\Facades\Config as ConfigRepository;
12
use Illuminate\Support\Facades\Event;
13
use Illuminate\Support\ServiceProvider;
14
use OpenTelemetry\API\Trace\NoopTracer;
15
use OpenTelemetry\API\Trace\TracerInterface;
16
use OpenTelemetry\Contrib\Jaeger\AgentExporter;
17
use OpenTelemetry\SDK\Common\Util\ShutdownHandler;
18
use OpenTelemetry\SDK\Trace\Span;
19
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
20
use OpenTelemetry\SDK\Trace\TracerProvider;
21
use Umbrellio\Jaravel\Listeners\ConsoleCommandFinishedListener;
22
use Umbrellio\Jaravel\Listeners\ConsoleCommandStartedListener;
23
use Umbrellio\Jaravel\Services\ConsoleCommandFilter;
24
use Umbrellio\Jaravel\Services\Job\JobWithTracingInjectionDispatcher;
25
26
class JaravelServiceProvider extends ServiceProvider
27
{
28
    public function boot()
29
    {
30
        $config = __DIR__ . '/config/jaravel.php';
31
32
        $this->publishes([
33
            $config => base_path('config/jaravel.php'),
34
        ], 'config');
35
36
        if (!ConfigRepository::get('jaravel.enabled', false)) {
37
            $this->configureFakeTracer();
38
39
            return;
40
        }
41
42
        $this->configureTracer();
43
44
        $this->listenLogs();
45
        $this->listenConsoleEvents();
46
        $this->extendJobsDispatcher();
47
    }
48
49
    public function configureFakeTracer(): void
50
    {
51
        $this->app->instance(TracerInterface::class, NoopTracer::getInstance());
52
    }
53
54
    public function extendJobsDispatcher(): void
55
    {
56
        $dispatcher = $this->app->make(Dispatcher::class);
57
        $this->app->extend(Dispatcher::class, function () use ($dispatcher) {
58
            return $this->app->make(JobWithTracingInjectionDispatcher::class, compact('dispatcher'));
59
        });
60
    }
61
62
    private function configureTracer(): void
63
    {
64
        if ($tracerCallable = ConfigRepository::get('jaravel.custom_tracer_callable', null)) {
65
            $this->app->singleton(TracerInterface::class, $tracerCallable);
66
67
            return;
68
        }
69
70
        $host = ConfigRepository::get('jaravel.agent_host', '127.0.0.1');
71
        $port = ConfigRepository::get('jaravel.agent_port', 6832);
72
        $tracerName = ConfigRepository::get('jaravel.tracer_name', 'application');
73
        $exporter = new AgentExporter($tracerName, "{$host}:{$port}");
74
75
        $tracerProvider = new TracerProvider(new SimpleSpanProcessor($exporter));
76
        ShutdownHandler::register([$tracerProvider, 'shutdown']);
77
        $tracer = $tracerProvider->getTracer($tracerName);
78
79
        $this->app->instance(TracerInterface::class, $tracer);
80
    }
81
82
    private function listenLogs(): void
83
    {
84
        if (!ConfigRepository::get('jaravel.logs_enabled', true)) {
85
            return;
86
        }
87
88
        Event::listen(MessageLogged::class, function (MessageLogged $e) {
89
            $span = Span::getCurrent();
90
91
            $span->addEvent('Log', [
92
                'message' => $e->message,
93
                'context' => $e->context,
94
                'level' => $e->level,
95
            ]);
96
        });
97
    }
98
99
    private function listenConsoleEvents(): void
100
    {
101
        if (!$this->app->runningInConsole()) {
102
            return;
103
        }
104
105
        /** @var ConsoleCommandFilter $filter */
106
        $filter = $this->app->make(ConsoleCommandFilter::class);
107
108
        if (!$filter->allow()) {
109
            return;
110
        }
111
112
        Event::listen(
113
            CommandStarting::class,
114
            ConfigRepository::get('jaravel.console.listeners.started', ConsoleCommandStartedListener::class)
115
        );
116
117
        Event::listen(
118
            CommandFinished::class,
119
            ConfigRepository::get('jaravel.console.listeners.finished', ConsoleCommandFinishedListener::class)
120
        );
121
    }
122
}
123