public function Logger::log in MongoDB 8.2
See also
https://httpd.apache.org/docs/2.4/en/mod/mod_unique_id.html
File
- modules/
mongodb_watchdog/ src/ Logger.php, line 303
Class
- Logger
- Class Logger is a PSR/3 Logger using a MongoDB data store.
Namespace
Drupal\mongodb_watchdogCode
public function log($level, $template, array $context = []) : void {
// PSR-3 LoggerInterface documents level as "mixed", while the RFC itself
// in §1.1 implies implementations may know about non-standard levels. In
// the case of Drupal implementations, this includes the 8 RFC5424 levels.
if (is_string($level)) {
$level = $this->rfc5424levels[$level];
}
if ($level > $this->limit) {
return;
}
// Convert PSR3-style messages to SafeMarkup::format() style, so they can be
// translated at runtime too.
$placeholders = $this->parser
->parseMessagePlaceholders($template, $context);
// If code location information is all present, as for errors/exceptions,
// then use it to build the message template id.
$type = $context['channel'] ?? static::DEFAULT_CHANNEL;
$location = [
'%type' => 1,
'@message' => 1,
'%function' => 1,
'%file' => 1,
'%line' => 1,
];
if (!empty(array_diff_key($location, $placeholders))) {
$this
->enhanceLogEntry($placeholders, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10));
}
$file = $placeholders['%file'];
$line = $placeholders['%line'];
$function = $placeholders['%function'];
$key = implode(":", [
$type,
$level,
$file,
$line,
$function,
]);
$templateId = md5($key);
$selector = [
'_id' => $templateId,
];
$update = [
'$inc' => [
'count' => 1,
],
'$set' => [
'_id' => $templateId,
'message' => $template,
'severity' => $level,
'changed' => $this->time
->getCurrentTime(),
'type' => mb_substr($type, 0, 64),
],
];
$options = [
'upsert' => TRUE,
];
$templateResult = $this->database
->selectCollection(static::TEMPLATE_COLLECTION)
->updateOne($selector, $update, $options);
// Only insert each template once per request.
if ($this->requestTracking && !isset($this->templates[$templateId])) {
$requestId = $this->requestStack
->getCurrentRequest()->server
->get('UNIQUE_ID');
$this->templates[$templateId] = 1;
$track = [
'requestId' => $requestId,
'templateId' => $templateId,
];
$this
->trackerCollection()
->insertOne($track);
}
else {
// 24-byte format like mod_unique_id values.
$requestId = '@@Not-a-valid-request@@';
}
$eventCollection = $this
->eventCollection($templateId);
if ($templateResult
->getUpsertedCount()) {
// Capped collections are actually size-based, not count-based, so "items"
// is only a maximum, assuming event documents weigh 1kB, but the actual
// number of items stored may be lower if items are heavier.
// We do not use 'autoindexid' for greater speed, because:
// - it does not work on replica sets,
// - it is deprecated in MongoDB 3.2 and going away in 3.4.
$options = [
'capped' => TRUE,
'size' => $this->items * 1024,
'max' => $this->items,
];
$this->database
->createCollection($eventCollection
->getCollectionName(), $options);
// Do not create this index by default, as its cost is useless if request
// tracking is not enabled.
if ($this->requestTracking) {
$key = [
'requestTracking_id' => 1,
];
$options = [
'name' => 'admin-by-request',
];
$eventCollection
->createIndex($key, $options);
}
}
foreach ($placeholders as &$placeholder) {
if ($placeholder instanceof MarkupInterface) {
$placeholder = Xss::filterAdmin($placeholder);
}
}
$event = [
'hostname' => mb_substr($context['ip'] ?? '', 0, 128),
'link' => $context['link'] ?? NULL,
'location' => $context['request_uri'] ?? NULL,
'referer' => $context['referer'] ?? NULL,
'timestamp' => $context['timestamp'] ?? $this->time
->getCurrentTime(),
'user' => [
'uid' => $context['uid'] ?? 0,
],
'variables' => $placeholders,
];
if ($this->requestTracking) {
// Fetch the current request on each event to support subrequest nesting.
$event['requestTracking_id'] = $requestId;
$event['requestTracking_sequence'] = $this->sequence;
$this->sequence++;
}
$eventCollection
->insertOne($event);
}