No Description

MessageFormatter.php 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php
  2. namespace GuzzleHttp;
  3. use Psr\Http\Message\MessageInterface;
  4. use Psr\Http\Message\RequestInterface;
  5. use Psr\Http\Message\ResponseInterface;
  6. /**
  7. * Formats log messages using variable substitutions for requests, responses,
  8. * and other transactional data.
  9. *
  10. * The following variable substitutions are supported:
  11. *
  12. * - {request}: Full HTTP request message
  13. * - {response}: Full HTTP response message
  14. * - {ts}: ISO 8601 date in GMT
  15. * - {date_iso_8601} ISO 8601 date in GMT
  16. * - {date_common_log} Apache common log date using the configured timezone.
  17. * - {host}: Host of the request
  18. * - {method}: Method of the request
  19. * - {uri}: URI of the request
  20. * - {host}: Host of the request
  21. * - {version}: Protocol version
  22. * - {target}: Request target of the request (path + query + fragment)
  23. * - {hostname}: Hostname of the machine that sent the request
  24. * - {code}: Status code of the response (if available)
  25. * - {phrase}: Reason phrase of the response (if available)
  26. * - {error}: Any error messages (if available)
  27. * - {req_header_*}: Replace `*` with the lowercased name of a request header to add to the message
  28. * - {res_header_*}: Replace `*` with the lowercased name of a response header to add to the message
  29. * - {req_headers}: Request headers
  30. * - {res_headers}: Response headers
  31. * - {req_body}: Request body
  32. * - {res_body}: Response body
  33. */
  34. class MessageFormatter
  35. {
  36. /**
  37. * Apache Common Log Format.
  38. * @link http://httpd.apache.org/docs/2.4/logs.html#common
  39. * @var string
  40. */
  41. const CLF = "{hostname} {req_header_User-Agent} - [{date_common_log}] \"{method} {target} HTTP/{version}\" {code} {res_header_Content-Length}";
  42. const DEBUG = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}";
  43. const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}';
  44. /** @var string Template used to format log messages */
  45. private $template;
  46. /**
  47. * @param string $template Log message template
  48. */
  49. public function __construct($template = self::CLF)
  50. {
  51. $this->template = $template ?: self::CLF;
  52. }
  53. /**
  54. * Returns a formatted message string.
  55. *
  56. * @param RequestInterface $request Request that was sent
  57. * @param ResponseInterface $response Response that was received
  58. * @param \Exception $error Exception that was received
  59. *
  60. * @return string
  61. */
  62. public function format(
  63. RequestInterface $request,
  64. ResponseInterface $response = null,
  65. \Exception $error = null
  66. ) {
  67. $cache = [];
  68. return preg_replace_callback(
  69. '/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
  70. function (array $matches) use ($request, $response, $error, &$cache) {
  71. if (isset($cache[$matches[1]])) {
  72. return $cache[$matches[1]];
  73. }
  74. $result = '';
  75. switch ($matches[1]) {
  76. case 'request':
  77. $result = Psr7\str($request);
  78. break;
  79. case 'response':
  80. $result = $response ? Psr7\str($response) : '';
  81. break;
  82. case 'req_headers':
  83. $result = trim($request->getMethod()
  84. . ' ' . $request->getRequestTarget())
  85. . ' HTTP/' . $request->getProtocolVersion() . "\r\n"
  86. . $this->headers($request);
  87. break;
  88. case 'res_headers':
  89. $result = $response ?
  90. sprintf(
  91. 'HTTP/%s %d %s',
  92. $response->getProtocolVersion(),
  93. $response->getStatusCode(),
  94. $response->getReasonPhrase()
  95. ) . "\r\n" . $this->headers($response)
  96. : 'NULL';
  97. break;
  98. case 'req_body':
  99. $result = $request->getBody();
  100. break;
  101. case 'res_body':
  102. $result = $response ? $response->getBody() : 'NULL';
  103. break;
  104. case 'ts':
  105. case 'date_iso_8601':
  106. $result = gmdate('c');
  107. break;
  108. case 'date_common_log':
  109. $result = date('d/M/Y:H:i:s O');
  110. break;
  111. case 'method':
  112. $result = $request->getMethod();
  113. break;
  114. case 'version':
  115. $result = $request->getProtocolVersion();
  116. break;
  117. case 'uri':
  118. case 'url':
  119. $result = $request->getUri();
  120. break;
  121. case 'target':
  122. $result = $request->getRequestTarget();
  123. break;
  124. case 'req_version':
  125. $result = $request->getProtocolVersion();
  126. break;
  127. case 'res_version':
  128. $result = $response
  129. ? $response->getProtocolVersion()
  130. : 'NULL';
  131. break;
  132. case 'host':
  133. $result = $request->getHeaderLine('Host');
  134. break;
  135. case 'hostname':
  136. $result = gethostname();
  137. break;
  138. case 'code':
  139. $result = $response ? $response->getStatusCode() : 'NULL';
  140. break;
  141. case 'phrase':
  142. $result = $response ? $response->getReasonPhrase() : 'NULL';
  143. break;
  144. case 'error':
  145. $result = $error ? $error->getMessage() : 'NULL';
  146. break;
  147. default:
  148. // handle prefixed dynamic headers
  149. if (strpos($matches[1], 'req_header_') === 0) {
  150. $result = $request->getHeaderLine(substr($matches[1], 11));
  151. } elseif (strpos($matches[1], 'res_header_') === 0) {
  152. $result = $response
  153. ? $response->getHeaderLine(substr($matches[1], 11))
  154. : 'NULL';
  155. }
  156. }
  157. $cache[$matches[1]] = $result;
  158. return $result;
  159. },
  160. $this->template
  161. );
  162. }
  163. private function headers(MessageInterface $message)
  164. {
  165. $result = '';
  166. foreach ($message->getHeaders() as $name => $values) {
  167. $result .= $name . ': ' . implode(', ', $values) . "\r\n";
  168. }
  169. return trim($result);
  170. }
  171. }