Skip to content

Commit

Permalink
ITKDev: Added exception hanling
Browse files Browse the repository at this point in the history
  • Loading branch information
cableman committed Apr 26, 2024
1 parent d016055 commit d38dd28
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 47 deletions.
6 changes: 0 additions & 6 deletions os2web_audit.module

This file was deleted.

25 changes: 25 additions & 0 deletions src/Exception/AuditException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Drupal\os2web_audit\Exception;

class AuditException extends \Exception {

/**
* The name of the plugin-.
*
* @var string $pluginName
*/
private string $pluginName = 'Unknown plugin';

public function __construct(string $message = "", int $code = 0, \Throwable $previous = NULL, string $pluginName = '') {
parent::__construct($message, $code, $previous);

if (isset($pluginName)) {
$this->pluginName = $pluginName;
}
}

public function getPluginName(): string {
return $this->pluginName;
}
}
6 changes: 6 additions & 0 deletions src/Exception/ConnectionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php

namespace Drupal\os2web_audit\Exception;

class ConnectionException extends AuditException {
}
9 changes: 0 additions & 9 deletions src/Form/SettingsForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,6 @@ public function buildForm(array $form, FormStateInterface $form_state): array {
'#default_value' => $config->get('provider'),
];

$form['fallback'] = [
'#type' => 'select',
'#title' => $this->t('Fallback Log provider'),
'#description' => $this->t('Select the logger provider you which to use, if the main provider fails'),
'#options' => $options,
'#default_value' => $config->get('fallback'),
];

return parent::buildForm($form, $form_state);
}

Expand All @@ -97,7 +89,6 @@ public function submitForm(array &$form, FormStateInterface $form_state): void {

$this->config(self::$configName)
->set('provider', $form_state->getValue('provider'))
->set('fallback', $form_state->getValue('fallback'))
->save();
}

