Skip to content
Snippets Groups Projects
Commit 3e837e43 authored by Reiter, Christoph's avatar Reiter, Christoph :snake:
Browse files

Add a request specific ID to the logging processor

We currently attach a user session ID to each log entry, so we know
which requests are part of the same user session.

This only works after the user is authenticated since we generate the
logging ID from the access token.

This adds a per-request uuid so we know which log lines are part of
the same request.
parent bacda30a
No related branches found
No related tags found
No related merge requests found
Pipeline #80792 passed
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "60d4189d81142d4a8db05bd05648f2eb",
"content-hash": "4ab91450e5719405ae60fb0d5496b029",
"packages": [
{
"name": "api-platform/core",
......@@ -3892,6 +3892,85 @@
],
"time": "2021-05-21T13:25:03+00:00"
},
{
"name": "symfony/polyfill-uuid",
"version": "v1.23.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-uuid.git",
"reference": "9165effa2eb8a31bb3fa608df9d529920d21ddd9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/9165effa2eb8a31bb3fa608df9d529920d21ddd9",
"reference": "9165effa2eb8a31bb3fa608df9d529920d21ddd9",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-uuid": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Uuid\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Grégoire Pineau",
"email": "lyrixx@lyrixx.info"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for uuid functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"uuid"
],
"support": {
"source": "https://github.com/symfony/polyfill-uuid/tree/v1.23.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-02-19T12:13:01+00:00"
},
{
"name": "symfony/property-access",
"version": "v5.4.0",
......@@ -5199,6 +5278,80 @@
],
"time": "2021-11-23T21:36:27+00:00"
},
{
"name": "symfony/uid",
"version": "v5.4.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/uid.git",
"reference": "89b2e717aa45a57cc0dbe8bff57b9d15b919c67b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/uid/zipball/89b2e717aa45a57cc0dbe8bff57b9d15b919c67b",
"reference": "89b2e717aa45a57cc0dbe8bff57b9d15b919c67b",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-uuid": "^1.15"
},
"require-dev": {
"symfony/console": "^4.4|^5.0|^6.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Uid\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Grégoire Pineau",
"email": "lyrixx@lyrixx.info"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides an object-oriented API to generate and represent UIDs",
"homepage": "https://symfony.com",
"keywords": [
"UID",
"ulid",
"uuid"
],
"support": {
"source": "https://github.com/symfony/uid/tree/v5.4.2"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-12-16T21:52:00+00:00"
},
{
"name": "symfony/validator",
"version": "v5.4.1",
......@@ -7840,5 +7993,5 @@
"platform-overrides": {
"php": "7.3"
},
"plugin-api-version": "2.1.0"
"plugin-api-version": "2.2.0"
}
......@@ -6,14 +6,18 @@ namespace Dbp\Relay\CoreBundle\Logging;
use Dbp\Relay\CoreBundle\API\UserSessionInterface;
use Dbp\Relay\CoreBundle\Helpers\Tools as CoreTools;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Uid\Uuid;
final class LoggingProcessor
{
private $userDataProvider;
private $requestStack;
public function __construct(UserSessionInterface $userDataProvider)
public function __construct(UserSessionInterface $userDataProvider, RequestStack $requestStack)
{
$this->userDataProvider = $userDataProvider;
$this->requestStack = $requestStack;
}
private function maskUserId(array &$record)
......@@ -38,10 +42,22 @@ final class LoggingProcessor
// Mask the user identifier
$this->maskUserId($record);
// Add some default context (session ID etc)
// Add a session ID (the same during multiple requests for the same user session)
$loggingId = $this->userDataProvider->getSessionLoggingId();
if ($loggingId !== null) {
$record['context']['dbp-id'] = $loggingId;
$record['context']['relay-session-id'] = $loggingId;
}
// Add a request ID (the same during the same client request)
$request = $this->requestStack->getMainRequest();
if ($request !== null) {
$requestAttributeKey = 'relay-request-id';
$requestId = $request->attributes->get($requestAttributeKey);
if ($requestId === null) {
$requestId = Uuid::v4()->toRfc4122();
$request->attributes->set($requestAttributeKey, $requestId);
}
$record['context']['relay-request-id'] = $requestId;
}
return $record;
......
......@@ -7,21 +7,44 @@ namespace Dbp\Relay\CoreBundle\Tests\Logging;
use Dbp\Relay\CoreBundle\Logging\LoggingProcessor;
use Dbp\Relay\CoreBundle\TestUtils\TestUserSession;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
class LoggingProcessorTest extends WebTestCase
{
public function testFilter()
{
$processor = new LoggingProcessor(new TestUserSession('some-random-user-id'));
$processor = new LoggingProcessor(new TestUserSession('some-random-user-id'), new RequestStack());
$record = ['message' => 'http://foo.bar?token=secret'];
$record = $processor->__invoke($record);
$this->assertSame(['message' => 'http://foo.bar?token=hidden', 'context' => ['dbp-id' => 'logging-id']], $record);
$this->assertSame(['message' => 'http://foo.bar?token=hidden', 'context' => ['relay-session-id' => 'logging-id']], $record);
}
public function testRequestId()
{
$stack = new RequestStack();
$stack->push(new Request());
$processor = new LoggingProcessor(new TestUserSession('some-random-user-id'), $stack);
$record = ['message' => 'foo'];
$processed = $processor->__invoke($record);
$this->assertArrayHasKey('relay-request-id', $processed['context']);
$processed2 = $processor->__invoke($record);
$this->assertSame($processed['context']['relay-request-id'], $processed2['context']['relay-request-id']);
}
public function testSessionId()
{
$processor = new LoggingProcessor(new TestUserSession('log'), new RequestStack());
$record = ['message' => 'foobar'];
$record = $processor->__invoke($record);
$this->assertSame(['message' => 'foobar', 'context' => ['relay-session-id' => 'logging-id']], $record);
}
public function testMaskUserId()
{
$processor = new LoggingProcessor(new TestUserSession('some-random-user-id'));
$processor = new LoggingProcessor(new TestUserSession('some-random-user-id'), new RequestStack());
$record = [
'message' => 'hello some-random-user-id!',
......@@ -32,12 +55,12 @@ class LoggingProcessorTest extends WebTestCase
$this->assertSame([
'message' => 'hello *****!',
'extra' => ['foo' => '*****'],
'context' => ['foo' => '*****', 'dbp-id' => 'logging-id'], ], $record);
'context' => ['foo' => '*****', 'relay-session-id' => 'logging-id'], ], $record);
// Don't mask when contained in a word
$processor = new LoggingProcessor(new TestUserSession('log'));
$processor = new LoggingProcessor(new TestUserSession('log'), new RequestStack());
$record = ['message' => 'logging log'];
$record = $processor->__invoke($record);
$this->assertSame(['message' => 'logging *****', 'context' => ['dbp-id' => 'logging-id']], $record);
$this->assertSame(['message' => 'logging *****', 'context' => ['relay-session-id' => 'logging-id']], $record);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment