Passed
Pull Request — master (#3)
by
unknown
12:46
created

anonymous//src/JaravelServiceProvider.php$0   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 11
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 1
c 2
b 1
f 0
dl 0
loc 11
rs 10
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\Facades\Log;
14
use Illuminate\Support\ServiceProvider;
15
use Jaeger;
16
use Jaeger\Config;
17
use Jaeger\Reporter\InMemoryReporter;
18
use Jaeger\Sampler\ConstSampler;
19
use Jaeger\ScopeManager;
20
use OpenTracing\GlobalTracer;
21
use OpenTracing\Tracer;
22
use Umbrellio\Jaravel\Listeners\ConsoleCommandFinishedListener;
23
use Umbrellio\Jaravel\Listeners\ConsoleCommandStartedListener;
24
use Umbrellio\Jaravel\Services\ConsoleCommandFilter;
25
use Umbrellio\Jaravel\Services\Job\JobWithTracingInjectionDispatcher;
26
27
class JaravelServiceProvider extends ServiceProvider
28
{
29
    public function boot()
30
    {
31
        $config = __DIR__ . '/config/jaravel.php';
32
33
        $this->publishes([
34
            $config => base_path('config/jaravel.php'),
35
        ], 'config');
36
37
        if (!ConfigRepository::get('jaravel.enabled', false)) {
38
            $this->configureFakeTracer();
39
40
            return;
41
        }
42
43
        $this->configureTracer();
44
45
        $this->listenLogs();
46
        $this->listenConsoleEvents();
47
        $this->extendJobsDispatcher();
48
    }
49
50
    public function configureFakeTracer(): void
51
    {
52
        $tracer = new class(
53
            'fake-tracer',
54
            new InMemoryReporter(),
55
            new ConstSampler(),
56
            true,
57
            null,
58
            new ScopeManager()) extends \Jaeger\Tracer {
59
60
            protected function getHostName()
61
            {
62
                return null;
63
            }
64
        };
65
66
        $this->app->instance(Tracer::class, $tracer);
67
    }
68
69
    public function extendJobsDispatcher(): void
70
    {
71
        $dispatcher = $this->app->make(Dispatcher::class);
72
        $this->app->extend(Dispatcher::class, function () use ($dispatcher) {
73
            return $this->app->make(JobWithTracingInjectionDispatcher::class, [
74
                'dispatcher' => $dispatcher,
75
            ]);
76
        });
77
    }
78
79
    private function configureTracer(): void
80
    {
81
        if ($tracerCallable = ConfigRepository::get('jaravel.custom_tracer_callable', null)) {
82
            $this->app->singleton(Tracer::class, $tracerCallable);
83
84
            return;
85
        }
86
87
        $config = new Config(
88
            [
89
                'sampler' => [
90
                    'type' => Jaeger\SAMPLER_TYPE_CONST,
91
                    'param' => true,
92
                ],
93
                'logging' => true,
94
                "local_agent" => [
95
                    "reporting_host" => ConfigRepository::get('jaravel.agent_host', '127.0.0.1'),
96
                    "reporting_port" => 6832,
97
                ],
98
                'trace_id_header' => ConfigRepository::get('jaravel.trace_id_header', 'X-Trace-Id'),
99
                'dispatch_mode' => Config::JAEGER_OVER_BINARY_UDP,
100
            ],
101
            ConfigRepository::get('jaravel.tracer_name', 'application')
102
        );
103
104
        $config->initializeTracer();
105
106
        $tracer = GlobalTracer::get();
107
108
        $this->app->instance(Tracer::class, $tracer);
109
    }
110
111
    private function listenLogs(): void
112
    {
113
        if (!ConfigRepository::get('jaravel.logs_enabled', true)) {
114
            return;
115
        }
116
117
        Event::listen(MessageLogged::class, function (MessageLogged $e) {
118
            $span = $this->app->make(Tracer::class)->getActiveSpan();
119
            if (!$span) {
120
                return;
121
            }
122
123
            $span->log([
124
                'message' => $e->message,
125
                'context' => $e->context,
126
                'level' => $e->level,
127
            ]);
128
        });
129
    }
130
131
    private function listenConsoleEvents(): void
132
    {
133
        if (!$this->app->runningInConsole()) {
134
            return;
135
        }
136
137
        /** @var ConsoleCommandFilter $filter */
138
        $filter = $this->app->make(ConsoleCommandFilter::class);
139
140
        if (!$filter->allow()) {
141
            return;
142
        }
143
144
        Event::listen(
145
            CommandStarting::class,
146
            ConfigRepository::get('jaravel.console.listeners.started', ConsoleCommandStartedListener::class)
147
        );
148
149
        Event::listen(
150
            CommandFinished::class,
151
            ConfigRepository::get('jaravel.console.listeners.finished', ConsoleCommandFinishedListener::class)
152
        );
153
    }
154
}
155