Skip to content

Commit 9992837

Browse files
authored
Curl instrumentation improvements (#423)
* Improved Curl instrumentation * Style fix
1 parent 5c4ed14 commit 9992837

File tree

2 files changed

+59
-38
lines changed

2 files changed

+59
-38
lines changed

.github/dependabot.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ updates:
5757
# Maintain dependencies for all packages
5858
- package-ecosystem: "composer"
5959
directories:
60-
- "/examples/aws/AwsClientApp"
6160
- "/examples/instrumentation/Wordpress"
6261
- "/src/AutoInstrumentationInstaller"
6362
- "/src/Aws"
63+
- "/src/Aws/examples/AwsClientApp"
6464
- "/src/Context/Swoole"
6565
- "/src/Exporter/Instana"
6666
- "/src/Instrumentation/AwsSdk"
@@ -78,12 +78,13 @@ updates:
7878
- "/src/Instrumentation/MySqli"
7979
- "/src/Instrumentation/OpenAIPHP"
8080
- "/src/Instrumentation/PDO"
81-
- "/src/Instrumentation/Psr3"
82-
- "/src/Instrumentation/Psr6"
81+
- "/src/Instrumentation/PostgreSql"
8382
- "/src/Instrumentation/Psr14"
8483
- "/src/Instrumentation/Psr15"
8584
- "/src/Instrumentation/Psr16"
8685
- "/src/Instrumentation/Psr18"
86+
- "/src/Instrumentation/Psr3"
87+
- "/src/Instrumentation/Psr6"
8788
- "/src/Instrumentation/ReactPHP"
8889
- "/src/Instrumentation/Slim"
8990
- "/src/Instrumentation/Symfony"

src/Instrumentation/Curl/src/CurlInstrumentation.php

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use CurlHandle;
88
use CurlMultiHandle;
9+
use OpenTelemetry\API\Behavior\LogsMessagesTrait;
910
use OpenTelemetry\API\Globals;
1011
use OpenTelemetry\API\Instrumentation\CachedInstrumentation;
1112
use OpenTelemetry\API\Trace\Span;
@@ -21,11 +22,13 @@
2122

2223
class CurlInstrumentation
2324
{
25+
use LogsMessagesTrait;
26+
2427
public const NAME = 'curl';
2528

2629
public static function register(): void
2730
{
28-
/** @var WeakMap<CurlHandle, CurlHandleMetadata> */
31+
// @var WeakMap<CurlHandle, CurlHandleMetadata>
2932
$curlHandleToAttributes = new WeakMap();
3033

3134
/** @var WeakMap<CurlMultiHandle, array> $curlMultiToHandle
@@ -72,7 +75,12 @@ public static function register(): void
7275
return;
7376
}
7477

75-
/** @psalm-suppress PossiblyNullReference */
78+
if (!isset($curlHandleToAttributes[$params[0]])) {
79+
self::logDebug('Curl handle is not tracked', ['retVal' => $retVal, 'params' => $params]);
80+
81+
return;
82+
}
83+
7684
$curlHandleToAttributes[$params[0]]->updateFromCurlOption($params[1], $params[2]);
7785
}
7886
);
@@ -92,35 +100,37 @@ public static function register(): void
92100
return;
93101
}
94102

103+
if (!isset($curlHandleToAttributes[$params[0]])) {
104+
self::logDebug('Curl handle is not tracked', ['retVal' => $retVal, 'params' => $params]);
105+
106+
return;
107+
}
108+
95109
foreach ($params[1] as $option => $value) {
96110
/** @psalm-suppress PossiblyNullReference */
97111
$curlHandleToAttributes[$params[0]]->updateFromCurlOption($option, $value);
98112
}
99113
}
100114
);
101115

102-
hook(
103-
null,
104-
'curl_close',
105-
pre: static function ($obj, array $params) use ($curlHandleToAttributes) {
106-
if (count($params) > 0 && $params[0] instanceof CurlHandle) {
107-
$curlHandleToAttributes->offsetUnset($params[0]);
108-
}
109-
},
110-
post: null
111-
);
112-
113116
hook(
114117
null,
115118
'curl_copy_handle',
116119
pre: null,
117120
post: static function ($obj, array $params, mixed $retVal) use ($curlHandleToAttributes) {
118-
if ($params[0] instanceof CurlHandle && $retVal instanceof CurlHandle) {
119-
/** @psalm-suppress PossiblyNullReference
120-
* @psalm-suppress PossiblyNullArgument
121-
*/
122-
$curlHandleToAttributes[$retVal] = $curlHandleToAttributes[$params[0]];
121+
if (!($params[0] instanceof CurlHandle && $retVal instanceof CurlHandle)) {
122+
self::logDebug('curl_copy_handle', ['retVal' => $retVal, 'params' => $params]);
123+
124+
return;
125+
}
126+
127+
if (!isset($curlHandleToAttributes[$params[0]])) {
128+
self::logDebug('curl_copy_handle. Handle is not tracked', ['retVal' => $retVal, 'params' => $params]);
129+
130+
return;
123131
}
132+
133+
$curlHandleToAttributes[$retVal] = $curlHandleToAttributes[$params[0]];
124134
}
125135
);
126136

@@ -143,51 +153,58 @@ public static function register(): void
143153
return;
144154
}
145155

