Skip to content
4 changes: 2 additions & 2 deletions docs/tutorials/add-logger-adapter.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Adding a new logger adapter 💾

This document is part of the Utopia contributors' guide. Before you continue reading this document make sure you have read the [Code of Conduct](https://raw.githubusercontent.com/utopia-php/logger/main/CODE_OF_CONDUCT.md) and the [Contributing Guide](https://raw.githubusercontent.com/utopia-php/logger/main/CONTRIBUTING.md).
This document is part of the Utopia contributors' guide. Before you continue reading this document make sure you have read the [Code of Conduct](../../CODE_OF_CONDUCT.md) and the [Contributing Guide](../../CONTRIBUTING.md).

## Getting started

Expand Down Expand Up @@ -139,7 +139,7 @@ In `src/Logger/Logger.php` update variable `const PROVIDERS` to include your pro

## 3. Test your adapter

After you finished adding your new adapter, you should write a proper test for it. To do that, you enter `tests/LoggerTests.php` and take a look at `testAdapters()` method. In there, we already build a whole log object and all you need to do is to push the log using your provider. Take a look at how test for already existign adapter looks or use template below:
After you finished adding your new adapter, you should write a proper test for it. To do that, you enter `tests/LoggerTests.php` and take a look at `testAdapters()` method. In there, we already build a whole log object and all you need to do is to push the log using your provider. Take a look at how test for already existing adapter looks or use the template below:

