Skip to content
This repository was archived by the owner on Jul 7, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/Agent/CreateDataDogAgentLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Myli\DatadogLogger\Agent;

use Exception;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;

/**
* Class CreateDataDogAgentLogger
*
* @package Myli\DatadogLogger
* @author Aurélien SCHILTZ <aurelien@myli.io>
* @copyright 2016-2019 Myli
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class CreateDataDogAgentLogger
{
/**
* Create DataDog Agent Logger
*
* @param array $config
*
* @return Logger
* @throws Exception
*/
public function __invoke(array $config)
{
if (empty($config['path'])) {
$config['path'] = storage_path('logs/laravel-json-datadog.log');
}

if (\is_string($config['path'])) {
$pathInfo = pathinfo($config['path']);
$config['path'] = str_replace(
$pathInfo['filename'],
$pathInfo['filename'] . '-' . php_sapi_name(),
$config['path']
);
}

$streamHandler = new StreamHandler(
$config['path'],
$config['level'] ?? Logger::DEBUG,
$config['bubble'] ?? true,
$config['permission'] ?? null,
$config['lock'] ?? false
);

$streamHandler->setFormatter(new DataDogAgentFormatter());

return (new Logger('datadog-agent'))->pushHandler($streamHandler);
}
}
35 changes: 35 additions & 0 deletions src/Agent/DataDogAgentFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Myli\DatadogLogger\Agent;

use Illuminate\Log\Logger;
use Myli\DatadogLogger\DataDogFormatter;

/**
* Class DataDogAgentFormatter
*
* @package Myli\DatadogLogger\Agent
* @author Aurélien SCHILTZ <aurelien@myli.io>
* @copyright 2016-2019 Myli
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class DataDogAgentFormatter extends DataDogFormatter
{
/**
* Set this formatter to the logger
*
* @param $logger
*
* @return void
*/
public function __invoke(Logger $logger)
{
/**
* @var \Monolog\Logger $logger We can assume it's a monolog logger since
* Laravel's Logger has _call function calling the logger directly
*/
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter($this);
}
}
}
24 changes: 16 additions & 8 deletions src/CreateDataDogLogger.php → src/Api/CreateDataDogApiLogger.php
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
<?php

namespace Myli\DatadogLogger;
namespace Myli\DatadogLogger\Api;

use Exception;
use Monolog\Handler\MissingExtensionException;
use Monolog\Logger;
use Myli\DatadogLogger\ApiKeyNotFoundException;

/**
* Class CreateDataDogLogger
* Class CreateDataDogApiLogger
*
* @package Myli\DatadogLogger
* @package Myli\DatadogLogger\Api
* @author Aurélien SCHILTZ <aurelien@myli.io>
* @copyright 2016-2019 Myli
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class CreateDataDogLogger
class CreateDataDogApiLogger
{
/**
* Create DataDogLogger
* Create the DataDog Api Logger
*
* @param array $config
*
* @return Logger
* @throws ApiKeyNotFoundException
* @throws MissingExtensionException
*/
public function __invoke(array $config)
Expand All @@ -30,10 +33,15 @@ public function __invoke(array $config)
$isEuropeRegion = true;
}
if (empty($config['apiKey'])) {
throw new \Exception('apiKey not set for DataDogLogger');
throw new ApiKeyNotFoundException();
}
$dataDogHandler = new DataDogHandler($config['apiKey'], $isEuropeRegion, $config['level'] ?? Logger::DEBUG, $config['bubble'] ?? true);
$dataDogHandler = new DataDogApiHandler(
$config['apiKey'],
$isEuropeRegion,
$config['level'] ?? Logger::DEBUG,
$config['bubble'] ?? true
);

return (new Logger('datadog'))->pushHandler($dataDogHandler);
return (new Logger('datadog-api'))->pushHandler($dataDogHandler);
}
}
70 changes: 35 additions & 35 deletions src/DataDogHandler.php → src/Api/DataDogApiHandler.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Myli\DatadogLogger;
namespace Myli\DatadogLogger\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
Expand All @@ -10,14 +10,14 @@
use Monolog\Logger;