146-
/** @psalm-suppress PossiblyNullReference */
147-
$spanName = $curlHandleToAttributes[$params[0]]->getAttributes()[TraceAttributes::HTTP_REQUEST_METHOD] ?? 'curl_exec';
156+
$spanName = 'curl_exec';
157+
$attributes = [];
158+
159+
if (isset($curlHandleToAttributes[$params[0]])) {
160+
$attributes = $curlHandleToAttributes[$params[0]]->getAttributes();
161+
$spanName = $attributes[TraceAttributes::HTTP_REQUEST_METHOD] ?? $spanName;
162+
} else {
163+
self::logDebug('Curl handle is not tracked', ['params' => $params]);
164+
}
148165

149166
$propagator = Globals::propagator();
150167
$parent = Context::getCurrent();
151168

152-
/** @psalm-suppress PossiblyNullReference */
153169
$builder = $instrumentation->tracer()
154170
->spanBuilder($spanName)
155171
->setParent($parent)
156172
->setSpanKind(SpanKind::KIND_CLIENT)
157173
->setAttribute(TraceAttributes::CODE_FUNCTION_NAME, $function)
158174
->setAttribute(TraceAttributes::CODE_FILE_PATH, $filename)
159175
->setAttribute(TraceAttributes::CODE_LINE_NUMBER, $lineno)
160-
->setAttributes($curlHandleToAttributes[$params[0]]->getAttributes());
176+
->setAttributes($attributes);
161177

162178
$span = $builder->startSpan();
163179
$context = $span->storeInContext($parent);
164-
$propagator->inject($curlHandleToAttributes[$params[0]], HeadersPropagator::instance(), $context);
180+
if (isset($curlHandleToAttributes[$params[0]])) {
181+
$propagator->inject($curlHandleToAttributes[$params[0]], HeadersPropagator::instance(), $context);
182+
}
165183

166184
Context::storage()->attach($context);
167185

168-
$curlSetOptInstrumentationSuppressed = true;
186+
if (!isset($curlHandleToAttributes[$params[0]])) {
187+
return;
188+
}
169189

170-
/** @psalm-suppress PossiblyNullReference */
190+
$curlSetOptInstrumentationSuppressed = true;
171191
$headers = $curlHandleToAttributes[$params[0]]->getRequestHeadersToSend();
172192
if ($headers) {
173193
curl_setopt($params[0], CURLOPT_HTTPHEADER, $headers);
174194
}
175195

176196
if (self::isResponseHeadersCapturingEnabled()) {
177-
/** @psalm-suppress PossiblyNullReference */
178197
curl_setopt($params[0], CURLOPT_HEADERFUNCTION, $curlHandleToAttributes[$params[0]]->getResponseHeaderCaptureFunction());
179198
}
180199

181200
if (self::isRequestHeadersCapturingEnabled()) {
182-
/** @psalm-suppress PossiblyNullReference */
183201
if (!$curlHandleToAttributes[$params[0]]->isVerboseEnabled()) { // we let go of captuing request headers because CURLINFO_HEADER_OUT is disabling CURLOPT_VERBOSE
184202
curl_setopt($params[0], CURLINFO_HEADER_OUT, true);
203+
} else {
204+
self::logDebug('Request headers won\'t be captured because verbose mode is disabled', ['params' => $params]);
185205
}
186-
//TODO log?
187-
188206
}
189207
$curlSetOptInstrumentationSuppressed = false;
190-
191208
},
192209
post: static function ($obj, array $params, mixed $retVal) use ($curlHandleToAttributes) {
193210
if (!($params[0] instanceof CurlHandle)) {
@@ -213,12 +230,15 @@ public static function register(): void
213230
$span->setAttribute(TraceAttributes::ERROR_TYPE, 'cURL error (' . $errno . ')');
214231
}
215232

216-
/** @psalm-suppress PossiblyNullReference */
217-
$capturedHeaders = $curlHandleToAttributes[$params[0]]->getCapturedResponseHeaders();
218-
foreach (self::getResponseHeadersToCapture() as $headerToCapture) {
219-
if (($value = $capturedHeaders[strtolower($headerToCapture)] ?? null) != null) {
220-
$span->setAttribute(sprintf('http.response.header.%s', strtolower(string: $headerToCapture)), $value);
233+
if (isset($curlHandleToAttributes[$params[0]])) {
234+
$capturedHeaders = $curlHandleToAttributes[$params[0]]->getCapturedResponseHeaders();
235+
foreach (self::getResponseHeadersToCapture() as $headerToCapture) {
236+
if (($value = $capturedHeaders[strtolower($headerToCapture)] ?? null) != null) {
237+
$span->setAttribute(sprintf('http.response.header.%s', strtolower(string: $headerToCapture)), $value);
238+
}
221239
}
240+
} else {
241+
self::logDebug('Curl handle is not tracked', ['params' => $params]);
222242
}
223243

224244
$span->end();

0 commit comments

Comments
 (0)