```php
// Test [ADAPTER_NAME]
Expand Down
160 changes: 160 additions & 0 deletions src/Logger/Adapter/HoneyBadger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?php

namespace Utopia\Logger\Adapter;

use Exception;
use Utopia\Logger\Adapter;
use Utopia\Logger\Log;
use Utopia\Logger\Logger;

// Reference Material
// https://docs.honeybadger.io/api/reporting-exceptions

class HoneyBadger extends Adapter
{
protected string $apiKey;

/**
* Return unique adapter name
*
* @return string
*/
public static function getName(): string
{
return "honeyBadger";
}

/**
* Push log to external provider
*
* @param Log $log
* @return int
*/
public function push(Log $log): int
{
$params = [];

foreach ($log->getExtra() as $paramKey => $paramValue) {
$params[$paramKey] = var_export($paramValue, true);
}

$breadcrumbsObject = $log->getBreadcrumbs();
$breadcrumbsArray = [];

foreach ($breadcrumbsObject as $breadcrumb) {
\array_push($breadcrumbsArray, [
'category' => $breadcrumb->getCategory(),
'timestamp' => \intval($breadcrumb->getTimestamp()),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this recently, but got an error in Honeybadger because they expect this to be a string like 2020-01-27T12:37:31.616-08:00. Would you please update this to be a ISO-8601 formatted timestamp in UTC?

'message' => $breadcrumb->getMessage(),
'metadata' => [
'exception' => $breadcrumb->getType()
]
]);
}

$requestBody = [
'notifier' => [
'name' => 'utopia-logger',
'url' => 'https://github.com/utopia-php/logger',
'tags' => $log->getTags(),
'version' => $log->getVersion(),
],
'error' => [
'class' => $log->getType(),
'message' => $log->getMessage(),
'backtrace' => [],
//TODO: Add causes
'causes' => []
],
'breadcrumbs' => [
"enabled" => true,
"trail" => $breadcrumbsArray
],

'request' => [
'params' => $params,
'action' => $log->getAction(),
'context' => empty($log->getUser()) ? null : [
'user_id' => $log->getUser()->getId(),
'user_email' => $log->getUser()->getEmail(),
]

],
'server' => [
'project_root' => $log->getServer(),
'environment_name' => $log->getEnvironment(),
'hostname' => $log->getServer(),
],

];


// init curl object
$ch = \curl_init();

// define options
$optArray = array(
CURLOPT_URL => 'https://api.honeybadger.io/v1/notices',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => \json_encode($requestBody),
CURLOPT_HEADEROPT => \CURLHEADER_UNIFIED,
CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'X-API-Key: ' . $this->apiKey, 'Accept: application/json', 'User-Agent: utopia-logger/' . Logger::LIBRARY_VERSION)
);

// apply those options
\curl_setopt_array($ch, $optArray);

// execute request and get response
$result = \curl_exec($ch);
$response = \curl_getinfo($ch, \CURLINFO_HTTP_CODE);


if (!$result && $response >= 400) {
throw new Exception("Log could not be pushed with status code " . $response . ": " . \curl_error($ch));
}

\curl_close($ch);

return $response;
}
/**
* HoneyBadger constructor.
*
* @param string $configKey
*/
public function __construct(string $configKey)
{
$this->apiKey = $configKey;
}

public function getSupportedTypes(): array
{
return [
Log::TYPE_INFO,
Log::TYPE_DEBUG,
Log::TYPE_VERBOSE,
Log::TYPE_WARNING,
Log::TYPE_ERROR
];
}

public function getSupportedEnvironments(): array
{
return [
Log::ENVIRONMENT_STAGING,
Log::ENVIRONMENT_PRODUCTION,
];
}

public function getSupportedBreadcrumbTypes(): array
{
return [
Log::TYPE_INFO,
Log::TYPE_DEBUG,
Log::TYPE_VERBOSE,
Log::TYPE_WARNING,
Log::TYPE_ERROR
];
}
}
3 changes: 2 additions & 1 deletion src/Logger/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class Logger
"raygun",
"sentry",
"appSignal",
"logOwl"
"logOwl",
"honeyBadger"
];

/**
Expand Down
14 changes: 10 additions & 4 deletions tests/LoggerTest.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use PHPUnit\Framework\TestCase;

use Utopia\Logger\Adapter\AppSignal;
use Utopia\Logger\Adapter\HoneyBadger;
use Utopia\Logger\Adapter\LogOwl;
use Utopia\Logger\Adapter\Raygun;
use Utopia\Logger\Adapter\Sentry;
Expand Down Expand Up @@ -75,11 +76,11 @@ public function testLog(): void
self::assertEquals("aws-001", $log->getServer());

$log->addExtra('isLoggedIn', false);
self::assertEquals([ 'isLoggedIn' => false ], $log->getExtra());
self::assertEquals(['isLoggedIn' => false], $log->getExtra());

$log->addTag('authMethod', 'session');
$log->addTag('authProvider', 'basic');
self::assertEquals([ 'authMethod' => 'session', 'authProvider' => 'basic' ], $log->getTags());
self::assertEquals(['authMethod' => 'session', 'authProvider' => 'basic'], $log->getTags());

$userId = "myid123";
$user = new User($userId);
Expand All @@ -94,7 +95,6 @@ public function testLog(): void
self::assertEquals("http", $log->getBreadcrumbs()[0]->getCategory());
self::assertEquals("DELETE /api/v1/database/abcd1234/efgh5678", $log->getBreadcrumbs()[0]->getMessage());
self::assertEquals($timestamp, $log->getBreadcrumbs()[0]->getTimestamp());

}

/**
Expand Down Expand Up @@ -141,7 +141,7 @@ public function testAdapters(): void
$log->setType(Log::TYPE_ERROR);
$log->setVersion("0.11.5");
$log->setMessage("Document efgh5678 not found");
$log->setUser(new User("efgh5678"));
$log->setUser(new User("efgh5678", "abc@test.com", "John Doe"));
$log->addBreadcrumb(new Breadcrumb(Log::TYPE_DEBUG, "http", "DELETE /api/v1/database/abcd1234/efgh5678", \microtime(true) - 500));
$log->addBreadcrumb(new Breadcrumb(Log::TYPE_DEBUG, "auth", "Using API key", \microtime(true) - 400));
$log->addBreadcrumb(new Breadcrumb(Log::TYPE_INFO, "auth", "Authenticated with * Using API Key", \microtime(true) - 350));
Expand Down Expand Up @@ -184,5 +184,11 @@ public function testAdapters(): void
$logger = new Logger($adapter);
$response = $logger->addLog($log);
$this->assertEquals(200, $response);

// Test HoneyBadger
$adapter = new HoneyBadger(\getenv("TEST_HONEYBADGER_KEY"));
Comment thread
2002Bishwajeet marked this conversation as resolved.
Outdated
$logger = new Logger($adapter);
$response = $logger->addLog($log);
Comment thread
2002Bishwajeet marked this conversation as resolved.
$this->assertEquals(201, $response);
}
}