forked from open-telemetry/opentelemetry-demo
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add PHP quote service (open-telemetry#345)
- Loading branch information
Juliano Costa
authored
Sep 14, 2022
1 parent
81627c0
commit 880ac1f
Showing
18 changed files
with
366 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.dockerignore | ||
.idea | ||
Dockerfile | ||
vendor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.idea/ | ||
.vscode/ | ||
/coverage/ | ||
/vendor/ | ||
/logs/* | ||
!/logs/README.md | ||
.phpunit.result.cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
FROM composer:2.4.1 AS build | ||
|
||
WORKDIR /tmp/ | ||
COPY ./src/quoteservice/composer.json . | ||
|
||
RUN composer install \ | ||
--ignore-platform-reqs \ | ||
--no-interaction \ | ||
--no-plugins \ | ||
--no-scripts \ | ||
--prefer-dist | ||
|
||
FROM php:8.1-cli | ||
|
||
# install GRPC (required for the OTel exporter) | ||
RUN apt-get -y update && apt install -y --no-install-recommends zlib1g-dev && \ | ||
pecl install grpc protobuf && \ | ||
docker-php-ext-enable grpc protobuf | ||
|
||
WORKDIR /var/www | ||
COPY --from=build /tmp/vendor/ /var/www/vendor/ | ||
COPY ./src/quoteservice/ /var/www | ||
|
||
EXPOSE ${QUOTE_SERVICE_PORT} | ||
|
||
ENTRYPOINT php -S 0.0.0.0:${QUOTE_SERVICE_PORT} -t public |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Quote Service | ||
|
||
The Quote Service calculates the shipping costs, | ||
based on the number of items to be shipped. | ||
|
||
It is a PHP based service. | ||
|
||
## Build the service | ||
|
||
To build the quote service, run the following from root directory | ||
of opentelemetry-demo | ||
|
||
```sh | ||
docker compose build quoteservice | ||
``` | ||
|
||
## Run the service | ||
|
||
Execute the below command to run the service. | ||
|
||
```sh | ||
docker compose up quoteservice | ||
``` | ||
|
||
In order to get traffic into the service you have to deploy | ||
the whole opentelemetry-demo. | ||
|
||
Please follow the root README to do so. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
use App\Application\Settings\SettingsInterface; | ||
use DI\ContainerBuilder; | ||
use Monolog\Handler\StreamHandler; | ||
use Monolog\Logger; | ||
use Monolog\Processor\UidProcessor; | ||
use Psr\Container\ContainerInterface; | ||
use Psr\Log\LoggerInterface; | ||
|
||
return function (ContainerBuilder $containerBuilder) { | ||
$containerBuilder->addDefinitions([ | ||
LoggerInterface::class => function (ContainerInterface $c) { | ||
$settings = $c->get(SettingsInterface::class); | ||
|
||
$loggerSettings = $settings->get('logger'); | ||
$logger = new Logger($loggerSettings['name']); | ||
|
||
$processor = new UidProcessor(); | ||
$logger->pushProcessor($processor); | ||
|
||
$handler = new StreamHandler($loggerSettings['path'], $loggerSettings['level']); | ||
$logger->pushHandler($handler); | ||
|
||
return $logger; | ||
}, | ||
]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
use OpenTelemetry\API\Trace\AbstractSpan; | ||
use OpenTelemetry\API\Trace\SpanKind; | ||
use OpenTelemetry\SDK\Trace\Tracer; | ||
use Psr\Http\Message\ResponseInterface as Response; | ||
use Psr\Http\Message\ServerRequestInterface as Request; | ||
use Slim\App; | ||
|
||
function calculateQuote($jsonObject, Tracer $tracer): float | ||
{ | ||
$quote = 0.0; | ||
$childSpan = $tracer | ||
->spanBuilder('calculate-quote') | ||
->setSpanKind(SpanKind::KIND_INTERNAL) | ||
->startSpan(); | ||
$childSpan->addEvent('Calculating quote'); | ||
|
||
try { | ||
$numberOfItems = intval($jsonObject['numberOfItems']); | ||
$quote = 8.90 * $numberOfItems; | ||
|
||
$childSpan->setAttribute('app.quote.items.count', $numberOfItems); | ||
$childSpan->setAttribute('app.quote.cost.total', $quote); | ||
|
||
$childSpan->addEvent('Quote calculated, returning its value'); | ||
} catch (\Exception $exception) { | ||
$childSpan->recordException($exception); | ||
} finally { | ||
$childSpan->end(); | ||
return $quote; | ||
} | ||
} | ||
|
||
return function (App $app) { | ||
$app->post('/getquote', function (Request $request, Response $response, Tracer $tracer) { | ||
$span = AbstractSpan::getCurrent(); | ||
$span->addEvent('Received get quote request, processing it'); | ||
|
||
$body = $request->getBody()->getContents(); | ||
$jsonObject = json_decode($body, true); | ||
|
||
$data = calculateQuote($jsonObject, $tracer); | ||
|
||
$payload = json_encode($data); | ||
$response->getBody()->write($payload); | ||
|
||
$span->addEvent('Quote processed, response sent back'); | ||
|
||
return $response | ||
->withHeader('Content-Type', 'application/json'); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
use App\Application\Settings\Settings; | ||
use App\Application\Settings\SettingsInterface; | ||
use DI\ContainerBuilder; | ||
use Monolog\Logger; | ||
|
||
return function (ContainerBuilder $containerBuilder) { | ||
// Global Settings Object | ||
$containerBuilder->addDefinitions([ | ||
SettingsInterface::class => function () { | ||
return new Settings([ | ||
'displayErrorDetails' => true, // Should be set to false in production | ||
'logError' => false, | ||
'logErrorDetails' => false, | ||
'logger' => [ | ||
'name' => 'slim-app', | ||
'path' => 'php://stdout', | ||
'level' => Logger::DEBUG, | ||
], | ||
]); | ||
} | ||
]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"name": "openteletry-demo/quoteservice", | ||
"description": "Quote Service part of OpenTelemetry Demo", | ||
"license": "Apache-2.0", | ||
"require": { | ||
"php": "7.4 || 8.1", | ||
"ext-json": "dev-main", | ||
"monolog/monolog": "2.8.0", | ||
"open-telemetry/opentelemetry": "0.0.15", | ||
"guzzlehttp/guzzle": "7.4.5", | ||
"php-di/php-di": "6.4.0", | ||
"php-di/slim-bridge": "3.2.0", | ||
"php-http/guzzle7-adapter": "1.0.0", | ||
"slim/psr7": "1.5", | ||
"slim/slim": "4.10.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"App\\": "src/" | ||
} | ||
}, | ||
"scripts": { | ||
"start": "php -S 0.0.0.0:${QUOTE_SERVICE_PORT} -t public", | ||
"test": "phpunit" | ||
}, | ||
"config": { | ||
"allow-plugins": { | ||
"phpstan/extension-installer": true | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
use DI\Bridge\Slim\Bridge; | ||
use DI\ContainerBuilder; | ||
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator; | ||
use OpenTelemetry\API\Trace\SpanKind; | ||
use OpenTelemetry\API\Trace\StatusCode; | ||
use OpenTelemetry\SDK\Trace\Tracer; | ||
use OpenTelemetry\SDK\Trace\TracerProviderFactory; | ||
use OpenTelemetry\SDK\Common\Util\ShutdownHandler; | ||
use Psr\Http\Message\ServerRequestInterface as Request; | ||
use Psr\Http\Server\RequestHandlerInterface as RequestHandler; | ||
use Slim\Factory\AppFactory; | ||
use Slim\Factory\ServerRequestCreatorFactory; | ||
use Slim\Routing\RouteContext; | ||
|
||
require __DIR__ . '/../vendor/autoload.php'; | ||
|
||
// Instantiate PHP-DI ContainerBuilder | ||
$containerBuilder = new ContainerBuilder(); | ||
|
||
// Set up settings | ||
$settings = require __DIR__ . '/../app/settings.php'; | ||
$settings($containerBuilder); | ||
|
||
// Set up dependencies | ||
$dependencies = require __DIR__ . '/../app/dependencies.php'; | ||
$dependencies($containerBuilder); | ||
|
||
// Add OTel | ||
$tracerProvider = (new TracerProviderFactory('quoteservice'))->create(); | ||
ShutdownHandler::register([$tracerProvider, 'shutdown']); | ||
$tracer = $tracerProvider->getTracer('io.opentelemetry.contrib.php'); | ||
|
||
$containerBuilder->addDefinitions([ | ||
Tracer::class => $tracer | ||
]); | ||
|
||
// Build PHP-DI Container instance | ||
$container = $containerBuilder->build(); | ||
|
||
// Instantiate the app | ||
AppFactory::setContainer($container); | ||
$app = Bridge::create($container); | ||
|
||
// Register middleware | ||
//middleware starts root span based on route pattern, sets status from http code | ||
$app->add(function (Request $request, RequestHandler $handler) use ($tracer) { | ||
$parent = TraceContextPropagator::getInstance()->extract($request->getHeaders()); | ||
$routeContext = RouteContext::fromRequest($request); | ||
$route = $routeContext->getRoute(); | ||
$root = $tracer->spanBuilder($route->getPattern()) | ||
->setStartTimestamp((int) ($request->getServerParams()['REQUEST_TIME_FLOAT'] * 1e9)) | ||
->setParent($parent) | ||
->setSpanKind(SpanKind::KIND_SERVER) | ||
->startSpan(); | ||
$scope = $root->activate(); | ||
|
||
try { | ||
$response = $handler->handle($request); | ||
$root->setStatus($response->getStatusCode() < 500 ? StatusCode::STATUS_OK : StatusCode::STATUS_ERROR); | ||
} finally { | ||
$root->end(); | ||
$scope->detach(); | ||
} | ||
|
||
return $response; | ||
}); | ||
$app->addRoutingMiddleware(); | ||
|
||
// Register routes | ||
$routes = require __DIR__ . '/../app/routes.php'; | ||
$routes($app); | ||
|
||
// Create Request object from globals | ||
$serverRequestCreator = ServerRequestCreatorFactory::create(); | ||
$request = $serverRequestCreator->createServerRequestFromGlobals(); | ||
|
||
// Add Body Parsing Middleware | ||
$app->addBodyParsingMiddleware(); | ||
|
||
// Add Error Middleware | ||
$errorMiddleware = $app->addErrorMiddleware(true, true, true); | ||
|
||
// Run App | ||
$app->run(); | ||
$tracerProvider->shutdown(); |
Oops, something went wrong.