Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 226b36e

Browse filesBrowse files
feature #30964 [HttpKernel] Add a "short" trace header format, make header configurable (mpdude)
This PR was squashed before being merged into the 4.3-dev branch (closes #30964). Discussion ---------- [HttpKernel] Add a "short" trace header format, make header configurable | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | symfony/symfony-docs#11340 This pull requests adds the first usage of `array_key_first` to the Symfony code base. Additionally, it makes it possible to configure the `HttpCache` to also add a "trace" header in production. The `HttpCache` is a convenient, low-barrier yet performant way of accelerating the application. By having the "trace" information returned as a header in production as well, you can write it to server log files. For example, with Apache you can use `%{X-Symfony-Cache}o` in the `LogFormat` directive to log response headers. With the information in the log files, you can easily process it from logfile processing/system metrics tools to find out about cache performance, efficiency and the URLs that might need extra cache tweaking. <img width="1040" alt="Bildschirmfoto 2019-04-07 um 11 43 23" src="https://user-images.githubusercontent.com/1202333/55681763-6e90e980-592a-11e9-900f-e096350531c2.png"> The "short" format will only output information for the main request to avoid leaking internal URLs for ESI subrequests. I also chose a concise format like `stale/valid/store` because that's much easier to parse out of logfiles (no whitespace, no need for quotes etc.). If you're not comfortable with having `Symfony` in the header name that way, the header name can be changed through a configuration setting as well. #FOSSHackathon Commits ------- 9a2fcc9 [HttpKernel] Add a \"short\" trace header format, make header configurable
2 parents b0989aa + 9a2fcc9 commit 226b36e
Copy full SHA for 226b36e

File tree

5 files changed

+76
-4
lines changed
Filter options

5 files changed

+76
-4
lines changed

‎src/Symfony/Component/HttpKernel/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ CHANGELOG
2424
* renamed `GetResponseForExceptionEvent` to `ExceptionEvent`
2525
* renamed `PostResponseEvent` to `TerminateEvent`
2626
* added `HttpClientKernel` for handling requests with an `HttpClientInterface` instance
27+
* added `trace_header` and `trace_level` configuration options to `HttpCache`
2728

2829
4.2.0
2930
-----

‎src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
+33-3Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,14 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
4040
*
4141
* The available options are:
4242
*
43-
* * debug: If true, the traces are added as a HTTP header to ease debugging
43+
* * debug If true, exceptions are thrown when things go wrong. Otherwise, the cache
44+
* will try to carry on and deliver a meaningful response.
45+
*
46+
* * trace_level May be one of 'none', 'short' and 'full'. For 'short', a concise trace of the
47+
* master request will be added as an HTTP header. 'full' will add traces for all
48+
* requests (including ESI subrequests). (default: 'full' if in debug; 'none' otherwise)
49+
*
50+
* * trace_header Header name to use for traces. (default: X-Symfony-Cache)
4451
*
4552
* * default_ttl The number of seconds that a cache entry should be considered
4653
* fresh when no explicit freshness information is provided in
@@ -87,7 +94,13 @@ public function __construct(HttpKernelInterface $kernel, StoreInterface $store,
8794
'allow_revalidate' => false,
8895
'stale_while_revalidate' => 2,
8996
'stale_if_error' => 60,
97+
'trace_level' => 'none',
98+
'trace_header' => 'X-Symfony-Cache',
9099
], $options);
100+
101+
if (!isset($options['trace_level']) && $this->options['debug']) {
102+
$this->options['trace_level'] = 'full';
103+
}
91104
}
92105

93106
/**
@@ -110,6 +123,23 @@ public function getTraces()
110123
return $this->traces;
111124
}
112125

126+
private function addTraces(Response $response)
127+
{
128+
$traceString = null;
129+
130+
if ('full' === $this->options['trace_level']) {
131+
$traceString = $this->getLog();
132+
}
133+
134+
if ('short' === $this->options['trace_level'] && $masterId = array_key_first($this->traces)) {
135+
$traceString = implode('/', $this->traces[$masterId]);
136+
}
137+
138+
if (null !== $traceString) {
139+
$response->headers->add([$this->options['trace_header'] => $traceString]);
140+
}
141+
}
142+
113143
/**
114144
* Returns a log message for the events of the last request processing.
115145
*
@@ -194,8 +224,8 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
194224

195225
$this->restoreResponseBody($request, $response);
196226

197-
if (HttpKernelInterface::MASTER_REQUEST === $type && $this->options['debug']) {
198-
$response->headers->set('X-Symfony-Cache', $this->getLog());
227+
if (HttpKernelInterface::MASTER_REQUEST === $type) {
228+
$this->addTraces($response);
199229
}
200230

201231
if (null !== $this->surrogate) {

‎src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTest.php
+38Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,44 @@ public function testUsesOriginalRequestForSurrogate()
15081508
// Surrogate request
15091509
$cache->handle($request, HttpKernelInterface::SUB_REQUEST);
15101510
}
1511+
1512+
public function testTraceHeaderNameCanBeChanged()
1513+
{
1514+
$this->cacheConfig['trace_header'] = 'X-My-Header';
1515+
$this->setNextResponse();
1516+
$this->request('GET', '/');
1517+
1518+
$this->assertTrue($this->response->headers->has('X-My-Header'));
1519+
}
1520+
1521+
public function testTraceLevelDefaultsToFullIfDebug()
1522+
{
1523+
$this->setNextResponse();
1524+
$this->request('GET', '/');
1525+
1526+
$this->assertTrue($this->response->headers->has('X-Symfony-Cache'));
1527+
$this->assertEquals('GET /: miss', $this->response->headers->get('X-Symfony-Cache'));
1528+
}
1529+
1530+
public function testTraceLevelDefaultsToNoneIfNotDebug()
1531+
{
1532+
$this->cacheConfig['debug'] = false;
1533+
$this->setNextResponse();
1534+
$this->request('GET', '/');
1535+
1536+
$this->assertFalse($this->response->headers->has('X-Symfony-Cache'));
1537+
}
1538+
1539+
public function testTraceLevelShort()
1540+
{
1541+
$this->cacheConfig['trace_level'] = 'short';
1542+
1543+
$this->setNextResponse();
1544+
$this->request('GET', '/');
1545+
1546+
$this->assertTrue($this->response->headers->has('X-Symfony-Cache'));
1547+
$this->assertEquals('miss', $this->response->headers->get('X-Symfony-Cache'));
1548+
}
15111549
}
15121550

15131551
class TestKernel implements HttpKernelInterface

‎src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTestCase.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Tests/HttpCache/HttpCacheTestCase.php
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ public function request($method, $uri = '/', $server = [], $cookies = [], $esi =
122122

123123
$this->store = new Store(sys_get_temp_dir().'/http_cache');
124124

125-
$this->cacheConfig['debug'] = true;
125+
if (!isset($this->cacheConfig['debug'])) {
126+
$this->cacheConfig['debug'] = true;
127+
}
126128

127129
$this->esi = $esi ? new Esi() : null;
128130
$this->cache = new HttpCache($this->kernel, $this->store, $this->esi, $this->cacheConfig);

‎src/Symfony/Component/HttpKernel/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/composer.json
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"symfony/http-foundation": "^4.1.1",
2323
"symfony/debug": "~3.4|~4.0",
2424
"symfony/polyfill-ctype": "~1.8",
25+
"symfony/polyfill-php73": "^1.9",
2526
"psr/log": "~1.0"
2627
},
2728
"require-dev": {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.