Skip to content

Commit

Permalink
Merge branch '0.7.0' into dont-bloat-laravel-logs
Browse files Browse the repository at this point in the history
  • Loading branch information
aozisik committed Dec 19, 2023
2 parents 8224aac + cf8cd9c commit 509d464
Show file tree
Hide file tree
Showing 21 changed files with 784 additions and 62 deletions.
8 changes: 1 addition & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
name: run-tests

on:
push:
branches:
- master
pull_request:
branches:
- master
on: [push, pull_request]

jobs:
test:
Expand Down
4 changes: 2 additions & 2 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
Expand Down
72 changes: 33 additions & 39 deletions src/AppkeepProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Appkeep\Laravel;

use Appkeep\Laravel\Facades\Appkeep;
use Illuminate\Support\ServiceProvider;
use Appkeep\Laravel\Commands\RunCommand;
use Illuminate\Console\Scheduling\Event;
use Appkeep\Laravel\Commands\InitCommand;
use Appkeep\Laravel\Commands\ListCommand;
use Appkeep\Laravel\Commands\LoginCommand;
Expand All @@ -27,6 +27,10 @@ public function register()
return new AppkeepService();
});

$this->app->singleton(EventCollector::class, function () {
return new EventCollector();
});

$this->app->bind(HttpClient::class, function () {
return new HttpClient(config('appkeep.key'));
});
Expand All @@ -43,13 +47,29 @@ public function boot()
{
$this->loadRoutesFrom(__DIR__ . '/../routes/web.php');

if ($this->app->runningInConsole()) {
$this->bootForConsole();
}
$this->bootForConsole();

$this->app->booted(function () {
if ($this->app->runningInConsole()) {
$this->scheduleRunCommand();
}

// Watch slow queries, scheduled tasks, etc.
Appkeep::watch($this->app);
});

$this->app->terminating(function () {
// Write in-memory events to cache.
$this->app->make(EventCollector::class)->persist();
});
}

public function bootForConsole()
{
if (!$this->app->runningInConsole()) {
return;
}

$this->publishes([
__DIR__ . '/../config/appkeep.php' => config_path('appkeep.php'),
], 'config');
Expand All @@ -65,45 +85,19 @@ public function bootForConsole()
LoginCommand::class,
PostDeployCommand::class,
]);

$this->app->booted(function () {
$schedule = $this->app->make(Schedule::class);

$schedule->command('appkeep:run')
->everyMinute()
->runInBackground()
->evenInMaintenanceMode();

$this->watchScheduledTasks($schedule);
});
}

protected function watchScheduledTasks(Schedule $schedule)
protected function scheduleRunCommand()
{
/**
* @var AppkeepService
*/
$appkeep = app('appkeep');
$schedule = $this->app->make(Schedule::class);

if (!$appkeep->scheduledTaskMonitoringEnabled) {
return;
}
$schedule->command('appkeep:run')
->everyMinute()
->runInBackground()
->evenInMaintenanceMode();

collect($schedule->events())
->filter(function ($event) {
// Don't monitor the Appkeep scheduled task itself.
return $event->command && !str_contains($event->command, 'appkeep:run');
})
->each(function (Event $event) use ($appkeep) {
$event->before(fn () => $appkeep->scheduledTaskStarted($event));

$event->onSuccessWithOutput(
fn () => $appkeep->scheduledTaskCompleted($event)
);

$event->onFailureWithOutput(
fn () => $appkeep->scheduledTaskFailed($event)
);
});
$this->app->singleton('command.appkeep.run', function ($app) {
return new RunCommand($app['appkeep']);
});
}
}
16 changes: 13 additions & 3 deletions src/AppkeepService.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
namespace Appkeep\Laravel;

use InvalidArgumentException;
use Appkeep\Laravel\Concerns\ReportsScheduledTaskOutputs;
use Appkeep\Laravel\Concerns\WatchesSlowQueries;
use Illuminate\Contracts\Foundation\Application;
use Appkeep\Laravel\Concerns\WatchesScheduledTasks;

class AppkeepService
{
use ReportsScheduledTaskOutputs;
use WatchesSlowQueries;
use WatchesScheduledTasks;

public $checks = [];

public function version()
{
return '0.6.1';
return '0.7.0';
}

public function client()
Expand All @@ -31,6 +34,13 @@ public function forgetDefaultChecks()
return $this;
}

public function watch(Application $app)
{
$this->watchScheduledTasks($app);

$this->watchSlowQueries($app);
}

