PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php

https://gitlab.com/madwanz64/laravel
PHP | 217 lines | 143 code | 38 blank | 36 comment | 23 complexity | befe37d4be0eae6af036ac9ba2d178d8 MD5 | raw file
  1. <?php declare(strict_types=1);
  2. /*
  3. * This file is part of the Monolog package.
  4. *
  5. * (c) Jordi Boggiano <j.boggiano@seld.be>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Monolog\Formatter;
  11. use Monolog\Utils;
  12. /**
  13. * Formats incoming records into a one-line string
  14. *
  15. * This is especially useful for logging to files
  16. *
  17. * @author Jordi Boggiano <j.boggiano@seld.be>
  18. * @author Christophe Coevoet <stof@notk.org>
  19. */
  20. class LineFormatter extends NormalizerFormatter
  21. {
  22. public const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
  23. /** @var string */
  24. protected $format;
  25. /** @var bool */
  26. protected $allowInlineLineBreaks;
  27. /** @var bool */
  28. protected $ignoreEmptyContextAndExtra;
  29. /** @var bool */
  30. protected $includeStacktraces;
  31. /**
  32. * @param string|null $format The format of the message
  33. * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format
  34. * @param bool $allowInlineLineBreaks Whether to allow inline line breaks in log entries
  35. * @param bool $ignoreEmptyContextAndExtra
  36. */
  37. public function __construct(?string $format = null, ?string $dateFormat = null, bool $allowInlineLineBreaks = false, bool $ignoreEmptyContextAndExtra = false, bool $includeStacktraces = false)
  38. {
  39. $this->format = $format === null ? static::SIMPLE_FORMAT : $format;
  40. $this->allowInlineLineBreaks = $allowInlineLineBreaks;
  41. $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
  42. $this->includeStacktraces($includeStacktraces);
  43. parent::__construct($dateFormat);
  44. }
  45. public function includeStacktraces(bool $include = true): self
  46. {
  47. $this->includeStacktraces = $include;
  48. if ($this->includeStacktraces) {
  49. $this->allowInlineLineBreaks = true;
  50. }
  51. return $this;
  52. }
  53. public function allowInlineLineBreaks(bool $allow = true): self
  54. {
  55. $this->allowInlineLineBreaks = $allow;
  56. return $this;
  57. }
  58. public function ignoreEmptyContextAndExtra(bool $ignore = true): self
  59. {
  60. $this->ignoreEmptyContextAndExtra = $ignore;
  61. return $this;
  62. }
  63. /**
  64. * {@inheritDoc}
  65. */
  66. public function format(array $record): string
  67. {
  68. $vars = parent::format($record);
  69. $output = $this->format;
  70. foreach ($vars['extra'] as $var => $val) {
  71. if (false !== strpos($output, '%extra.'.$var.'%')) {
  72. $output = str_replace('%extra.'.$var.'%', $this->stringify($val), $output);
  73. unset($vars['extra'][$var]);
  74. }
  75. }
  76. foreach ($vars['context'] as $var => $val) {
  77. if (false !== strpos($output, '%context.'.$var.'%')) {
  78. $output = str_replace('%context.'.$var.'%', $this->stringify($val), $output);
  79. unset($vars['context'][$var]);
  80. }
  81. }
  82. if ($this->ignoreEmptyContextAndExtra) {
  83. if (empty($vars['context'])) {
  84. unset($vars['context']);
  85. $output = str_replace('%context%', '', $output);
  86. }
  87. if (empty($vars['extra'])) {
  88. unset($vars['extra']);
  89. $output = str_replace('%extra%', '', $output);
  90. }
  91. }
  92. foreach ($vars as $var => $val) {
  93. if (false !== strpos($output, '%'.$var.'%')) {
  94. $output = str_replace('%'.$var.'%', $this->stringify($val), $output);
  95. }
  96. }
  97. // remove leftover %extra.xxx% and %context.xxx% if any
  98. if (false !== strpos($output, '%')) {
  99. $output = preg_replace('/%(?:extra|context)\..+?%/', '', $output);
  100. if (null === $output) {
  101. $pcreErrorCode = preg_last_error();
  102. throw new \RuntimeException('Failed to run preg_replace: ' . $pcreErrorCode . ' / ' . Utils::pcreLastErrorMessage($pcreErrorCode));
  103. }
  104. }
  105. return $output;
  106. }
  107. public function formatBatch(array $records): string
  108. {
  109. $message = '';
  110. foreach ($records as $record) {
  111. $message .= $this->format($record);
  112. }
  113. return $message;
  114. }
  115. /**
  116. * @param mixed $value
  117. */
  118. public function stringify($value): string
  119. {
  120. return $this->replaceNewlines($this->convertToString($value));
  121. }
  122. protected function normalizeException(\Throwable $e, int $depth = 0): string
  123. {
  124. $str = $this->formatException($e);
  125. if ($previous = $e->getPrevious()) {
  126. do {
  127. $str .= "\n[previous exception] " . $this->formatException($previous);
  128. } while ($previous = $previous->getPrevious());
  129. }
  130. return $str;
  131. }
  132. /**
  133. * @param mixed $data
  134. */
  135. protected function convertToString($data): string
  136. {
  137. if (null === $data || is_bool($data)) {
  138. return var_export($data, true);
  139. }
  140. if (is_scalar($data)) {
  141. return (string) $data;
  142. }
  143. return $this->toJson($data, true);
  144. }
  145. protected function replaceNewlines(string $str): string
  146. {
  147. if ($this->allowInlineLineBreaks) {
  148. if (0 === strpos($str, '{')) {
  149. return str_replace(array('\r', '\n'), array("\r", "\n"), $str);
  150. }
  151. return $str;
  152. }
  153. return str_replace(["\r\n", "\r", "\n"], ' ', $str);
  154. }
  155. private function formatException(\Throwable $e): string
  156. {
  157. $str = '[object] (' . Utils::getClass($e) . '(code: ' . $e->getCode();
  158. if ($e instanceof \SoapFault) {
  159. if (isset($e->faultcode)) {
  160. $str .= ' faultcode: ' . $e->faultcode;
  161. }
  162. if (isset($e->faultactor)) {
  163. $str .= ' faultactor: ' . $e->faultactor;
  164. }
  165. if (isset($e->detail)) {
  166. if (is_string($e->detail)) {
  167. $str .= ' detail: ' . $e->detail;
  168. } elseif (is_object($e->detail) || is_array($e->detail)) {
  169. $str .= ' detail: ' . $this->toJson($e->detail, true);
  170. }
  171. }
  172. }
  173. $str .= '): ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine() . ')';
  174. if ($this->includeStacktraces) {
  175. $str .= "\n[stacktrace]\n" . $e->getTraceAsString() . "\n";
  176. }
  177. return $str;
  178. }
  179. }