Expand Down
3 changes: 3 additions & 0 deletions src/Plugin/AuditLogger/AuditLoggerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ interface AuditLoggerInterface extends PluginInspectionInterface {
* @param array<string, string> $metadata
* Additional metadata associated with the log entry. Defaults to an empty
* array.
*
* @throws \Drupal\os2web_audit\Exception\ConnectionException
* @throws \Drupal\os2web_audit\Exception\AuditException
*/
public function log(string $type, int $timestamp, string $line, array $metadata = []): void;

Expand Down
3 changes: 2 additions & 1 deletion src/Plugin/AuditLogger/Loki.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
/**
* {@inheritdoc}
*
* @throws \JsonException
* @throws \Drupal\os2web_audit\Exception\ConnectionException
* @throws \Drupal\os2web_audit\Exception\AuditException
*/
public function log(string $type, int $timestamp, string $line, array $metadata = []): void {
$client = new LokiClient([
Expand Down
47 changes: 28 additions & 19 deletions src/Service/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

namespace Drupal\os2web_audit\Service;

use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\os2web_audit\Exception\ConnectionException;
use Drupal\os2web_audit\Exception\AuditException;
use Drupal\os2web_audit\Form\PluginSettingsForm;
use Drupal\os2web_audit\Form\SettingsForm;
use Drupal\os2web_audit\Plugin\LoggerManager;
Expand All @@ -19,6 +23,7 @@ public function __construct(
private readonly LoggerManager $loggerManager,
private readonly ConfigFactoryInterface $configFactory,
private readonly AccountProxyInterface $currentUser,
private readonly LoggerChannelFactoryInterface $watchdog,
) {
}

Expand All @@ -27,41 +32,33 @@ public function __construct(
*
* @param string $type
* The type of event to log (auth, lookup etc.)
* @param int $timestamp
* The timestamp for the log message.
* @param string $line
* The log message.
* @param bool $logUser
* Log information about the current logged-in user (need to track who has
* lookup information in external services). Default: false.
* @param array<string, string> $metadata
* Additional metadata for the log message. Default is an empty array.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
public function info(string $type, int $timestamp, string $line, bool $logUser = FALSE, array $metadata = []): void {
$this->log($type, $timestamp, $line, $logUser, $metadata + ['level' => 'info']);
public function info(string $type, string $line, bool $logUser = TRUE, array $metadata = []): void {
$this->log($type, time(), $line, $logUser, $metadata + ['level' => 'info']);
}

/**
* Logs a message at error level.
*
* @param string $type
* The type of event to log (auth, lookup etc.)
* @param int $timestamp
* The timestamp for the log message.
* @param string $line
* The log message.
* @param bool $logUser
* Log information about the current logged-in user (need to track who has
* lookup information in external services). Default: false.
* @param array<string, string> $metadata
* Additional metadata for the log message. Default is an empty array.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
public function error(string $type, int $timestamp, string $line, bool $logUser = FALSE, array $metadata = []): void {
$this->log($type, $timestamp, $line, $logUser, $metadata + ['level' => 'error']);
public function error(string $type, string $line, bool $logUser = TRUE, array $metadata = []): void {
$this->log($type, time(), $line, $logUser, $metadata + ['level' => 'error']);
}

/**
Expand All @@ -78,24 +75,36 @@ public function error(string $type, int $timestamp, string $line, bool $logUser
* lookup information in external services). Default: false.
* @param array<string, string> $metadata
* Additional metadata for the log message. Default is an empty array.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
private function log(string $type, int $timestamp, string $line, bool $logUser = FALSE, array $metadata = []): void {
$config = $this->configFactory->get(SettingsForm::$configName);
$plugin_id = $config->get('provider');

// @todo default logger (file)
// @todo Fallback logger on error.
$configuration = $this->configFactory->get(PluginSettingsForm::getConfigName())->get($plugin_id);
$logger = $this->loggerManager->createInstance($plugin_id, $configuration ?? []);

if ($logUser) {
// Add user id to the log message metadata.
$metadata['userId'] = $this->currentUser->id();
}

$logger->log($type, $timestamp, $line, $metadata);
try {
/** @var \Drupal\os2web_audit\Plugin\AuditLogger\AuditLoggerInterface $logger */
$logger = $this->loggerManager->createInstance($plugin_id, $configuration ?? []);
$logger->log($type, $timestamp, $line, $metadata);
}
catch (PluginException $e) {
$this->watchdog->get('os2web_audit')->error($e->getMessage());
}
catch (AuditException|ConnectionException $e) {
// Change metadata into string.
$data = implode(', ', array_map(function($key, $value) {
return $key . " => " . $value;
}, array_keys($metadata), $metadata));

// Fallback to send log message info watchdog.
$msg = sprintf("Type: %s, Msg: %s, Metadata: %s", $type, $line, $data);
$this->watchdog->get('os2web_audit')->info($msg);
$this->watchdog->get('os2web_audit_error')->error($e->getMessage());
}
}

}
43 changes: 31 additions & 12 deletions src/Service/LokiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace Drupal\os2web_audit\Service;

use Drupal\os2web_audit\Exception\ConnectionException;
use Drupal\os2web_audit\Exception\AuditException;

/**
* Class LokiClient.
*
Expand Down Expand Up @@ -57,7 +60,8 @@ public function __construct(
/**
* {@inheritdoc}
*
* @throws \JsonException
* @throws \Drupal\os2web_audit\Exception\ConnectionException
* @throws \Drupal\os2web_audit\Exception\AuditException
*/
public function send(string $label, int $epoch, string $line, array $metadata = []): void {
$packet = [
Expand Down Expand Up @@ -103,20 +107,31 @@ private function getEntrypoint(string $entrypoint): string {
* @param array<string, mixed> $packet
* The packet to send.
*
* @throws \JsonException
* If unable to encode the packet to JSON.
* @throws \LogicException
* @throws ConnectionException
* If unable to connect to the Loki endpoint.
* @throws AuditException
* Errors in logging the packet
*/
private function sendPacket(array $packet): void {
$payload = json_encode($packet, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$url = sprintf('%s/loki/api/v1/push', $this->entrypoint);
try {
$payload = json_encode($packet, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} catch (\JsonException $e) {
throw new AuditException(
message: 'Payload could not be encoded.',
previous: $e,
pluginName: 'Loki',
);
}

if (NULL === $this->connection) {
$url = sprintf('%s/loki/api/v1/push', $this->entrypoint);
$this->connection = curl_init($url);

if (FALSE === $this->connection) {
throw new \LogicException('Unable to connect to ' . $url);
throw new ConnectionException(
message: 'Unable to connect to ' . $url,
pluginName: 'Loki',
);
}
}

Expand Down Expand Up @@ -145,14 +160,18 @@ private function sendPacket(array $packet): void {
$result = curl_exec($this->connection);

if (FALSE === $result) {
throw new \RuntimeException('Error sending packet to Loki');
throw new ConnectionException(
message: 'Error sending packet to Loki',
pluginName: 'Loki',
);
}

if (curl_errno($this->connection)) {
echo 'Curl error: ' . curl_error($this->connection);
}
else {
echo 'Curl result: ' . $result;
throw new AuditException(
message: curl_error($this->connection),
code: curl_errno($this->connection),
pluginName: 'Loki',
);
}
}
}
Expand Down

0 comments on commit d38dd28

Please sign in to comment.