public function checks(array $checks = [], $replace = false)
{
if (! app()->runningInConsole()) {
Expand Down
119 changes: 119 additions & 0 deletions src/Checks/DatabaseConnectionCountCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

namespace Appkeep\Laravel\Checks;

use Exception;
use Appkeep\Laravel\Check;
use Appkeep\Laravel\Result;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Appkeep\Laravel\Database\MySqlInspector;
use Appkeep\Laravel\Database\PostgresInspector;
use Appkeep\Laravel\Database\SqlServerInspector;

class DatabaseConnectionCountCheck extends Check
{
protected $warnAt;

protected $failAt;

private $connection;

private $inspectors = [
'mysql' => MySqlInspector::class,
'pgsql' => PostgresInspector::class,
];

/**
* Check a different connection
*/
public function connection($connection)
{
$this->connection = $connection;

return $this;
}

public function warnIfConnectionCountIsAbove($count)
{
$this->warnAt = (int) $count;

return $this;
}

public function failIfConnectionCountIsAbove($count)
{
$this->failAt = (int) $count;

return $this;
}

/**
* @var Result
*/
public function run()
{
$connection = $this->connection ?? config('database.default');
$meta = ['connection' => $connection];

$db = DB::connection($connection);
$driver = $db->getDriverName();

// If there's no inspector for this connection, we can't check it.
// In that case, we'll just skip this check.
if (! isset($this->inspectors[$driver])) {
return Result::ok()->meta($meta);
}

/**
* @var DatabaseIn
*/
$inspector = app($this->inspectors[$driver], [
'connection' => $db,
]);

$cacheKey = 'appkeep.db.' . $connection . '.connection_count';

$maxConnections = Cache::remember(
$cacheKey,
now()->addHours(2),
function () use ($inspector) {
try {
return $inspector->maximumConnectionCount();
} catch (Exception $e) {
// Failed to get the maximum connection count.
report($e);

// Let's just assume the default.
return 100;
}
}
);

$currentConnections = $inspector->currentConnectionCount();

if (is_null($this->warnAt)) {
$this->warnAt = floor($maxConnections * 0.8);
}

if (is_null($this->failAt)) {
$this->failAt = $maxConnections - 1;
}

if ($currentConnections >= $this->failAt) {
return Result::fail("Too many active database connections.")
->summary($currentConnections)
->meta($meta);
}

if ($currentConnections >= $this->warnAt) {
return Result::warn("Approaching the maximum number of database connections.")
->summary($currentConnections)
->meta($meta);
}

return Result::ok()
->summary($currentConnections)
->meta($meta);
}
}
30 changes: 30 additions & 0 deletions src/Commands/RunCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Appkeep\Laravel\Result;
use Illuminate\Console\Command;
use Appkeep\Laravel\Enums\Status;
use Appkeep\Laravel\EventCollector;
use Appkeep\Laravel\Facades\Appkeep;
use Appkeep\Laravel\Events\ChecksEvent;

Expand All @@ -14,6 +15,35 @@ class RunCommand extends Command
protected $description = 'Run all Appkeep checks';

public function handle()
{
$this->sendCollectedEvents();

$this->runChecks();
}

private function sendCollectedEvents()
{
$collector = resolve(EventCollector::class);

$events = $collector->pull();

if (empty($events)) {
$this->line('No collected events to send.');

return;
}

$this->info(sprintf('Sending %d collected events to Appkeep...', count($events)));

try {
Appkeep::client()->sendBatchEvents(array_values($events))->throw();
} catch (\Exception $e) {
$this->warn('Failed to post collected events to Appkeep.');
$this->line($e->getMessage());
}
}

private function runChecks()
{
$checks = Appkeep::checks();

Expand Down
3 changes: 3 additions & 0 deletions src/Concerns/RegistersDefaultChecks.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Appkeep\Laravel\Checks\SystemLoadCheck;
use Appkeep\Laravel\Checks\OptimizationCheck;
use Appkeep\Laravel\Checks\ProductionModeCheck;
use Appkeep\Laravel\Checks\DatabaseConnectionCountCheck;
use Laravel\Horizon\Contracts\MasterSupervisorRepository;

trait RegistersDefaultChecks
Expand All @@ -24,6 +25,8 @@ protected function registerDefaultChecks()

DatabaseCheck::make(),

DatabaseConnectionCountCheck::make(),

CacheCheck::make(),

DiskUsageCheck::make(),
Expand Down
Loading

0 comments on commit 509d464

Please sign in to comment.