21 'message',
'channel',
'level',
'type',
23 'url',
'ip',
'http_method',
'server',
'referrer',
25 'host',
'wiki',
'reqId',
'mwversion',
47 public function __construct(
string $applicationName, ?
string $systemName =
null,
48 string $extraKey =
'',
string $contextKey =
'ctxt_',
$version = self::V0
51 parent::__construct( $applicationName, $systemName, $extraKey, $contextKey );
54 public function format( array $record ): string {
55 $record = \Monolog\Formatter\NormalizerFormatter::
format( $record );
56 if ( $this->version === self::V1 ) {
57 $message = $this->
formatV1( $record );
58 } elseif ( $this->version === self::V0 ) {
59 $message = $this->
formatV0( $record );
64 return $this->toJson( $message ) .
"\n";
73 if ( $this->contextKey !==
'' ) {
74 return $this->formatMonologV0( $record );
77 $context = !empty( $record[
'context'] ) ? $record[
'context'] : [];
78 $record[
'context'] = [];
79 $formatted = $this->formatMonologV0( $record );
81 $formatted[
'@fields'] = $this->fixKeyConflicts( $formatted[
'@fields'], $context );
94 if ( empty( $record[
'datetime'] ) ) {
95 $record[
'datetime'] = gmdate(
'c' );
98 '@timestamp' => $record[
'datetime'],
99 '@source' => $this->systemName,
102 if ( isset( $record[
'message'] ) ) {
103 $message[
'@message'] = $record[
'message'];
105 if ( isset( $record[
'channel'] ) ) {
106 $message[
'@tags'] = [ $record[
'channel'] ];
107 $message[
'@fields'][
'channel'] = $record[
'channel'];
109 if ( isset( $record[
'level'] ) ) {
110 $message[
'@fields'][
'level'] = $record[
'level'];
112 if ( $this->applicationName ) {
113 $message[
'@type'] = $this->applicationName;
115 if ( isset( $record[
'extra'][
'server'] ) ) {
116 $message[
'@source_host'] = $record[
'extra'][
'server'];
118 if ( isset( $record[
'extra'][
'url'] ) ) {
119 $message[
'@source_path'] = $record[
'extra'][
'url'];
121 if ( !empty( $record[
'extra'] ) ) {
122 foreach ( $record[
'extra'] as $key => $val ) {
123 $message[
'@fields'][$this->extraKey . $key] = $val;
126 if ( !empty( $record[
'context'] ) ) {
127 foreach ( $record[
'context'] as $key => $val ) {
128 $message[
'@fields'][$this->contextKey . $key] = $val;
141 if ( $this->contextKey ) {
142 return $this->formatMonologV1( $record );
145 $context = !empty( $record[
'context'] ) ? $record[
'context'] : [];
146 $record[
'context'] = [];
147 $formatted = $this->formatMonologV1( $record );
149 return $this->fixKeyConflicts( $formatted, $context );
160 if ( empty( $record[
'datetime'] ) ) {
161 $record[
'datetime'] = gmdate(
'c' );
164 '@timestamp' => $record[
'datetime'],
166 'host' => $this->systemName,
168 if ( isset( $record[
'message'] ) ) {
169 $message[
'message'] = $record[
'message'];
171 if ( isset( $record[
'channel'] ) ) {
172 $message[
'type'] = $record[
'channel'];
173 $message[
'channel'] = $record[
'channel'];
175 if ( isset( $record[
'level_name'] ) ) {
176 $message[
'level'] = $record[
'level_name'];
180 if ( isset( $record[
'level'] ) ) {
181 $message[
'monolog_level'] = $record[
'level'];
183 if ( $this->applicationName ) {
184 $message[
'type'] = $this->applicationName;
186 if ( !empty( $record[
'extra'] ) ) {
187 foreach ( $record[
'extra'] as $key => $val ) {
188 $message[$this->extraKey . $key] = $val;
191 if ( !empty( $record[
'context'] ) ) {
192 foreach ( $record[
'context'] as $key => $val ) {
193 $message[$this->contextKey . $key] = $val;
208 foreach ( $context as $key => $val ) {
210 in_array( $key, $this->reservedKeys,
true ) &&
211 isset( $fields[$key] ) && $fields[$key] !== $val
213 $fields[
'logstash_formatter_key_conflict'][] = $key;
216 $fields[$key] = $val;
230 'class' => get_class( $e ),
231 'message' => $e->getMessage(),
232 'code' => $e->getCode(),
233 'file' => $e->getFile() .
':' . $e->getLine(),
234 'trace' => \MWExceptionHandler::getRedactedTraceAsString( $e ),
237 $previous = $e->getPrevious();
239 $data[
'previous'] = $this->normalizeException( $previous );