diff --git a/.docker/nginx.conf b/.docker/nginx.conf new file mode 100644 index 0000000..0bf0e5f --- /dev/null +++ b/.docker/nginx.conf @@ -0,0 +1,33 @@ +user nginx; +worker_processes 1; + +error_log /dev/stderr warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Detect if a client provides a X-Request-ID header (proxy before this), and pass it on to the backend + # server. If no such header is provided, it can provide a random value. + map $http_x_request_id $reqid { + default $http_x_request_id; + "" $request_id; + } + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for" "$reqid"'; + + access_log /dev/stdout main; + + sendfile on; + keepalive_timeout 65; + gzip on; + + include /etc/nginx/conf.d/*.conf; +} \ No newline at end of file diff --git a/.docker/vhost.conf b/.docker/vhost.conf index 288be9d..e8a266e 100644 --- a/.docker/vhost.conf +++ b/.docker/vhost.conf @@ -14,11 +14,6 @@ server { fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; - # optionally set the value of the environment variables used in the application - # fastcgi_param APP_ENV prod; - # fastcgi_param APP_SECRET ; - # fastcgi_param DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name"; - # When you are using symlinks to link the document root to the # current version of your application, you should pass the real # application path instead of the path to the symlink to PHP @@ -28,6 +23,7 @@ server { # for more information). fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $realpath_root; + fastcgi_param HTTP_X_REQUEST_ID $reqid; # Prevents URIs that include the front controller. This will 404: # http://domain.tld/index.php/some-path # Remove the internal directive to allow URIs like this @@ -39,7 +35,4 @@ server { location ~ \.php$ { return 404; } - - error_log /var/log/nginx/project_error.log; - access_log /var/log/nginx/project_access.log; } diff --git a/config/packages/dev/monolog.yaml b/config/packages/dev/monolog.yaml deleted file mode 100644 index b1998da..0000000 --- a/config/packages/dev/monolog.yaml +++ /dev/null @@ -1,19 +0,0 @@ -monolog: - handlers: - main: - type: stream - path: "%kernel.logs_dir%/%kernel.environment%.log" - level: debug - channels: ["!event"] - # uncomment to get logging in your browser - # you may have to allow bigger header sizes in your Web server configuration - #firephp: - # type: firephp - # level: info - #chromephp: - # type: chromephp - # level: info - console: - type: console - process_psr_3_messages: false - channels: ["!event", "!doctrine", "!console"] diff --git a/config/packages/monolog.yml b/config/packages/monolog.yml new file mode 100644 index 0000000..34505a9 --- /dev/null +++ b/config/packages/monolog.yml @@ -0,0 +1,10 @@ +services: + +monolog: + channels: ["information"] + handlers: + information: + type: stream + path: "php://stdout" + formatter: monolog.formatter.json + channels: ["information"] \ No newline at end of file diff --git a/config/packages/prod/monolog.yaml b/config/packages/prod/monolog.yaml deleted file mode 100644 index 148619b..0000000 --- a/config/packages/prod/monolog.yaml +++ /dev/null @@ -1,18 +0,0 @@ -monolog: - handlers: - main: - type: fingers_crossed - action_level: error - handler: nested - excluded_404s: - # regex: exclude all 404 errors from the logs - - ^/ - nested: - type: stream - path: "php://stdout" - level: error - - console: - type: console - process_psr_3_messages: false - channels: ["!event", "!doctrine"] diff --git a/config/services.yaml b/config/services.yaml index 59f1d98..13d0044 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -12,6 +12,7 @@ services: autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. bind: $bindCoverStoreRemoteURL: '%env(COVERSTORE_REMOTE_URL)%' + $bindTraceId: '%env(traceId:HTTP_X_REQUEST_ID)%' # makes classes in src/ available to be used as services # this creates a service per class whose id is the fully-qualified class name @@ -19,6 +20,13 @@ services: resource: '../src/*' exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' + monolog.formatter.json: + class: Monolog\Formatter\JsonFormatter + + App\Logger\TraceIdProcessor: + tags: + - { name: monolog.processor } + # controllers are imported separately to make sure services can be injected # as action arguments even if you don't extend any base controller class App\Controller\: diff --git a/docker-compose.yml b/docker-compose.yml index b69d426..8d81608 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -52,6 +52,7 @@ services: - '80' volumes: - ${PWD}/.docker/vhost.conf:/etc/nginx/conf.d/default.conf:ro + - ${PWD}/.docker/nginx.conf:/etc/nginx/nginx.conf:ro - ./:/app:delegated labels: - "traefik.enable=true" diff --git a/src/EnvVarProcessor/TraceIdEnvVarProcessor.php b/src/EnvVarProcessor/TraceIdEnvVarProcessor.php new file mode 100644 index 0000000..2398743 --- /dev/null +++ b/src/EnvVarProcessor/TraceIdEnvVarProcessor.php @@ -0,0 +1,53 @@ +generate(); + } + + return $this::$id; + } + + /** + * {@inheritdoc} + */ + public static function getProvidedTypes() + { + return [ + 'traceId' => 'string', + ]; + } + + /** + * Generate new unique id. + * + * @throws \Exception + */ + private function generate() { + $this::$id = bin2hex(random_bytes(16)); + } +} \ No newline at end of file diff --git a/src/EventSubscriber/MaterialPostWriteSubscriber.php b/src/EventSubscriber/MaterialPostWriteSubscriber.php index d8f00b3..9c33ab1 100644 --- a/src/EventSubscriber/MaterialPostWriteSubscriber.php +++ b/src/EventSubscriber/MaterialPostWriteSubscriber.php @@ -24,15 +24,18 @@ final class MaterialPostWriteSubscriber implements EventSubscriberInterface { private $bus; private $storage; + private $requestId; /** * MaterialPostWriteSubscriber constructor. * + * @param string $bindRequestId * @param MessageBusInterface $bus * @param StorageInterface $storage */ - public function __construct(MessageBusInterface $bus, StorageInterface $storage) + public function __construct(string $bindRequestId, MessageBusInterface $bus, StorageInterface $storage) { + $this->requestId = $bindRequestId; $this->bus = $bus; $this->storage = $storage; } @@ -79,6 +82,7 @@ public function materialPostWrite(ViewEvent $event) $message->setOperation(VendorState::INSERT); $message->setImageUrl($url); $message->setAccrediting($material->getAgencyId()); + $message->setRequestId($this->requestId); $this->bus->dispatch($message); break; } diff --git a/src/EventSubscriber/MaterialPreWriteSubscriber.php b/src/EventSubscriber/MaterialPreWriteSubscriber.php index 2c95468..e1487c4 100644 --- a/src/EventSubscriber/MaterialPreWriteSubscriber.php +++ b/src/EventSubscriber/MaterialPreWriteSubscriber.php @@ -26,6 +26,7 @@ final class MaterialPreWriteSubscriber implements EventSubscriberInterface { private $bus; private $storage; + private $requestId; /** @var User */ private $user; @@ -33,12 +34,14 @@ final class MaterialPreWriteSubscriber implements EventSubscriberInterface /** * MaterialPreWriteSubscriber constructor. * + * @param string $bindRequestId * @param MessageBusInterface $bus * @param StorageInterface $storage * @param Security $security */ - public function __construct(MessageBusInterface $bus, StorageInterface $storage, Security $security) + public function __construct(string $bindRequestId, MessageBusInterface $bus, StorageInterface $storage, Security $security) { + $this->requestId = $bindRequestId; $this->bus = $bus; $this->storage = $storage; @@ -79,6 +82,7 @@ public function materialPreWrite(ViewEvent $event) $message->setIdentifierType($item->getIsType()); $message->setIdentifier($item->getIsIdentifier()); $message->setOperation(VendorState::DELETE); + $message->setRequestId($this->requestId); $this->bus->dispatch($message); break; diff --git a/src/Logger/TraceIdProcessor.php b/src/Logger/TraceIdProcessor.php new file mode 100644 index 0000000..e38d589 --- /dev/null +++ b/src/Logger/TraceIdProcessor.php @@ -0,0 +1,42 @@ +traceId = $bindTraceId; + } + + /** + * Magic invoke function. + * + * @param array $record + * Log record + * + * @return array + * The record added require id in extras + */ + public function __invoke(array $record) + { + $record['extra']['traceId'] = $this->traceId; + + return $record; + } +} diff --git a/src/Message/CoverUserUploadMessage.php b/src/Message/CoverUserUploadMessage.php index 8b6d757..d5297f9 100644 --- a/src/Message/CoverUserUploadMessage.php +++ b/src/Message/CoverUserUploadMessage.php @@ -20,6 +20,7 @@ class CoverUserUploadMessage private $imageUrl; private $accrediting; private $vendorId; + private $requestId; /** * @return string @@ -140,4 +141,30 @@ public function setVendorId($vendorId): self return $this; } + + /** + * Get request id (which is unique for the whole request). + * + * @return string + * The request id + */ + public function getRequestId() + { + return $this->requestId; + } + + /** + * Set request id (which is unique for the whole request). + * + * @param string $requestId + * The request id (normally found in HTTP_X_REQUEST_ID) + * + * @return CoverUserUploadMessage + */ + public function setRequestId(string $requestId): self + { + $this->requestId = $requestId; + + return $this; + } }