Skip to content

Commit

Permalink
[DDS-1053] Added the Tide Logs module.
Browse files Browse the repository at this point in the history
When enabled and a Collector Code provided, it forwards logs to the SumoLogic HTTP collector.
  • Loading branch information
yusufhm committed Feb 18, 2022
0 parents commit a7d0529
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 0 deletions.
18 changes: 18 additions & 0 deletions config/schema/tide_logs.schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Schema for the configuration files of the tide_logs module.

tide_logs.settings:
type: config_object
label: 'Tide logs settings'
mapping:
enable:
type: boolean
label: 'Enabled'
sumologic_collector_code:
type: string
label: 'Sumo Logic collector code'
sumologic_category:
type: string
label: 'Sumo Logic category'
debug:
type: boolean
label: 'Show debug messages'
65 changes: 65 additions & 0 deletions src/Form/TideLogsSettingsForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Drupal\tide_logs\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\tide_logs\Logger\TideLogsLoggerFactory;

/**
* Settings form for tide_logs.
*/
class TideLogsSettingsForm extends ConfigFormBase {

/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return ['tide_logs.settings'];
}

/**
* {@inheritdoc}
*/
public function getFormId() {
return 'tide_logs_settings_form';
}

/**
* Build the form.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('tide_logs.settings');

$form['enable'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enable module'),
'#description' => $this->t('Send logs to SumoLogic.'),
'#default_value' => $config->get('enable'),
];

$form['description'] = [
'#prefix' => '<div class="ll-settings-description">',
'#suffix' => '</div>',
'#markup' => $this->t(
'<p>Current settings for the Tide Logs module. The defaults are set in configuration, this page is meant primarily for troubleshooting.</p>' .
'<ul>' .
'<li><b>' . $this->t('SumoLogic category') . ':</b> ' . TideLogsLoggerFactory::getSumoLogicCategory($this->configFactory()) . '</li>' .
'</ul>'
),
];

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

/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$this->config('tide_logs.settings')
->set('enable', $form_state->getValue('enable'))
->save();
}

}
70 changes: 70 additions & 0 deletions src/Logger/TideLogsLoggerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace Drupal\tide_logs\Logger;

use GuzzleHttp\Client;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Logger\LogMessageParserInterface;
use Drupal\lagoon_logs\Logger\LagoonLogsLoggerFactory;

class TideLogsLoggerFactory {
const TIDE_LOGS_DEFAULT_SUMOLOGIC_CATEGORY = 'sdp/dev/tide';

public static function create(
ConfigFactoryInterface $config,
LogMessageParserInterface $parser,
Client $http_client
) {
return new TideLogsLogger(
self::getSumoLogicCollectorCode($config),
self::getSumoLogicCategory($config),
self::getLogIdentifier($config),
$parser,
$http_client,
self::getDebug($config)
);
}

public static function getLogIdentifier(ConfigFactoryInterface $config) {
$enabled = $config->get('tide_logs.settings')->get('enable');
return $enabled ?
implode('-', [
getenv('LAGOON_PROJECT') ?: LagoonLogsLoggerFactory::LAGOON_LOGS_DEFAULT_LAGOON_PROJECT,
getenv('LAGOON_GIT_SAFE_BRANCH') ?: LagoonLogsLoggerFactory::LAGOON_LOGS_DEFAULT_SAFE_BRANCH,
]) :
FALSE;
}

public static function getSumoLogicCollectorCode(ConfigFactoryInterface $config) {
$enabled = $config->get('tide_logs.settings')->get('enable');
if (!$enabled) {
return FALSE;
}
// Allow collector code to be specified via environment.
$config_code = $config->get('tide_logs.settings')->get('sumologic_collector_code');
return $config_code ?: getenv('SUMOLOGIC_COLLECTOR_CODE');
}

public static function getSumoLogicCategory(ConfigFactoryInterface $config) {
$enabled = $config->get('tide_logs.settings')->get('enable');
if (!$enabled) {
return FALSE;
}
// Allow category to be specified via environment, otherwise default.
$category = $config->get('tide_logs.settings')->get('sumologic_category');
if (!$category) {
$category = getenv('SUMOLOGIC_CATEGORY');
}
return $category ?: static::TIDE_LOGS_DEFAULT_SUMOLOGIC_CATEGORY;
}

public static function getDebug(ConfigFactoryInterface $config)
{
$enabled = $config->get('tide_logs.settings')->get('enable');
if (!$enabled) {
return FALSE;
}
return $config->get('tide_logs.settings')->get('debug');
}

}
69 changes: 69 additions & 0 deletions src/Monolog/Handler/SumoLogicHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php declare(strict_types=1);

namespace Drupal\tide_logs\Monolog\Handler;

use Monolog\Logger;
use GuzzleHttp\Client;
use Monolog\Formatter\JsonFormatter;
use Monolog\Formatter\FormatterInterface;
use Monolog\Handler\AbstractProcessingHandler;

class SumoLogicHandler extends AbstractProcessingHandler {

protected const HOST = 'collectors.au.sumologic.com';
protected const ENDPOINT = 'receiver/v1/http';

/**
* The GuzzleHttp Client.
*/
protected Client $client;

/** @var string */
protected $collectorCode;

/** @var string */
protected $host;

/** @var string */
protected $category;

/**
* @param string $collector_code
* Collector code supplied by Sumo Logic.
*/
public function __construct(string $collector_code, string $category, string $host = "", $level = Logger::DEBUG, bool $bubble = true)
{
$this->collectorCode = $collector_code;
$this->host = $host;
$this->category = $category;
parent::__construct($level, $bubble);
}

/**
* Sets the GuzzleHttp Client.
*/
public function setClient(Client $client)
{
$this->client = $client;
}

protected function write(array $record): void
{
$url = sprintf("https://%s/%s/%s/", static::HOST, static::ENDPOINT, $this->collectorCode);

$headers = ['X-Sumo-Category' => $this->category];
if ($this->host) {
$headers['X-Sumo-Host'] = $this->host;
}

$this->client->post($url, [
'headers' => $headers,
'json' => $record,
]);
}

protected function getDefaultFormatter(): FormatterInterface
{
return new JsonFormatter();
}
}
9 changes: 9 additions & 0 deletions tide_logs.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: Tide Logs
description: Simple monolog wrapper for Sumo Logic.
package: Tide
configure: tide_logs.settings
type: module
core_version_requirement: ^8 || ^9

dependencies:
- lagoon_logs:lagoon_logs
5 changes: 5 additions & 0 deletions tide_logs.links.menu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
system.tide_logs_settings:
title: 'Tide Logs settings'
parent: system.admin_config_development
description: 'Configure Tide Logs.'
route_name: tide_logs.settings
7 changes: 7 additions & 0 deletions tide_logs.routing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
tide_logs.settings:
path: '/admin/config/development/tide_logs'
defaults:
_form: '\Drupal\tide_logs\Form\TideLogsSettingsForm'
_title: 'Tide Logs configuration'
requirements:
_permission: 'administer site configuration'
7 changes: 7 additions & 0 deletions tide_logs.services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
logger.tide_logs:
class: Drupal\tide_logs\Logger\TideLogsLogger
factory: Drupal\tide_logs\Logger\TideLogsLoggerFactory::create
tags:
- { name: logger }
arguments: ['@config.factory', '@logger.log_message_parser', '@http_client']

0 comments on commit a7d0529

Please sign in to comment.