8
8
use OpenTelemetry \API \Trace \TracerProviderInterface ;
9
9
use OpenTelemetry \API \Logs \LoggerProviderInterface ;
10
10
use OpenTelemetry \API \Metrics \MeterProviderInterface ;
11
+ use OpenTelemetry \SDK \Common \Export \Http \PsrTransportFactory ;
11
12
use OpenTelemetry \SDK \Trace \TracerProvider ;
12
13
use OpenTelemetry \SDK \Logs \LoggerProvider ;
13
14
use OpenTelemetry \SDK \Metrics \MeterProvider ;
14
15
use OpenTelemetry \SDK \Trace \SpanProcessor \SimpleSpanProcessor ;
15
16
use OpenTelemetry \SDK \Logs \Processor \SimpleLogRecordProcessor as LogProcessor ;
16
- use OpenTelemetry \Contrib \Otlp \OtlpHttpTransportFactory ;
17
17
use OpenTelemetry \Contrib \Otlp \SpanExporter ;
18
18
use OpenTelemetry \Contrib \Otlp \LogsExporter ;
19
19
use OpenTelemetry \Contrib \Otlp \MetricExporter ;
24
24
use OpenTelemetry \SemConv \ResourceAttributes ;
25
25
use OpenTelemetry \SDK \Metrics \Data \Temporality ;
26
26
use Illuminate \Support \Facades \Log ;
27
+ use Illuminate \Http \Client \Factory as LaravelHttpFactory ;
28
+ use GuzzleHttp \Psr7 \HttpFactory as GuzzleHttpFactory ;
29
+ use OpenTelemetry \SDK \Common \Export \TransportFactoryInterface ;
30
+ use Illuminate \Support \Facades \Http ;
31
+ use Psr \Http \Client \ClientInterface ;
32
+ use Psr \Http \Message \RequestFactoryInterface ;
33
+ use Psr \Http \Message \StreamFactoryInterface ;
27
34
28
35
class LaravelApmServiceProvider extends ServiceProvider
29
36
{
37
+
38
+ private $ contentType ;
39
+ private $ headers ;
40
+
41
+ private $ endpoint ;
42
+
30
43
public function register ()
31
44
{
45
+ $ this ->endpoint = config ('laravel-apm.endpoint ' );
46
+ $ this ->contentType = config ('laravel-apm.content_type ' );
47
+ $ this ->headers = config ('laravel-apm.headers ' );
48
+
32
49
$ this ->mergeConfigFrom (__DIR__ . '/../config/laravel-apm.php ' , 'laravel-apm ' );
33
50
34
51
$ this ->app ->singleton (ExportingReader::class, function ($ app ) {
35
- $ endpoint = config ('laravel-apm.endpoint ' ) . '/v1/metrics ' ;
36
- $ contentType = config ('laravel-apm.content_type ' );
37
- $ headers = config ('laravel-apm.headers ' );
52
+ $ transportFactory = $ this ->getTransportFactory ();
38
53
39
- $ transport = ( new OtlpHttpTransportFactory ()) ->create ($ endpoint , $ contentType , $ headers );
54
+ $ transport = $ transportFactory ->create ($ this -> endpoint . ' /v1/metrics ' , $ this -> contentType , $ this -> headers );
40
55
41
- $ exporter = new MetricExporter ($ transport , [
42
- 'counter ' => Temporality::CUMULATIVE ,
43
- 'observable_counter ' => Temporality::CUMULATIVE ,
44
- 'histogram ' => Temporality::DELTA ,
45
- 'observable_gauge ' => Temporality::DELTA ,
46
- ]);
56
+ $ exporter = new MetricExporter ($ transport , Temporality::CUMULATIVE );
47
57
48
58
return new ExportingReader ($ exporter );
49
59
});
@@ -106,12 +116,12 @@ public function boot()
106
116
107
117
private function createTracerProvider ()
108
118
{
109
- $ endpoint = config ( ' laravel-apm.endpoint ' ) . ' /v1/traces ' ;
110
- $ contentType = config ( ' laravel-apm.content_type ' );
111
- $ headers = config ( ' laravel-apm.headers ' );
119
+ $ transportFactory = $ this -> getTransportFactory () ;
120
+
121
+ $ transport = $ transportFactory -> create ( $ this -> endpoint . ' /v1/traces ' , $ this -> contentType , $ this -> headers );
112
122
113
- $ transport = (new OtlpHttpTransportFactory ())->create ($ endpoint , $ contentType , $ headers );
114
123
$ exporter = new SpanExporter ($ transport );
124
+
115
125
$ spanProcessor = new SimpleSpanProcessor ($ exporter );
116
126
117
127
return TracerProvider::builder ()
@@ -124,12 +134,12 @@ private function createTracerProvider()
124
134
125
135
private function createLoggerProvider ()
126
136
{
127
- $ transport = (new OtlpHttpTransportFactory ())->create (
128
- config ('laravel-apm.endpoint ' ) . '/v1/logs ' ,
129
- config ('laravel-apm.content_type ' ),
130
- config ('laravel-apm.headers ' )
131
- );
137
+ $ transportFactory = $ this ->getTransportFactory ();
138
+
139
+ $ transport = $ transportFactory ->create ($ this ->endpoint . '/v1/logs ' , $ this ->contentType , $ this ->headers );
140
+
132
141
$ exporter = new LogsExporter ($ transport );
142
+
133
143
return LoggerProvider::builder ()
134
144
->addLogRecordProcessor (new LogProcessor ($ exporter ))
135
145
->build ();
@@ -156,4 +166,38 @@ private function configureLogging()
156
166
$ otelHandler = new \OpenTelemetry \Contrib \Logs \Monolog \Handler ($ loggerProvider , 'debug ' );
157
167
Log::pushHandler ($ otelHandler );
158
168
}
169
+
170
+ protected function createHttpFactories (): array
171
+ {
172
+ // if (class_exists(LaravelHttpFactory::class)) {
173
+ // $factory = new LaravelHttpFactory();
174
+ // return [
175
+ // 'client' => $factory->buildClient(),
176
+ // 'requestFactory' => $factory,
177
+ // 'streamFactory' => $factory,
178
+ // ];
179
+ // }
180
+
181
+ if (class_exists (GuzzleHttpFactory::class)) {
182
+ $ factory = new GuzzleHttpFactory ();
183
+ return [
184
+ 'client ' => new \GuzzleHttp \Client (),
185
+ 'requestFactory ' => $ factory ,
186
+ 'streamFactory ' => $ factory ,
187
+ ];
188
+ }
189
+
190
+ throw new \RuntimeException ('No suitable HTTP factories found. Please install Guzzle or use Laravel 8.0+ ' );
191
+ }
192
+
193
+ private function getTransportFactory (): TransportFactoryInterface
194
+ {
195
+ $ factories = $ this ->createHttpFactories ();
196
+
197
+ return new PsrTransportFactory (
198
+ $ factories ['client ' ],
199
+ $ factories ['requestFactory ' ],
200
+ $ factories ['streamFactory ' ]
201
+ );
202
+ }
159
203
}
0 commit comments