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

https://gitlab.com/Pasantias/pasantiasASLG · PHP · 166 lines · 107 code · 17 blank · 42 comment · 18 complexity · 73bd07ce780cf8deb8c4216c8b0f7829 MD5 · raw file

  1. <?php
  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. /**
  12. * Serializes a log message to Logstash Event Format
  13. *
  14. * @see http://logstash.net/
  15. * @see https://github.com/logstash/logstash/blob/master/lib/logstash/event.rb
  16. *
  17. * @author Tim Mower <timothy.mower@gmail.com>
  18. */
  19. class LogstashFormatter extends NormalizerFormatter
  20. {
  21. const V0 = 0;
  22. const V1 = 1;
  23. /**
  24. * @var string the name of the system for the Logstash log message, used to fill the @source field
  25. */
  26. protected $systemName;
  27. /**
  28. * @var string an application name for the Logstash log message, used to fill the @type field
  29. */
  30. protected $applicationName;
  31. /**
  32. * @var string a prefix for 'extra' fields from the Monolog record (optional)
  33. */
  34. protected $extraPrefix;
  35. /**
  36. * @var string a prefix for 'context' fields from the Monolog record (optional)
  37. */
  38. protected $contextPrefix;
  39. /**
  40. * @var int logstash format version to use
  41. */
  42. protected $version;
  43. /**
  44. * @param string $applicationName the application that sends the data, used as the "type" field of logstash
  45. * @param string $systemName the system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine
  46. * @param string $extraPrefix prefix for extra keys inside logstash "fields"
  47. * @param string $contextPrefix prefix for context keys inside logstash "fields", defaults to ctxt_
  48. * @param int $version the logstash format version to use, defaults to 0
  49. */
  50. public function __construct($applicationName, $systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_', $version = self::V0)
  51. {
  52. // logstash requires a ISO 8601 format date with optional millisecond precision.
  53. parent::__construct('Y-m-d\TH:i:s.uP');
  54. $this->systemName = $systemName ?: gethostname();
  55. $this->applicationName = $applicationName;
  56. $this->extraPrefix = $extraPrefix;
  57. $this->contextPrefix = $contextPrefix;
  58. $this->version = $version;
  59. }
  60. /**
  61. * {@inheritdoc}
  62. */
  63. public function format(array $record)
  64. {
  65. $record = parent::format($record);
  66. if ($this->version === self::V1) {
  67. $message = $this->formatV1($record);
  68. } else {
  69. $message = $this->formatV0($record);
  70. }
  71. return $this->toJson($message) . "\n";
  72. }
  73. protected function formatV0(array $record)
  74. {
  75. if (empty($record['datetime'])) {
  76. $record['datetime'] = gmdate('c');
  77. }
  78. $message = array(
  79. '@timestamp' => $record['datetime'],
  80. '@source' => $this->systemName,
  81. '@fields' => array(),
  82. );
  83. if (isset($record['message'])) {
  84. $message['@message'] = $record['message'];
  85. }
  86. if (isset($record['channel'])) {
  87. $message['@tags'] = array($record['channel']);
  88. $message['@fields']['channel'] = $record['channel'];
  89. }
  90. if (isset($record['level'])) {
  91. $message['@fields']['level'] = $record['level'];
  92. }
  93. if ($this->applicationName) {
  94. $message['@type'] = $this->applicationName;
  95. }
  96. if (isset($record['extra']['server'])) {
  97. $message['@source_host'] = $record['extra']['server'];
  98. }
  99. if (isset($record['extra']['url'])) {
  100. $message['@source_path'] = $record['extra']['url'];
  101. }
  102. if (!empty($record['extra'])) {
  103. foreach ($record['extra'] as $key => $val) {
  104. $message['@fields'][$this->extraPrefix . $key] = $val;
  105. }
  106. }
  107. if (!empty($record['context'])) {
  108. foreach ($record['context'] as $key => $val) {
  109. $message['@fields'][$this->contextPrefix . $key] = $val;
  110. }
  111. }
  112. return $message;
  113. }
  114. protected function formatV1(array $record)
  115. {
  116. if (empty($record['datetime'])) {
  117. $record['datetime'] = gmdate('c');
  118. }
  119. $message = array(
  120. '@timestamp' => $record['datetime'],
  121. '@version' => 1,
  122. 'host' => $this->systemName,
  123. );
  124. if (isset($record['message'])) {
  125. $message['message'] = $record['message'];
  126. }
  127. if (isset($record['channel'])) {
  128. $message['type'] = $record['channel'];
  129. $message['channel'] = $record['channel'];
  130. }
  131. if (isset($record['level_name'])) {
  132. $message['level'] = $record['level_name'];
  133. }
  134. if ($this->applicationName) {
  135. $message['type'] = $this->applicationName;
  136. }
  137. if (!empty($record['extra'])) {
  138. foreach ($record['extra'] as $key => $val) {
  139. $message[$this->extraPrefix . $key] = $val;
  140. }
  141. }
  142. if (!empty($record['context'])) {
  143. foreach ($record['context'] as $key => $val) {
  144. $message[$this->contextPrefix . $key] = $val;
  145. }
  146. }
  147. return $message;
  148. }
  149. }