From 2c17a4eef5a7bdc67ce71b1321e22d70c2e86eba Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Thu, 4 Jul 2024 22:42:45 -0400 Subject: [PATCH 01/13] stub service provider --- src/LaravelStatsDAdapterServiceProvider.php | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/LaravelStatsDAdapterServiceProvider.php diff --git a/src/LaravelStatsDAdapterServiceProvider.php b/src/LaravelStatsDAdapterServiceProvider.php new file mode 100644 index 0000000..31a3188 --- /dev/null +++ b/src/LaravelStatsDAdapterServiceProvider.php @@ -0,0 +1,10 @@ + Date: Fri, 5 Jul 2024 00:01:33 -0400 Subject: [PATCH 02/13] adapter manager, example config, untested service provider --- composer.json | 10 ++- config/statsd-adapter.php | 45 +++++++++++ src/AdapterManager.php | 90 +++++++++++++++++++++ src/LaravelStatsDAdapterServiceProvider.php | 10 --- src/StatsDAdapterServiceProvider.php | 28 +++++++ 5 files changed, 169 insertions(+), 14 deletions(-) create mode 100644 config/statsd-adapter.php create mode 100644 src/AdapterManager.php delete mode 100644 src/LaravelStatsDAdapterServiceProvider.php create mode 100644 src/StatsDAdapterServiceProvider.php diff --git a/composer.json b/composer.json index dce0af8..edb04a6 100644 --- a/composer.json +++ b/composer.json @@ -21,17 +21,19 @@ }, "require": { "php": "^8.2", - "cosmastech/statsd-client-adapter": "^0.0.1", - "illuminate/support": "^10.0|^11.0" + "cosmastech/statsd-client-adapter": "^0.0.2", + "illuminate/support": "^10.0|^11.0", + "illuminate/contracts": "^10.0|^11.0" }, "require-dev": { "phpunit/phpunit": "^11.2.5", - "friendsofphp/php-cs-fixer": "^3.59" + "friendsofphp/php-cs-fixer": "^3.59", + "league/statsd": "^2.0.0" }, "extra": { "laravel": { "providers": [ - "Cosmastech\\LaravelStatsDAdapter\\LaravelStatsDAdapterServiceProvider" + "Cosmastech\\LaravelStatsDAdapter\\StatsDAdapterServiceProvider" ] } }, diff --git a/config/statsd-adapter.php b/config/statsd-adapter.php new file mode 100644 index 0000000..f10c5e9 --- /dev/null +++ b/config/statsd-adapter.php @@ -0,0 +1,45 @@ + env("STATSD_ADAPTER_DEFAULT", "memory"), + + /** + * You may name your channel anything you wish. Valid drivers are: + * memory + * league + * datadog + * log_datadog + */ + "channels" => [ + "memory" => [ + "driver" => "memory", + ], + "league" => [ + "driver" => "league", + "instance_id" => null, + 'host' => env('STATSD_HOST', '127.0.0.1'), + 'port' => env('STATSD_PORT', 8125), + 'namespace' => env('STATSD_NAMESPACE', ''), + 'throwConnectionExceptions' => true, + ], + "datadog" => [ + "driver" => "datadog", + "host" => env("DD_AGENT_HOST"), + "port" => env("DD_DOGSTATSD_PORT"), + "socket_path" => null, + "datadog_host" => null, + "decimal_precision" => null, + "global_tags" => [], + "metric_prefix" => null, + "disable_telemetry" => null, + ], + "log_datadog" => [ + "driver" => "log_datadog", + "log_level" => "debug", + "decimal_precision" => null, + "global_tags" => [], + "metric_prefix" => null, + "disable_telemetry" => null, + ], + ], +]; diff --git a/src/AdapterManager.php b/src/AdapterManager.php new file mode 100644 index 0000000..5819385 --- /dev/null +++ b/src/AdapterManager.php @@ -0,0 +1,90 @@ +config = $this->app->get('config'); + } + + /** + * @inheritDoc + */ + public function getDefaultInstance() + { + return $this->config->get("statsd-adapter.default"); + } + + /** + * @inheritDoc + */ + public function setDefaultInstance($name) + { + // not sure if this is needed + } + + /** + * @inheritDoc + */ + public function getInstanceConfig($name) + { + return $this->config->get("statsd-adapter.channels.{$name}"); + } + + + protected function createMemoryAdapter(array $config): InMemoryClientAdapter + { + $wrapperClock = new WrapperClock(FactoryImmutable::getDefaultInstance()); + + return new InMemoryClientAdapter($wrapperClock); + } + + protected function createLog_datadogAdapter(array $config): DatadogStatsDClientAdapter + { + $logLevel = $config['log_level'] ?? 'debug'; + + return new DatadogStatsDClientAdapter( + new DatadogLoggingClient($this->app->make('log'), $logLevel, $config) + ); + } + + protected function createDatadogAdapter(array $config): DatadogStatsDClientAdapter + { + return new DatadogStatsDClientAdapter(new DogStatsd($config)); + } + + /** + * @throws ConfigurationException + */ + protected function createLeagueAdapter(array $config): LeagueStatsDClientAdapter + { + $leagueClient = new Client($config['instance_id'] ?? null); + $leagueClient->configure($config); + + return new LeagueStatsDClientAdapter($leagueClient, new SampleRateSendDecider()); + } +} diff --git a/src/LaravelStatsDAdapterServiceProvider.php b/src/LaravelStatsDAdapterServiceProvider.php deleted file mode 100644 index 31a3188..0000000 --- a/src/LaravelStatsDAdapterServiceProvider.php +++ /dev/null @@ -1,10 +0,0 @@ -app->singleton( + AdapterManager::class, + fn ($app) => new AdapterManager($app) + ); + + $this->app->singleton( + StatsDClientAdapter::class, + fn ($app) => $app->make(AdapterManager::class)->instance() + ); + } + + public function provides(): array + { + return [AdapterManager::class, StatsDClientAdapter::class]; + } +} From 94a291dac1fc9bc7f1c5fcb2607d204ecefe6b9f Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 6 Jul 2024 10:05:00 -0400 Subject: [PATCH 03/13] adapter manager updates --- src/AdapterManager.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/AdapterManager.php b/src/AdapterManager.php index 5819385..e31e9dd 100644 --- a/src/AdapterManager.php +++ b/src/AdapterManager.php @@ -18,15 +18,21 @@ class AdapterManager extends MultipleInstanceManager { protected $driverKey = 'adapter'; + protected string $defaultInstanceName; + /** * The configuration repository instance. - * + * @todo remove this after laravel/framework release 2024-07-06 * @var \Illuminate\Contracts\Config\Repository */ protected $config; + /** + * @inheritDoc + */ public function __construct($app) { + // @todo remove this after laravel/framework release 2024-07-06 parent::__construct($app); $this->config = $this->app->get('config'); } @@ -36,7 +42,7 @@ public function __construct($app) */ public function getDefaultInstance() { - return $this->config->get("statsd-adapter.default"); + return $this->defaultInstanceName ?? $this->config->get("statsd-adapter.default"); } /** @@ -44,7 +50,7 @@ public function getDefaultInstance() */ public function setDefaultInstance($name) { - // not sure if this is needed + $this->defaultInstanceName = $name; } /** @@ -64,6 +70,11 @@ protected function createMemoryAdapter(array $config): InMemoryClientAdapter } protected function createLog_datadogAdapter(array $config): DatadogStatsDClientAdapter + { + return $this->createDatadogAdapter($config); + } + + protected function createLogDatadogAdapter(array $config): DatadogStatsDClientAdapter { $logLevel = $config['log_level'] ?? 'debug'; From e4f36a2844c833da7911c97b8d9b289b327f33ad Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 6 Jul 2024 10:05:11 -0400 Subject: [PATCH 04/13] facade --- src/Stats.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/Stats.php diff --git a/src/Stats.php b/src/Stats.php new file mode 100644 index 0000000..9879087 --- /dev/null +++ b/src/Stats.php @@ -0,0 +1,13 @@ + Date: Sat, 6 Jul 2024 21:08:24 -0400 Subject: [PATCH 05/13] test wip --- composer.json | 103 +++++++++++------- .../database/factories/AdapterManagerTest.php | 11 ++ 2 files changed, 72 insertions(+), 42 deletions(-) create mode 100644 workbench/database/factories/AdapterManagerTest.php diff --git a/composer.json b/composer.json index edb04a6..2d51b98 100644 --- a/composer.json +++ b/composer.json @@ -1,45 +1,64 @@ { - "name": "cosmastech/laravel-statsd-adapter", - "description": "Easily use statsd-client-adapter within your Laravel project", - "license": "wtfpl", - "authors": [ - { - "name": "Luke Kuzmish", - "email": "luke@kuzmish.com", - "role": "Developer" + "name": "cosmastech/laravel-statsd-adapter", + "description": "Easily use statsd-client-adapter within your Laravel project", + "license": "wtfpl", + "authors": [ + { + "name": "Luke Kuzmish", + "email": "luke@kuzmish.com", + "role": "Developer" + } + ], + "autoload": { + "psr-4": { + "Cosmastech\\LaravelStatsDAdapter\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Cosmastech\\LaravelStatsDAdapter\\Tests\\": "tests", + "Workbench\\App\\": "workbench/app/", + "Workbench\\Database\\Factories\\": "workbench/database/factories/", + "Workbench\\Database\\Seeders\\": "workbench/database/seeders/" + } + }, + "require": { + "php": "^8.2", + "cosmastech/statsd-client-adapter": "^0.0.2", + "illuminate/support": "^10.0|^11.0", + "illuminate/contracts": "^10.0|^11.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.2.5", + "friendsofphp/php-cs-fixer": "^3.59", + "league/statsd": "^2.0.0", + "orchestra/testbench": "^9.1" + }, + "extra": { + "laravel": { + "providers": [ + "Cosmastech\\LaravelStatsDAdapter\\StatsDAdapterServiceProvider" + ] + } + }, + "scripts": { + "test": "phpunit tests", + "php-cs-fixer": "./vendor/bin/php-cs-fixer fix ./", + "php-cs-fixer-check": "./vendor/bin/php-cs-fixer check ./", + "post-autoload-dump": [ + "@clear", + "@prepare" + ], + "clear": "@php vendor/bin/testbench package:purge-skeleton --ansi", + "prepare": "@php vendor/bin/testbench package:discover --ansi", + "build": "@php vendor/bin/testbench workbench:build --ansi", + "serve": [ + "Composer\\Config::disableProcessTimeout", + "@build", + "@php vendor/bin/testbench serve" + ], + "lint": [ + "@php vendor/bin/phpstan analyse" + ] } - ], - "autoload": { - "psr-4": { - "Cosmastech\\LaravelStatsDAdapter\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "Cosmastech\\LaravelStatsDAdapter\\Tests\\": "tests" - } - }, - "require": { - "php": "^8.2", - "cosmastech/statsd-client-adapter": "^0.0.2", - "illuminate/support": "^10.0|^11.0", - "illuminate/contracts": "^10.0|^11.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.2.5", - "friendsofphp/php-cs-fixer": "^3.59", - "league/statsd": "^2.0.0" - }, - "extra": { - "laravel": { - "providers": [ - "Cosmastech\\LaravelStatsDAdapter\\StatsDAdapterServiceProvider" - ] - } - }, - "scripts": { - "test": "phpunit tests", - "php-cs-fixer": "./vendor/bin/php-cs-fixer fix ./", - "php-cs-fixer-check": "./vendor/bin/php-cs-fixer check ./" - } } \ No newline at end of file diff --git a/workbench/database/factories/AdapterManagerTest.php b/workbench/database/factories/AdapterManagerTest.php new file mode 100644 index 0000000..8846fa0 --- /dev/null +++ b/workbench/database/factories/AdapterManagerTest.php @@ -0,0 +1,11 @@ + Date: Sat, 6 Jul 2024 22:12:57 -0400 Subject: [PATCH 06/13] wip tests --- config/statsd-adapter.php | 8 +- src/AdapterManager.php | 2 +- testbench.yaml | 22 ++++++ tests/AbstractTestCase.php | 26 +++++++ .../AdapterManagerTest.php | 4 +- tests/StatsTest.php | 77 +++++++++++++++++++ workbench/bootstrap/app.php | 15 ++++ workbench/bootstrap/providers.php | 5 ++ 8 files changed, 151 insertions(+), 8 deletions(-) create mode 100644 testbench.yaml create mode 100644 tests/AbstractTestCase.php rename {workbench/database/factories => tests}/AdapterManagerTest.php (64%) create mode 100644 tests/StatsTest.php create mode 100644 workbench/bootstrap/app.php create mode 100644 workbench/bootstrap/providers.php diff --git a/config/statsd-adapter.php b/config/statsd-adapter.php index f10c5e9..8674d17 100644 --- a/config/statsd-adapter.php +++ b/config/statsd-adapter.php @@ -12,10 +12,10 @@ */ "channels" => [ "memory" => [ - "driver" => "memory", + "adapter" => "memory", ], "league" => [ - "driver" => "league", + "adapter" => "league", "instance_id" => null, 'host' => env('STATSD_HOST', '127.0.0.1'), 'port' => env('STATSD_PORT', 8125), @@ -23,7 +23,7 @@ 'throwConnectionExceptions' => true, ], "datadog" => [ - "driver" => "datadog", + "adapter" => "datadog", "host" => env("DD_AGENT_HOST"), "port" => env("DD_DOGSTATSD_PORT"), "socket_path" => null, @@ -34,7 +34,7 @@ "disable_telemetry" => null, ], "log_datadog" => [ - "driver" => "log_datadog", + "adapter" => "log_datadog", "log_level" => "debug", "decimal_precision" => null, "global_tags" => [], diff --git a/src/AdapterManager.php b/src/AdapterManager.php index e31e9dd..f6c84da 100644 --- a/src/AdapterManager.php +++ b/src/AdapterManager.php @@ -71,7 +71,7 @@ protected function createMemoryAdapter(array $config): InMemoryClientAdapter protected function createLog_datadogAdapter(array $config): DatadogStatsDClientAdapter { - return $this->createDatadogAdapter($config); + return $this->createLogDatadogAdapter($config); } protected function createLogDatadogAdapter(array $config): DatadogStatsDClientAdapter diff --git a/testbench.yaml b/testbench.yaml new file mode 100644 index 0000000..4843c84 --- /dev/null +++ b/testbench.yaml @@ -0,0 +1,22 @@ +providers: + # - Workbench\App\Providers\WorkbenchServiceProvider + +migrations: + - workbench/database/migrations + +seeders: + - Workbench\Database\Seeders\DatabaseSeeder + +workbench: + start: '/' + install: true + health: false + discovers: + web: true + api: false + commands: false + components: false + views: false + build: [] + assets: [] + sync: [] diff --git a/tests/AbstractTestCase.php b/tests/AbstractTestCase.php new file mode 100644 index 0000000..924f948 --- /dev/null +++ b/tests/AbstractTestCase.php @@ -0,0 +1,26 @@ +make('config'); + + $config->set('statsd-adapter', include __DIR__ . '/../config/statsd-adapter.php'); + } + + protected function createAdapterManager(): AdapterManager + { + return new AdapterManager($this->app); + } +} diff --git a/workbench/database/factories/AdapterManagerTest.php b/tests/AdapterManagerTest.php similarity index 64% rename from workbench/database/factories/AdapterManagerTest.php rename to tests/AdapterManagerTest.php index 8846fa0..82b34b6 100644 --- a/workbench/database/factories/AdapterManagerTest.php +++ b/tests/AdapterManagerTest.php @@ -1,11 +1,9 @@ increment("some-stat"); + + // Then + $stats = $inMemoryClientAdapter->getStats(); + self::assertEqualsWithDelta( + (new DateTimeImmutable("2021-01-01 00:00:00"))->getTimestamp(), + $stats->count[0]->recordedAt->getTimestamp(), + 1 + ); + } + + #[Test] + public function logDatadog_instance_returnsConfiguredDatadogClient() + { + // Given config set up with log_datadog channel + + // When + $datadogClientAdapter = Stats::instance("log_datadog"); + + // Then + self::assertInstanceOf(DatadogStatsDClientAdapter::class, $datadogClientAdapter); + self::assertInstanceOf(DatadogLoggingClient::class, $datadogClientAdapter->getClient()); + } +} diff --git a/workbench/bootstrap/app.php b/workbench/bootstrap/app.php new file mode 100644 index 0000000..450b9e9 --- /dev/null +++ b/workbench/bootstrap/app.php @@ -0,0 +1,15 @@ +withMiddleware(function (Middleware $middleware) { + // + }) + ->withExceptions(function (Exceptions $exceptions) { + // + })->create(); diff --git a/workbench/bootstrap/providers.php b/workbench/bootstrap/providers.php new file mode 100644 index 0000000..97d53ee --- /dev/null +++ b/workbench/bootstrap/providers.php @@ -0,0 +1,5 @@ + Date: Sun, 7 Jul 2024 09:10:35 -0400 Subject: [PATCH 07/13] more stats tests --- tests/StatsTest.php | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/StatsTest.php b/tests/StatsTest.php index 391cfc1..94fe0eb 100644 --- a/tests/StatsTest.php +++ b/tests/StatsTest.php @@ -14,10 +14,35 @@ class StatsTest extends AbstractTestCase { + #[Test] + public function getDefaultInstance_returnsConfigDefaultAdapter() + { + // Given + Config::set("statsd-adapter.default", "this-does-not-exist-but-thats-ok"); + + // When + $defaultInstanceString = Stats::getDefaultInstance(); + + // Then + self::assertEquals("this-does-not-exist-but-thats-ok", $defaultInstanceString); + } + + #[Test] + public function setDefaultInstance_overridesConfigDefault() + { + // Given application is configured + + // When + Stats::setDefaultInstance("yooooo"); + + // Then + self::assertEquals("yooooo", Stats::getDefaultInstance()); + } + #[Test] public function getFacadeRoot_returnsAdapterManager() { - // Given facade is set up + // Given facade has been booted // When $facadeRoot = Stats::getFacadeRoot(); From 95e655336ff0855901a2a9e91c5fee214fa95571 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sun, 7 Jul 2024 09:27:19 -0400 Subject: [PATCH 08/13] move tests --- tests/AdapterManagerTest.php | 87 +++++++++++++++++++++++++++++++++++- tests/StatsTest.php | 55 ----------------------- 2 files changed, 85 insertions(+), 57 deletions(-) diff --git a/tests/AdapterManagerTest.php b/tests/AdapterManagerTest.php index 82b34b6..9334932 100644 --- a/tests/AdapterManagerTest.php +++ b/tests/AdapterManagerTest.php @@ -2,8 +2,91 @@ namespace Cosmastech\LaravelStatsDAdapter\Tests; -use Orchestra\Testbench\TestCase; +use Cosmastech\StatsDClientAdapter\Adapters\Datadog\DatadogStatsDClientAdapter; +use Cosmastech\StatsDClientAdapter\Adapters\InMemory\InMemoryClientAdapter; +use Cosmastech\StatsDClientAdapter\Adapters\League\LeagueStatsDClientAdapter; +use Cosmastech\StatsDClientAdapter\Clients\Datadog\DatadogLoggingClient; +use Illuminate\Support\Facades\Config; +use League\StatsD\StatsDClient; +use PHPUnit\Framework\Attributes\Test; -class AdapterManagerTest extends TestCase +class AdapterManagerTest extends AbstractTestCase { + #[Test] + public function getDefaultInstance_returnsConfigDefaultAdapter() + { + // Given + $adapterManager = $this->createAdapterManager(); + + // And + Config::set("statsd-adapter.default", "this-does-not-exist-but-thats-ok"); + + // When + $defaultInstanceString = $adapterManager->getDefaultInstance(); + + // Then + self::assertEquals("this-does-not-exist-but-thats-ok", $defaultInstanceString); + } + + #[Test] + public function setDefaultInstance_overridesConfigDefault() + { + // Given + $adapterManager = $this->createAdapterManager(); + + // When + $adapterManager->setDefaultInstance("yooooo"); + + // Then + self::assertEquals("yooooo", $adapterManager->getDefaultInstance()); + } + + #[Test] + public function memoryAdapter_instance_returnsInMemoryClientAdapter() + { + // Given + $adapterManager = $this->createAdapterManager(); + + // And + Config::set("statsd-adapter.default", "memory"); + + // When + /** @var InMemoryClientAdapter $inMemoryClientAdapter */ + $inMemoryClientAdapter = $adapterManager->instance(); + + // Then + self::assertInstanceOf(InMemoryClientAdapter::class, $inMemoryClientAdapter); + } + + #[Test] + public function logDatadog_instance_returnsConfiguredDatadogClient() + { + // Given + $adapterManager = $this->createAdapterManager(); + + // And "log_datadog" channel is set and app is booted + + // When + $datadogClientAdapter = $adapterManager->instance("log_datadog"); + + // Then + self::assertInstanceOf(DatadogStatsDClientAdapter::class, $datadogClientAdapter); + self::assertInstanceOf(DatadogLoggingClient::class, $datadogClientAdapter->getClient()); + } + + public function league_instance_returnsConfiguredLeagueStatsDClient() + { + // Given + $adapterManager = $this->createAdapterManager(); + + // And "league" channel is set and app is booted + + // When + /** @var LeagueStatsDClientAdapter $leagueStatsDClientAdapter */ + $leagueStatsDClientAdapter = $adapterManager->instance("league"); + + // Then + self::assertInstanceOf(LeagueStatsDClientAdapter::class, $leagueStatsDClientAdapter); + self::assertInstanceOf(StatsDClient::class, $leagueStatsDClientAdapter->getClient()); + } } diff --git a/tests/StatsTest.php b/tests/StatsTest.php index 94fe0eb..e658ac5 100644 --- a/tests/StatsTest.php +++ b/tests/StatsTest.php @@ -4,41 +4,13 @@ use Cosmastech\LaravelStatsDAdapter\AdapterManager; use Cosmastech\LaravelStatsDAdapter\Stats; -use Cosmastech\StatsDClientAdapter\Adapters\Datadog\DatadogStatsDClientAdapter; use Cosmastech\StatsDClientAdapter\Adapters\InMemory\InMemoryClientAdapter; -use Cosmastech\StatsDClientAdapter\Clients\Datadog\DatadogLoggingClient; use DateTimeImmutable; use Illuminate\Support\Carbon; -use Illuminate\Support\Facades\Config; use PHPUnit\Framework\Attributes\Test; class StatsTest extends AbstractTestCase { - #[Test] - public function getDefaultInstance_returnsConfigDefaultAdapter() - { - // Given - Config::set("statsd-adapter.default", "this-does-not-exist-but-thats-ok"); - - // When - $defaultInstanceString = Stats::getDefaultInstance(); - - // Then - self::assertEquals("this-does-not-exist-but-thats-ok", $defaultInstanceString); - } - - #[Test] - public function setDefaultInstance_overridesConfigDefault() - { - // Given application is configured - - // When - Stats::setDefaultInstance("yooooo"); - - // Then - self::assertEquals("yooooo", Stats::getDefaultInstance()); - } - #[Test] public function getFacadeRoot_returnsAdapterManager() { @@ -51,20 +23,6 @@ public function getFacadeRoot_returnsAdapterManager() self::assertInstanceOf(AdapterManager::class, $facadeRoot); } - #[Test] - public function memoryAdapter_instance_returnsInMemoryClientAdapter() - { - // Given - Config::set("statsd-adapter.default", "memory"); - - // When - /** @var InMemoryClientAdapter $inMemoryClientAdapter */ - $inMemoryClientAdapter = Stats::instance(); - - // Then - self::assertInstanceOf(InMemoryClientAdapter::class, $inMemoryClientAdapter); - } - #[Test] public function memoryAdapter_logsRespectCarbonTestTime() { @@ -86,17 +44,4 @@ public function memoryAdapter_logsRespectCarbonTestTime() 1 ); } - - #[Test] - public function logDatadog_instance_returnsConfiguredDatadogClient() - { - // Given config set up with log_datadog channel - - // When - $datadogClientAdapter = Stats::instance("log_datadog"); - - // Then - self::assertInstanceOf(DatadogStatsDClientAdapter::class, $datadogClientAdapter); - self::assertInstanceOf(DatadogLoggingClient::class, $datadogClientAdapter->getClient()); - } } From 4296e57ba249f1e6e805a655eb6d117890f3d742 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sun, 7 Jul 2024 09:39:11 -0400 Subject: [PATCH 09/13] keep phpstan happier --- tests/AdapterManagerTest.php | 10 +++++----- tests/StatsTest.php | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/AdapterManagerTest.php b/tests/AdapterManagerTest.php index 9334932..ef7fe2f 100644 --- a/tests/AdapterManagerTest.php +++ b/tests/AdapterManagerTest.php @@ -13,7 +13,7 @@ class AdapterManagerTest extends AbstractTestCase { #[Test] - public function getDefaultInstance_returnsConfigDefaultAdapter() + public function getDefaultInstance_returnsConfigDefaultAdapter(): void { // Given $adapterManager = $this->createAdapterManager(); @@ -29,7 +29,7 @@ public function getDefaultInstance_returnsConfigDefaultAdapter() } #[Test] - public function setDefaultInstance_overridesConfigDefault() + public function setDefaultInstance_overridesConfigDefault(): void { // Given $adapterManager = $this->createAdapterManager(); @@ -42,7 +42,7 @@ public function setDefaultInstance_overridesConfigDefault() } #[Test] - public function memoryAdapter_instance_returnsInMemoryClientAdapter() + public function memoryAdapter_instance_returnsInMemoryClientAdapter(): void { // Given $adapterManager = $this->createAdapterManager(); @@ -59,7 +59,7 @@ public function memoryAdapter_instance_returnsInMemoryClientAdapter() } #[Test] - public function logDatadog_instance_returnsConfiguredDatadogClient() + public function logDatadog_instance_returnsConfiguredDatadogClient(): void { // Given $adapterManager = $this->createAdapterManager(); @@ -74,7 +74,7 @@ public function logDatadog_instance_returnsConfiguredDatadogClient() self::assertInstanceOf(DatadogLoggingClient::class, $datadogClientAdapter->getClient()); } - public function league_instance_returnsConfiguredLeagueStatsDClient() + public function league_instance_returnsConfiguredLeagueStatsDClient(): void { // Given $adapterManager = $this->createAdapterManager(); diff --git a/tests/StatsTest.php b/tests/StatsTest.php index e658ac5..294d598 100644 --- a/tests/StatsTest.php +++ b/tests/StatsTest.php @@ -12,7 +12,7 @@ class StatsTest extends AbstractTestCase { #[Test] - public function getFacadeRoot_returnsAdapterManager() + public function getFacadeRoot_returnsAdapterManager(): void { // Given facade has been booted @@ -24,7 +24,7 @@ public function getFacadeRoot_returnsAdapterManager() } #[Test] - public function memoryAdapter_logsRespectCarbonTestTime() + public function memoryAdapter_logsRespectCarbonTestTime(): void { // Given /** @var InMemoryClientAdapter $inMemoryClientAdapter */ From 5480db8433267f5339d0742be965524dd36a7ef7 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sun, 7 Jul 2024 10:13:15 -0400 Subject: [PATCH 10/13] facade documentor --- .github/workflows/php.yml | 47 +++++++++++++++++++++++++++++++++++++++ composer.json | 17 ++++++++++++-- src/AdapterManager.php | 3 +++ src/Stats.php | 20 +++++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/php.yml diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml new file mode 100644 index 0000000..91d6940 --- /dev/null +++ b/.github/workflows/php.yml @@ -0,0 +1,47 @@ +name: PHP Composer + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.2" + + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Run test suite + run: composer test + + - name: Style check + run: composer php-cs-fixer-check + + - name: Document facade + run: composer facade-documentor-lint diff --git a/composer.json b/composer.json index 2d51b98..9ce7b97 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,8 @@ "phpunit/phpunit": "^11.2.5", "friendsofphp/php-cs-fixer": "^3.59", "league/statsd": "^2.0.0", - "orchestra/testbench": "^9.1" + "orchestra/testbench": "^9.1", + "laravel/facade-documenter": "dev-main" }, "extra": { "laravel": { @@ -59,6 +60,18 @@ ], "lint": [ "@php vendor/bin/phpstan analyse" + ], + "facade-documentor": [ + "@php -f vendor/bin/facade.php -- \"\\\\Cosmastech\\\\LaravelStatsDAdapter\\\\Stats\"" + ], + "facade-documentor-lint": [ + "@php -f vendor/bin/facade.php -- --lint \"\\\\Cosmastech\\\\LaravelStatsDAdapter\\\\Stats\"" ] + }, + "repositories": { + "facade-documenter": { + "type": "vcs", + "url": "git@github.com:laravel/facade-documenter.git" + } } -} \ No newline at end of file +} diff --git a/src/AdapterManager.php b/src/AdapterManager.php index f6c84da..dc919eb 100644 --- a/src/AdapterManager.php +++ b/src/AdapterManager.php @@ -14,6 +14,9 @@ use League\StatsD\Client; use League\StatsD\Exception\ConfigurationException; +/** + * @mixin \Cosmastech\StatsDClientAdapter\Adapters\StatsDClientAdapter + */ class AdapterManager extends MultipleInstanceManager { protected $driverKey = 'adapter'; diff --git a/src/Stats.php b/src/Stats.php index 9879087..5eb7653 100644 --- a/src/Stats.php +++ b/src/Stats.php @@ -4,6 +4,26 @@ use Illuminate\Support\Facades\Facade; +/** + * @method static void getDefaultInstance() + * @method static void setDefaultInstance(string $name) + * @method static void getInstanceConfig(string $name) + * @method static mixed instance(string|null $name = null) + * @method static \Cosmastech\LaravelStatsDAdapter\AdapterManager forgetInstance(array|string|null $name = null) + * @method static void purge(string|null $name = null) + * @method static \Cosmastech\LaravelStatsDAdapter\AdapterManager extend(string $name, \Closure $callback) + * @method static void timing(string $stat, float $durationMs, float $sampleRate = 1, array $tags = []) + * @method static void gauge(string $stat, float $value, float $sampleRate = 1, array $tags = []) + * @method static void histogram(string $stat, float $value, float $sampleRate = 1, array $tags = []) + * @method static void distribution(string $stat, float $value, float $sampleRate = 1, array $tags = []) + * @method static void set(string $stat, string|float $value, float $sampleRate = 1, array $tags = []) + * @method static void increment(array|string $stats, float $sampleRate = 1, array $tags = [], int $value = 1) + * @method static void decrement(array|string $stats, float $sampleRate = 1, array $tags = [], int $value = 1) + * @method static void updateStats(array|string $stats, int $delta = 1, void $sampleRate = 1, void $tags = null) + * @method static mixed getClient() + * + * @see \Cosmastech\LaravelStatsDAdapter\AdapterManager + */ class Stats extends Facade { protected static function getFacadeAccessor(): string From 84671ec9947bab2da06c780ffd0db1168ef371cd Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sun, 7 Jul 2024 10:20:39 -0400 Subject: [PATCH 11/13] phpstan --- composer.json | 7 ++++--- phpstan.neon | 5 +++++ src/AdapterManager.php | 22 ++++++++++++++++++++-- src/StatsDAdapterServiceProvider.php | 3 +++ 4 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 phpstan.neon diff --git a/composer.json b/composer.json index 9ce7b97..54819f2 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ "friendsofphp/php-cs-fixer": "^3.59", "league/statsd": "^2.0.0", "orchestra/testbench": "^9.1", - "laravel/facade-documenter": "dev-main" + "laravel/facade-documenter": "dev-main", + "phpstan/phpstan": "^1.11" }, "extra": { "laravel": { @@ -58,8 +59,8 @@ "@build", "@php vendor/bin/testbench serve" ], - "lint": [ - "@php vendor/bin/phpstan analyse" + "static-analysis": [ + "@php vendor/bin/phpstan analyse -c phpstan.neon" ], "facade-documentor": [ "@php -f vendor/bin/facade.php -- \"\\\\Cosmastech\\\\LaravelStatsDAdapter\\\\Stats\"" diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..3a1f859 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,5 @@ +parameters: + level: 7 + paths: + - src + - tests diff --git a/src/AdapterManager.php b/src/AdapterManager.php index dc919eb..f61f31e 100644 --- a/src/AdapterManager.php +++ b/src/AdapterManager.php @@ -57,14 +57,17 @@ public function setDefaultInstance($name) } /** - * @inheritDoc + * @return array|null */ public function getInstanceConfig($name) { return $this->config->get("statsd-adapter.channels.{$name}"); } - + /** + * @param array $config + * @return InMemoryClientAdapter + */ protected function createMemoryAdapter(array $config): InMemoryClientAdapter { $wrapperClock = new WrapperClock(FactoryImmutable::getDefaultInstance()); @@ -72,11 +75,20 @@ protected function createMemoryAdapter(array $config): InMemoryClientAdapter return new InMemoryClientAdapter($wrapperClock); } + /** + * @param array $config + * @return DatadogStatsDClientAdapter + */ protected function createLog_datadogAdapter(array $config): DatadogStatsDClientAdapter { return $this->createLogDatadogAdapter($config); } + /** + * @param array $config + * @return DatadogStatsDClientAdapter + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ protected function createLogDatadogAdapter(array $config): DatadogStatsDClientAdapter { $logLevel = $config['log_level'] ?? 'debug'; @@ -86,12 +98,18 @@ protected function createLogDatadogAdapter(array $config): DatadogStatsDClientAd ); } + /** + * @param array $config + * @return DatadogStatsDClientAdapter + */ protected function createDatadogAdapter(array $config): DatadogStatsDClientAdapter { return new DatadogStatsDClientAdapter(new DogStatsd($config)); } /** + * @param array $config + * @return LeagueStatsDClientAdapter * @throws ConfigurationException */ protected function createLeagueAdapter(array $config): LeagueStatsDClientAdapter diff --git a/src/StatsDAdapterServiceProvider.php b/src/StatsDAdapterServiceProvider.php index 4c1d196..5e3cc83 100644 --- a/src/StatsDAdapterServiceProvider.php +++ b/src/StatsDAdapterServiceProvider.php @@ -21,6 +21,9 @@ public function register() ); } + /** + * @return array + */ public function provides(): array { return [AdapterManager::class, StatsDClientAdapter::class]; From 920b0cef3c9ed338767d791a91bb9a5673e70624 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sun, 7 Jul 2024 10:21:12 -0400 Subject: [PATCH 12/13] add build step --- .github/workflows/php.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 91d6940..27f1522 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -45,3 +45,6 @@ jobs: - name: Document facade run: composer facade-documentor-lint + + - name: Static Analysis + run: composer static-analysis From ca3c3f5112273d0039a8a37f3d9d5ad00f62ff26 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sun, 7 Jul 2024 10:22:22 -0400 Subject: [PATCH 13/13] fix facade docblock --- src/Stats.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stats.php b/src/Stats.php index 5eb7653..a05518f 100644 --- a/src/Stats.php +++ b/src/Stats.php @@ -7,7 +7,7 @@ /** * @method static void getDefaultInstance() * @method static void setDefaultInstance(string $name) - * @method static void getInstanceConfig(string $name) + * @method static array|null getInstanceConfig(string $name) * @method static mixed instance(string|null $name = null) * @method static \Cosmastech\LaravelStatsDAdapter\AdapterManager forgetInstance(array|string|null $name = null) * @method static void purge(string|null $name = null)