From fe80f6510bd60c85a17f2fd69f8f4b646da86faa Mon Sep 17 00:00:00 2001 From: Michael Zhou Date: Mon, 31 Oct 2022 19:47:44 -0700 Subject: [PATCH 1/2] Added Dynatrace Adaptor --- src/Logger/Adapter/Dynatrace.php | 182 +++++++++++++++++++++++++++++++ src/Logger/Logger.php | 3 +- tests/LoggerTest.php | 7 ++ 3 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 src/Logger/Adapter/Dynatrace.php diff --git a/src/Logger/Adapter/Dynatrace.php b/src/Logger/Adapter/Dynatrace.php new file mode 100644 index 0000000..b86e726 --- /dev/null +++ b/src/Logger/Adapter/Dynatrace.php @@ -0,0 +1,182 @@ + Access tokens) + */ + protected string $apiKey; + + /** + * @var string (required, this is part of Dynatrace endpoint: 'https://{{THIS_PART}}.live.dynatrace.com/api/v2/events/ingest') + */ + protected string $environmentId; + + /** + * Return unique adapter name + * + * @return string + */ + public static function getName(): string + { + return "dynatrace"; + } + + /** + * Push log to external provider + * + * @param Log $log + * @return int + * @throws Exception + */ + public function push(Log $log): int + { + $id = empty($log->getUser()) ? null : $log->getUser()->getId(); + $email = empty($log->getUser()) ? null : $log->getUser()->getEmail(); + $username = empty($log->getUser()) ? null : $log->getUser()->getUsername(); + + $breadcrumbsObject = $log->getBreadcrumbs(); + $breadcrumbsArray = []; + + foreach ($breadcrumbsObject as $breadcrumb) { + \array_push($breadcrumbsArray, [ + 'type' => $breadcrumb->getType(), + 'category' => $breadcrumb->getCategory(), + 'message' => $breadcrumb->getMessage(), + 'timestamp' => \intval($breadcrumb->getTimestamp()) + ]); + } + + $stackFrames = []; + + if (isset($log->getExtra()['detailedTrace'])) { + foreach ($log->getExtra()['detailedTrace'] as $trace) { + \array_push($stackFrames, [ + 'filename' => $trace['file'], + 'lineno' => $trace['line'], + 'function' => $trace['function'], + ]); + } + } + + $tags = array(); + + foreach ($log->getTags() as $tagKey => $tagValue) { + $tags[$tagKey] = $tagValue; + } + + if (!empty($log->getType())) { + $tags['type'] = $log->getType(); + } + if (!empty($log->getVersion())) { + $tags['version'] = $log->getVersion(); + } + if (!empty($log->getEnvironment())) { + $tags['environment'] = $log->getEnvironment(); + } + if (!empty($log->getAction())) { + $tags['action'] = $log->getAction(); + } + if (!empty($log->getNamespace())) { + $tags['namespace'] = $log->getNamespace(); + } + if (!empty($log->getServer())) { + $tags['server'] = $log->getServer(); + } + + $tags['userId'] = $id; + $tags['userEmail'] = $email; + $tags['userName'] = $username; + $tags['stacktrace'] = $stackFrames; + $tags['breadcrumbs'] = $breadcrumbsArray; + + // prepare log (request body) + $requestBody = [ + 'eventType' => 'ERROR_EVENT', + 'title' => $log->getMessage(), + 'startTime' => \intval($log->getTimestamp()), + 'endTime' => \intval($log->getTimestamp()), + 'properties' => $tags + ]; + + // init curl object + $ch = \curl_init(); + + // define options + $optArray = array( + CURLOPT_URL => 'https://' . $this->environmentId . '.live.dynatrace.com/api/v2/events/ingest', + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => \json_encode($requestBody), + CURLOPT_HEADEROPT => \CURLHEADER_UNIFIED, + CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Authorization: Api-Token ' . $this->apiKey) + ); + + // 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; + } + + /** + * Dynatrace constructor. + * + * @param string $configKey + */ + public function __construct(string $configKey) + { + $configChunks = \explode(";", $configKey); + $this->apiKey = $configChunks[0]; + $this->environmentId = $configChunks[1]; + } + + 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 + ]; + } +} \ No newline at end of file diff --git a/src/Logger/Logger.php b/src/Logger/Logger.php index d81a5db..264682a 100644 --- a/src/Logger/Logger.php +++ b/src/Logger/Logger.php @@ -11,7 +11,8 @@ class Logger "raygun", "sentry", "appSignal", - "logOwl" + "logOwl", + "dynatrace" ]; /** diff --git a/tests/LoggerTest.php b/tests/LoggerTest.php index 409853f..02c1f9c 100755 --- a/tests/LoggerTest.php +++ b/tests/LoggerTest.php @@ -4,6 +4,7 @@ use PHPUnit\Framework\TestCase; use Utopia\Logger\Adapter\AppSignal; +use Utopia\Logger\Adapter\Dynatrace; use Utopia\Logger\Adapter\LogOwl; use Utopia\Logger\Adapter\Raygun; use Utopia\Logger\Adapter\Sentry; @@ -180,5 +181,11 @@ public function testAdapters() $logger = new Logger($adapter); $response = $logger->addLog($log); $this->assertEquals(200, $response); + + // Test Dynatrace + $adapter = new Dynatrace(\getenv("TEST_DYNATRACE_KEY") . ';' . \getenv("TEST_DYNATRACE_ENV_ID")); + $logger = new Logger($adapter); + $response = $logger->addLog($log); + $this->assertEquals(201, $response); } } From 3eb1fc075558dd75a6d94e450f93875f624f203c Mon Sep 17 00:00:00 2001 From: Michael Zhou Date: Thu, 2 Mar 2023 01:04:41 -0800 Subject: [PATCH 2/2] Modify test for Dynatrace logger --- tests/LoggerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/LoggerTest.php b/tests/LoggerTest.php index ef647f3..2181ea8 100755 --- a/tests/LoggerTest.php +++ b/tests/LoggerTest.php @@ -184,7 +184,7 @@ public function testAdapters(): void $this->assertEquals(200, $response); // Test Dynatrace - $adapter = new Dynatrace(\getenv("TEST_DYNATRACE_KEY").';'.\getenv("TEST_DYNATRACE_ENV_ID")); + $adapter = new Dynatrace(\getenv('TEST_DYNATRACE_KEY').';'.\getenv('TEST_DYNATRACE_ENV_ID')); $logger = new Logger($adapter); $response = $logger->addLog($log); $this->assertEquals(201, $response);