Skip to content

Commit

Permalink
feat(laravel): adds laravel instrumentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
jcchavezs committed Jul 30, 2020
1 parent fee676f commit c4c3506
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 1 deletion.
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
"psr/http-server-middleware": "^1.0",
"middlewares/fast-route": "^1.2.1",
"middlewares/request-handler": "^1.4.0",
"squizlabs/php_codesniffer": "3.*"
"squizlabs/php_codesniffer": "3.*",
"illuminate/http": "^7.20",
"illuminate/routing": "^7.20"
},
"config": {
"sort-packages": true
Expand Down
107 changes: 107 additions & 0 deletions src/Zipkin/Instrumentation/Laravel/Middleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

declare(strict_types=1);

namespace Zipkin\Instrumentation\Laravel;

use Zipkin\Tracing;
use Zipkin\Tracer;
use Zipkin\SpanCustomizerShield;
use Zipkin\Span;
use Zipkin\Propagation\TraceContext;
use Zipkin\Propagation\SamplingFlags;
use Zipkin\Propagation\DefaultSamplingFlags;
use Zipkin\Kind;
use Zipkin\Instrumentation\Laravel\Propagation\RequestHeaders;
use Zipkin\Instrumentation\Http\Server\HttpServerTracing;
use Throwable;
use Illuminate\Http\Request;
use Closure;

class Middleware
{
/**
* @var Tracer
*/
private $tracer;

/**
* @var callable(array):?bool
*/
private $extractor;

/**
* @var Parser
*/
private $parser;

/**
* @var (callable(Request):?bool)|null
*/
private $requestSampler;

public function __construct(HttpServerTracing $tracing)
{
$this->tracer = $tracing->getTracing()->getTracer();
$this->extractor = $tracing->getTracing()->getPropagation()->getExtractor(new RequestHeaders());
$this->parser = $tracing->getParser();
$this->requestSampler = $tracing->getRequestSampler();
}

public static function createFromTracing(Tracing $tracing): self
{
return new self(new HttpServerTracing($tracing, new DefaultParser));
}

public function handle(Request $request, Closure $next)
{
$extractedContext = ($this->extractor)($request);

$span = $this->nextSpan($extractedContext, $request);
$scopeCloser = $this->tracer->openScope($span);

if ($span->isNoop()) {
try {
return $next($request);
} finally {
$span->finish();
$scopeCloser();
}
}

$span->setKind(Kind\SERVER);
$spanCustomizer = new SpanCustomizerShield($span);
$span->setName($this->parser->spanName($request));
$this->parser->request($request, $span->getContext(), $spanCustomizer);

try {
$response = $next($request);
$this->parser->response($response, $span->getContext(), $spanCustomizer);
return $response;
} catch (Throwable $e) {
$span->setError($e);
throw $e;
} finally {
$span->finish();
$scopeCloser();
}
}

private function nextSpan(?SamplingFlags $extractedContext, Request $request): Span
{
if ($extractedContext instanceof TraceContext) {
return $this->tracer->joinSpan($extractedContext);
}

$extractedContext = $extractedContext ?? DefaultSamplingFlags::createAsEmpty();
if ($this->requestSampler === null) {
return $this->tracer->nextSpan($extractedContext);
}

return $this->tracer->nextSpanWithSampler(
$this->requestSampler,
[$request],
$extractedContext
);
}
}
21 changes: 21 additions & 0 deletions src/Zipkin/Instrumentation/Laravel/Propagation/RequestHeaders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Zipkin\Instrumentation\Laravel\Propagation;

use Zipkin\Propagation\Getter;
use Illuminate\Http\Request;

final class RequestHeaders implements Getter
{
/**
* {@inheritdoc}
*
* @param Request $carrier
*/
public function get($carrier, string $key): ?string
{
return $carrier->hasHeader($key) ? $carrier->header($key)[0] : null;
}
}
55 changes: 55 additions & 0 deletions src/Zipkin/Instrumentation/Laravel/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace ZipkinBundle;

use Zipkin\Instrumentation\Http\Server\Request as ServerRequest;
use Illuminate\Http\Request as IlluminateHttpRequest;

class Request extends ServerRequest
{
/**
* @var IlluminateHttpRequest
*/
private $delegate;

private $route;

public function __construct(IlluminateHttpRequest $delegate)
{
$this->delegate = $delegate;
}

public function getMethod(): string
{
return $this->delegate->getMethod();
}

public function getPath(): ?string
{
return $this->delegate->getPathInfo() ?: '/';
}

public function getUrl(): string
{
return $this->delegate->getUri();
}

public function getHeader(string $name): string
{
return $this->delegate->headers->get($name);
}

/**
* @return IlluminateHttpRequest
*/
public function unwrap()
{
return $this->delegate;
}

public function getRoute(): ?string
{

return $this->delegate->route()->uri;
}
}
33 changes: 33 additions & 0 deletions src/Zipkin/Instrumentation/Laravel/Response.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace ZipkinBundle;

use Zipkin\Instrumentation\Http\Server\Response as ServerResponse;
use Symfony\Component\HttpFoundation\Response as HttpFoundationResponse;
use Symfony\Component\HttpFoundation\Request as HttpFoundationRequest;

class Response extends ServerResponse
{
/**
* @var HttpFoundationResponse
*/
private $delegate;

public function __construct(HttpFoundationResponse $delegate)
{
$this->delegate = $delegate;
}

public function getStatusCode(): int
{
return $this->delegate->getStatusCode();
}

/**
* @return HttpFoundationRequest
*/
public function unwrap()
{
return $this->delegate;
}
}
72 changes: 72 additions & 0 deletions src/Zipkin/Instrumentation/PDO/PDO.php_
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace Zipkin\Instrumentation\PDO;

use \PDO as StdPDO;
use PDOStatement;
use Zipkin\Tracer;

class PDO extends StdPDO
{
public function __construct(PDO $delegate, Tracer $tracer)
{
$this->delegate = $delegate;
$this->tracer = $tracer;
}

public function beginTransaction()
{
return $this->delegate->beginTransaction();
}

public function commit()
{
return $this->delegate->commit();
}
public function errorCode()
{
return $this->delegate->errorCode();
}
public function errorInfo()
{
return $this->delegate->errorInfo();
}
public function exec($statement)
{
return $this->delegate->exec($statement);
}
public function getAttribute($attribute)
{
return $this->delegate->getAttribute($attribute);
}
public function inTransaction()
{
return $this->delegate->inTransaction();
}
public function lastInsertId($name = null)
{
return $this->delegate->lastInsertId();
}

/**
* @return PDOStatement
*/
public function prepare($statement, array $driver_options = [])
{
return $this->delegate->prepare($statement, $driver_options);
}
public function query($statement)
{
return $this->delegate->query($statement);
}
public function quote($string, $parameter_type = PDO::PARAM_STR)
{
return $this->delegate->quote($string, $parameter_type);
}
public function rollBack(): bool
{
}
public function setAttribute(int $attribute, $value): bool
{
}
}

0 comments on commit c4c3506

Please sign in to comment.