/**
* Class DataDogHandler
* Class DataDogApiHandler
*
* @package DatadogLogger
* @package Myli\DatadogLogger\Api
* @author Aurélien SCHILTZ <aurelien@myli.io>
* @copyright 2016-2019 Myli
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class DataDogHandler extends AbstractProcessingHandler
class DataDogApiHandler extends AbstractProcessingHandler
{
protected const HOST_US = 'http-intake.logs.datadoghq.com';
protected const HOST_EU = 'http-intake.logs.datadoghq.eu';
Expand Down Expand Up @@ -48,41 +48,31 @@ class DataDogHandler extends AbstractProcessingHandler
public function __construct(string $token, bool $europeRegion = false, $level = Logger::DEBUG, bool $bubble = true)
{
if (!extension_loaded('curl')) {
throw new MissingExtensionException('The curl extension is needed to use the DataDogHandler');
throw new MissingExtensionException('The curl extension is needed to use the DataDogApiHandler');
}
$this->token = $token;
$this->host = $europeRegion ? self::HOST_EU : self::HOST_US;
parent::__construct($level, $bubble);
}

/**
* Get the Client
* Get the Token
*
* @return ClientInterface
* @return string
*/
protected function getHttpClient() : ClientInterface
public function getToken()
{
if (!$this->httpClient) {
$this->httpClient = $this->initHttpClient();
}

return $this->httpClient;
return $this->token;
}

/**
* Init a Guzzle Client
* Get the region of this DataDogApiHandler
*
* @return Client
* @return string
*/
private function initHttpClient()
public function getRegion()
{
$guzzleClient = new Client([
'base_uri' => sprintf("https://%s/v1/input/%s", $this->host, $this->token),
'http_errors' => false,// we don't want the logger to stop the application for a failed log
'debug' => false,
]);

return $guzzleClient;
return $this->host === self::HOST_EU ? 'eu' : 'us';
}

/**
Expand Down Expand Up @@ -121,32 +111,42 @@ protected function send(string $data) : void
}

/**
* Get the DataDogFormatter
* Get the Client
*
* @return DataDogFormatter
* @return ClientInterface
*/
protected function getDefaultFormatter() : DataDogFormatter
protected function getHttpClient() : ClientInterface
{
return new DataDogFormatter();
if (!$this->httpClient) {
$this->httpClient = $this->initHttpClient();
}

return $this->httpClient;
}

/**
* Get the Token
* Init a Guzzle Client
*
* @return string
* @return Client
*/
public function getToken()
private function initHttpClient()
{
return $this->token;
$guzzleClient = new Client([
'base_uri' => sprintf("https://%s/v1/input/%s", $this->host, $this->token),
'http_errors' => false,// we don't want the logger to stop the application for a failed log
'debug' => false,
]);

return $guzzleClient;
}

/**
* Get the region of this DataDogHandler
* Get the DataDogFormatter
*
* @return string
* @return DataDogFormatter
*/
public function getRegion()
protected function getDefaultFormatter() : DataDogFormatter
{
return $this->host === self::HOST_EU ? 'eu' : 'us';
return new DataDogFormatter();
}
}
11 changes: 11 additions & 0 deletions src/ApiKeyNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Myli\DatadogLogger;

class ApiKeyNotFoundException extends \Exception
{
public function __construct()
{
parent::__construct('apiKey not set for DataDogLogger', 500, null);
}
}
32 changes: 9 additions & 23 deletions src/DataDogFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,21 @@

namespace Myli\DatadogLogger;

use Illuminate\Log\Logger;
use DateTime;
use Monolog\Formatter\JsonFormatter;

/**
* Class DataDogFormatter
*
* @package DatadogLogger
* @package Myli\DatadogLogger
* @author Aurélien SCHILTZ <aurelien@myli.io>
* @copyright 2016-2019 Myli
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class DataDogFormatter extends JsonFormatter
{

/**
* Set this formatter to the logger
*
* @param $logger
*
* @return void
*/
public function __invoke(Logger $logger)
{
/**
* @var \Monolog\Logger $logger We can assume it's a monolog logger since
* Laravel's Logger has _call function calling the logger directly
*/
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter($this);
}
}
const LARAVEL_LOG_DATETIME_KEY = 'datetime';

/**
* Appends every variable needed by DataDog
Expand All @@ -47,18 +31,20 @@ public function __invoke(Logger $logger)
*/
public function format(array $record)
{
if (isset($record['datetime']) && ($record['datetime'] instanceof \DateTime)) {
if (isset($record[self::LARAVEL_LOG_DATETIME_KEY]) &&
($record[self::LARAVEL_LOG_DATETIME_KEY] instanceof DateTime)) {
/**
* @var \DateTime $dateTimeObj
* @var DateTime $dateTimeObj
*/
$dateTimeObj = $record['datetime'];
$record['published_date'] = $dateTimeObj->format(\DateTime::ISO8601);
$dateTimeObj = $record[self::LARAVEL_LOG_DATETIME_KEY];
$record['published_date'] = $dateTimeObj->format(DateTime::ISO8601);
}

if (isset($record['level_name'])) {
$record['status'] = $record['level_name'];
}
$record['ddsource'] = 'php-' . php_sapi_name();
$record['source'] = 'php-' . php_sapi_name();
$record['service'] = config('app.name');
$record['hostname'] = gethostname();

Expand Down
Loading