From 3b20eee909550cdd058411a7f92d0809a2874b2a Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 17 Nov 2023 20:08:21 +0100 Subject: [PATCH 1/3] feat: enable/disable log drain by service --- app/Actions/Database/StartMariadb.php | 2 +- app/Actions/Database/StartMongodb.php | 2 +- app/Actions/Database/StartMysql.php | 2 +- app/Actions/Database/StartPostgresql.php | 3 +- app/Actions/Database/StartRedis.php | 3 +- app/Actions/Server/InstallLogDrain.php | 1 + .../Livewire/Project/Application/General.php | 11 ++- .../Project/Database/Mariadb/General.php | 15 ++++ .../Project/Database/Mongodb/General.php | 17 ++++- .../Project/Database/Mysql/General.php | 16 +++++ .../Project/Database/Postgresql/General.php | 15 ++++ .../Project/Database/Redis/General.php | 15 ++++ .../Livewire/Project/Service/Application.php | 12 +++- .../Livewire/Project/Service/Database.php | 17 ++++- app/Jobs/ApplicationDeploymentJob.php | 2 +- app/Models/Application.php | 3 + app/Models/Server.php | 2 +- app/Models/Service.php | 2 +- app/Models/ServiceApplication.php | 4 ++ app/Models/ServiceDatabase.php | 4 ++ app/Models/StandaloneMariadb.php | 4 ++ app/Models/StandaloneMongodb.php | 5 +- app/Models/StandaloneMysql.php | 5 ++ app/Models/StandalonePostgresql.php | 5 ++ app/Models/StandaloneRedis.php | 5 ++ config/sentry.php | 2 +- config/version.php | 2 +- ...160437_add_drain_log_enable_by_service.php | 72 +++++++++++++++++++ .../project/application/general.blade.php | 2 + .../database/mariadb/general.blade.php | 5 ++ .../database/mongodb/general.blade.php | 17 +++-- .../project/database/mysql/general.blade.php | 5 ++ .../database/postgresql/general.blade.php | 6 ++ .../project/database/redis/general.blade.php | 5 ++ .../project/service/application.blade.php | 2 + .../project/service/database.blade.php | 2 + versions.json | 2 +- 37 files changed, 270 insertions(+), 24 deletions(-) create mode 100644 database/migrations/2023_11_17_160437_add_drain_log_enable_by_service.php diff --git a/app/Actions/Database/StartMariadb.php b/app/Actions/Database/StartMariadb.php index 3e32c2481..c6b243381 100644 --- a/app/Actions/Database/StartMariadb.php +++ b/app/Actions/Database/StartMariadb.php @@ -69,7 +69,7 @@ public function handle(StandaloneMariadb $database) ] ] ]; - if ($this->database->destination->server->isDrainLogActivated()) { + if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { $docker_compose['services'][$container_name]['logging'] = [ 'driver' => 'fluentd', 'options' => [ diff --git a/app/Actions/Database/StartMongodb.php b/app/Actions/Database/StartMongodb.php index 4ebbb9ec4..9eb884dbe 100644 --- a/app/Actions/Database/StartMongodb.php +++ b/app/Actions/Database/StartMongodb.php @@ -76,7 +76,7 @@ public function handle(StandaloneMongodb $database) ] ] ]; - if ($this->database->destination->server->isDrainLogActivated()) { + if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { $docker_compose['services'][$container_name]['logging'] = [ 'driver' => 'fluentd', 'options' => [ diff --git a/app/Actions/Database/StartMysql.php b/app/Actions/Database/StartMysql.php index c3f04dc9f..761832525 100644 --- a/app/Actions/Database/StartMysql.php +++ b/app/Actions/Database/StartMysql.php @@ -69,7 +69,7 @@ public function handle(StandaloneMysql $database) ] ] ]; - if ($this->database->destination->server->isDrainLogActivated()) { + if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { $docker_compose['services'][$container_name]['logging'] = [ 'driver' => 'fluentd', 'options' => [ diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index 1acdcf957..b88da5e4f 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -79,7 +79,8 @@ public function handle(StandalonePostgresql $database) ] ] ]; - if ($this->database->destination->server->isDrainLogActivated()) { + if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { + ray('Log Drain Enabled'); $docker_compose['services'][$container_name]['logging'] = [ 'driver' => 'fluentd', 'options' => [ diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index 0cbd01f63..fab055f20 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -78,7 +78,7 @@ public function handle(StandaloneRedis $database) ] ] ]; - if ($this->database->destination->server->isDrainLogActivated()) { + if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { $docker_compose['services'][$container_name]['logging'] = [ 'driver' => 'fluentd', 'options' => [ @@ -166,6 +166,5 @@ private function add_custom_redis() $content = $this->database->redis_conf; $content_base64 = base64_encode($content); $this->commands[] = "echo '{$content_base64}' | base64 -d > $this->configuration_dir/{$filename}"; - } } diff --git a/app/Actions/Server/InstallLogDrain.php b/app/Actions/Server/InstallLogDrain.php index 5ea1d5e43..4db355aa8 100644 --- a/app/Actions/Server/InstallLogDrain.php +++ b/app/Actions/Server/InstallLogDrain.php @@ -127,6 +127,7 @@ public function handle(Server $server, string $type) - ./parsers.conf:/parsers.conf ports: - 127.0.0.1:24224:24224 + restart: unless-stopped "); $readme = base64_encode('# New Relic Log Drain This log drain is based on [Fluent Bit](https://fluentbit.io/) and New Relic Log Forwarder. diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index bc853108f..63dbeba23 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -32,7 +32,7 @@ class General extends Component public bool $is_preview_deployments_enabled; public bool $is_auto_deploy_enabled; public bool $is_force_https_enabled; - + public bool $is_log_drain_enabled; protected $rules = [ 'application.name' => 'required', @@ -101,6 +101,7 @@ public function mount() $this->is_preview_deployments_enabled = $this->application->settings->is_preview_deployments_enabled; $this->is_auto_deploy_enabled = $this->application->settings->is_auto_deploy_enabled; $this->is_force_https_enabled = $this->application->settings->is_force_https_enabled; + $this->is_log_drain_enabled = $this->application->settings->is_log_drain_enabled; } $this->checkLabelUpdates(); } @@ -136,6 +137,14 @@ public function instantSave() $this->application->settings->is_preview_deployments_enabled = $this->is_preview_deployments_enabled; $this->application->settings->is_auto_deploy_enabled = $this->is_auto_deploy_enabled; $this->application->settings->is_force_https_enabled = $this->is_force_https_enabled; + $this->application->settings->is_log_drain_enabled = $this->is_log_drain_enabled; + if ($this->is_log_drain_enabled) { + if (!$this->application->destination->server->isLogDrainEnabled()) { + $this->application->settings->is_log_drain_enabled = $this->is_log_drain_enabled = false; + $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + return; + } + } $this->application->settings->save(); $this->application->save(); $this->application->refresh(); diff --git a/app/Http/Livewire/Project/Database/Mariadb/General.php b/app/Http/Livewire/Project/Database/Mariadb/General.php index 173e9290f..455f1b4ca 100644 --- a/app/Http/Livewire/Project/Database/Mariadb/General.php +++ b/app/Http/Livewire/Project/Database/Mariadb/General.php @@ -28,6 +28,7 @@ class General extends Component 'database.ports_mappings' => 'nullable', 'database.is_public' => 'nullable|boolean', 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', ]; protected $validationAttributes = [ 'database.name' => 'Name', @@ -50,6 +51,20 @@ public function mount() $this->db_url_public = $this->database->getDbUrl(); } } + public function instantSaveAdvanced() { + try { + if (!$this->database->destination->server->isLogDrainEnabled()) { + $this->database->is_log_drain_enabled = false; + $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + return; + } + $this->database->save(); + $this->emit('success', 'Database updated successfully.'); + $this->emit('success', 'You need to restart the service for the changes to take effect.'); + } catch (Exception $e) { + return handleError($e, $this); + } + } public function submit() { try { diff --git a/app/Http/Livewire/Project/Database/Mongodb/General.php b/app/Http/Livewire/Project/Database/Mongodb/General.php index 189f2632e..84669a019 100644 --- a/app/Http/Livewire/Project/Database/Mongodb/General.php +++ b/app/Http/Livewire/Project/Database/Mongodb/General.php @@ -27,6 +27,7 @@ class General extends Component 'database.ports_mappings' => 'nullable', 'database.is_public' => 'nullable|boolean', 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', ]; protected $validationAttributes = [ 'database.name' => 'Name', @@ -48,7 +49,21 @@ public function mount() $this->db_url_public = $this->database->getDbUrl(); } } - + public function instantSaveAdvanced() + { + try { + if (!$this->database->destination->server->isLogDrainEnabled()) { + $this->database->is_log_drain_enabled = false; + $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + return; + } + $this->database->save(); + $this->emit('success', 'Database updated successfully.'); + $this->emit('success', 'You need to restart the service for the changes to take effect.'); + } catch (Exception $e) { + return handleError($e, $this); + } + } public function submit() { try { diff --git a/app/Http/Livewire/Project/Database/Mysql/General.php b/app/Http/Livewire/Project/Database/Mysql/General.php index cb1a063db..c63cea293 100644 --- a/app/Http/Livewire/Project/Database/Mysql/General.php +++ b/app/Http/Livewire/Project/Database/Mysql/General.php @@ -28,6 +28,7 @@ class General extends Component 'database.ports_mappings' => 'nullable', 'database.is_public' => 'nullable|boolean', 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', ]; protected $validationAttributes = [ 'database.name' => 'Name', @@ -50,6 +51,21 @@ public function mount() $this->db_url_public = $this->database->getDbUrl(); } } + public function instantSaveAdvanced() + { + try { + if (!$this->database->destination->server->isLogDrainEnabled()) { + $this->database->is_log_drain_enabled = false; + $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + return; + } + $this->database->save(); + $this->emit('success', 'Database updated successfully.'); + $this->emit('success', 'You need to restart the service for the changes to take effect.'); + } catch (Exception $e) { + return handleError($e, $this); + } + } public function submit() { try { diff --git a/app/Http/Livewire/Project/Database/Postgresql/General.php b/app/Http/Livewire/Project/Database/Postgresql/General.php index ebc69a1bc..1804953ee 100644 --- a/app/Http/Livewire/Project/Database/Postgresql/General.php +++ b/app/Http/Livewire/Project/Database/Postgresql/General.php @@ -34,6 +34,7 @@ class General extends Component 'database.ports_mappings' => 'nullable', 'database.is_public' => 'nullable|boolean', 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', ]; protected $validationAttributes = [ 'database.name' => 'Name', @@ -57,6 +58,20 @@ public function mount() $this->db_url_public = $this->database->getDbUrl(); } } + public function instantSaveAdvanced() { + try { + if (!$this->database->destination->server->isLogDrainEnabled()) { + $this->database->is_log_drain_enabled = false; + $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + return; + } + $this->database->save(); + $this->emit('success', 'Database updated successfully.'); + $this->emit('success', 'You need to restart the service for the changes to take effect.'); + } catch (Exception $e) { + return handleError($e, $this); + } + } public function instantSave() { try { diff --git a/app/Http/Livewire/Project/Database/Redis/General.php b/app/Http/Livewire/Project/Database/Redis/General.php index 834a9f381..c2a28eef8 100644 --- a/app/Http/Livewire/Project/Database/Redis/General.php +++ b/app/Http/Livewire/Project/Database/Redis/General.php @@ -25,6 +25,7 @@ class General extends Component 'database.ports_mappings' => 'nullable', 'database.is_public' => 'nullable|boolean', 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', ]; protected $validationAttributes = [ 'database.name' => 'Name', @@ -43,6 +44,20 @@ public function mount() $this->db_url_public = $this->database->getDbUrl(); } } + public function instantSaveAdvanced() { + try { + if (!$this->database->destination->server->isLogDrainEnabled()) { + $this->database->is_log_drain_enabled = false; + $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + return; + } + $this->database->save(); + $this->emit('success', 'Database updated successfully.'); + $this->emit('success', 'You need to restart the service for the changes to take effect.'); + } catch (Exception $e) { + return handleError($e, $this); + } + } public function submit() { try { diff --git a/app/Http/Livewire/Project/Service/Application.php b/app/Http/Livewire/Project/Service/Application.php index 701a90c19..8a785b9c6 100644 --- a/app/Http/Livewire/Project/Service/Application.php +++ b/app/Http/Livewire/Project/Service/Application.php @@ -16,6 +16,7 @@ class Application extends Component 'application.image' => 'required', 'application.exclude_from_status' => 'required|boolean', 'application.required_fqdn' => 'required|boolean', + 'application.is_log_drain_enabled' => 'nullable|boolean', ]; public function render() { @@ -25,7 +26,11 @@ public function instantSave() { $this->submit(); } - + public function instantSaveAdvanced() + { + $this->submit(); + $this->emit('success', 'You need to restart the service for the changes to take effect.'); + } public function delete() { try { @@ -44,6 +49,11 @@ public function submit() { try { $this->validate(); + if (!$this->application->service->destination->server->isLogDrainEnabled()) { + $this->application->is_log_drain_enabled = false; + $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + return; + } $this->application->save(); updateCompose($this->application); $this->emit('success', 'Application saved successfully.'); diff --git a/app/Http/Livewire/Project/Service/Database.php b/app/Http/Livewire/Project/Service/Database.php index dee2785ba..6bf6098ad 100644 --- a/app/Http/Livewire/Project/Service/Database.php +++ b/app/Http/Livewire/Project/Service/Database.php @@ -21,18 +21,31 @@ class Database extends Component 'database.exclude_from_status' => 'required|boolean', 'database.public_port' => 'nullable|integer', 'database.is_public' => 'required|boolean', + 'database.is_log_drain_enabled' => 'required|boolean', ]; public function render() { return view('livewire.project.service.database'); } - public function mount() { + public function mount() + { if ($this->database->is_public) { $this->db_url_public = $this->database->getServiceDatabaseUrl(); } $this->refreshFileStorages(); } - public function instantSave() { + public function instantSaveAdvanced() + { + if (!$this->database->service->destination->server->isLogDrainEnabled()) { + $this->database->is_log_drain_enabled = false; + $this->emit('error', 'Log drain is not enabled on the server. Please enable it first.'); + return; + } + $this->submit(); + $this->emit('success', 'You need to restart the service for the changes to take effect.'); + } + public function instantSave() + { if ($this->database->is_public && !$this->database->public_port) { $this->emit('error', 'Public port is required.'); $this->database->is_public = false; diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 4e4f66301..dacdbf89b 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -864,7 +864,7 @@ private function generate_compose_file() ] ] ]; - if ($this->server->isDrainLogActivated()) { + if ($this->server->isLogDrainEnabled() && $this->application->isLogDrainEnabled()) { $docker_compose['services'][$this->container_name]['logging'] = [ 'driver' => 'fluentd', 'options' => [ diff --git a/app/Models/Application.php b/app/Models/Application.php index 27f34df34..cb3d85f94 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -300,6 +300,9 @@ public function isHealthcheckDisabled(): bool } return false; } + public function isLogDrainEnabled() { + return data_get($this, 'settings.is_log_drain_enabled', false); + } public function isConfigurationChanged($save = false) { $newConfigHash = $this->fqdn . $this->git_repository . $this->git_branch . $this->git_commit_sha . $this->build_pack . $this->static_image . $this->install_command . $this->build_command . $this->start_command . $this->port_exposes . $this->port_mappings . $this->base_directory . $this->publish_directory . $this->health_check_path . $this->health_check_port . $this->health_check_host . $this->health_check_method . $this->health_check_return_code . $this->health_check_scheme . $this->health_check_response_text . $this->health_check_interval . $this->health_check_timeout . $this->health_check_retries . $this->health_check_start_period . $this->health_check_enabled . $this->limits_memory . $this->limits_swap . $this->limits_swappiness . $this->limits_reservation . $this->limits_cpus . $this->limits_cpuset . $this->limits_cpu_shares . $this->dockerfile . $this->dockerfile_location . $this->custom_labels; diff --git a/app/Models/Server.php b/app/Models/Server.php index f00f772a8..9d91ea123 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -304,7 +304,7 @@ public function isFunctional() { return $this->settings->is_reachable && $this->settings->is_usable; } - public function isDrainLogActivated() + public function isLogDrainEnabled() { return $this->settings->is_logdrain_newrelic_enabled || $this->settings->is_logdrain_highlight_enabled || $this->settings->is_logdrain_axiom_enabled; } diff --git a/app/Models/Service.php b/app/Models/Service.php index 76c88eb85..cf78e8260 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -797,7 +797,7 @@ public function parse(bool $isNew = false): Collection $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true)); } } - if ($this->server->isDrainLogActivated()) { + if ($this->server->isLogDrainEnabled() && $savedService->isLogDrainEnabled()) { data_set($service, 'logging', [ 'driver' => 'fluentd', 'options' => [ diff --git a/app/Models/ServiceApplication.php b/app/Models/ServiceApplication.php index b1db1c581..b8e3f1a41 100644 --- a/app/Models/ServiceApplication.php +++ b/app/Models/ServiceApplication.php @@ -18,6 +18,10 @@ protected static function booted() $service->fileStorages()->delete(); }); } + public function isLogDrainEnabled() + { + return data_get($this, 'is_log_drain_enabled', false); + } public function type() { return 'service'; diff --git a/app/Models/ServiceDatabase.php b/app/Models/ServiceDatabase.php index 2feaeb947..79c1dd176 100644 --- a/app/Models/ServiceDatabase.php +++ b/app/Models/ServiceDatabase.php @@ -16,6 +16,10 @@ protected static function booted() $service->fileStorages()->delete(); }); } + public function isLogDrainEnabled() + { + return data_get($this, 'is_log_drain_enabled', false); + } public function type() { return 'service'; diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index f9f3ad1ae..cb9fa9aa2 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -41,6 +41,10 @@ protected static function booted() $database->environment_variables()->delete(); }); } + public function isLogDrainEnabled() + { + return data_get($this, 'is_log_drain_enabled', false); + } public function type(): string { return 'standalone-mariadb'; diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index 628cb6942..3a5b7a52a 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -44,7 +44,10 @@ protected static function booted() $database->environment_variables()->delete(); }); } - + public function isLogDrainEnabled() + { + return data_get($this, 'is_log_drain_enabled', false); + } public function mongoInitdbRootPassword(): Attribute { return Attribute::make( diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index d7314f59b..6de57cb73 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -46,6 +46,11 @@ public function type(): string return 'standalone-mysql'; } + public function isLogDrainEnabled() + { + return data_get($this, 'is_log_drain_enabled', false); + } + public function portsMappings(): Attribute { return Attribute::make( diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index ca19e7a87..1bef3b6c9 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -42,6 +42,11 @@ protected static function booted() }); } + public function isLogDrainEnabled() + { + return data_get($this, 'is_log_drain_enabled', false); + } + public function portsMappings(): Attribute { return Attribute::make( diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index a0de53a3e..fe1281c22 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -37,6 +37,11 @@ protected static function booted() }); } + public function isLogDrainEnabled() + { + return data_get($this, 'is_log_drain_enabled', false); + } + public function portsMappings(): Attribute { return Attribute::make( diff --git a/config/sentry.php b/config/sentry.php index d1111bbd4..0c8ab1b30 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.143', + 'release' => '4.0.0-beta.144', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 318484b79..a4a00caab 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ boolean('is_log_drain_enabled')->default(false); + }); + Schema::table('standalone_redis', function (Blueprint $table) { + $table->boolean('is_log_drain_enabled')->default(false); + }); + Schema::table('standalone_mysqls', function (Blueprint $table) { + $table->boolean('is_log_drain_enabled')->default(false); + }); + Schema::table('standalone_mariadbs', function (Blueprint $table) { + $table->boolean('is_log_drain_enabled')->default(false); + }); + Schema::table('standalone_postgresqls', function (Blueprint $table) { + $table->boolean('is_log_drain_enabled')->default(false); + }); + Schema::table('standalone_mongodbs', function (Blueprint $table) { + $table->boolean('is_log_drain_enabled')->default(false); + }); + Schema::table('service_applications', function (Blueprint $table) { + $table->boolean('is_log_drain_enabled')->default(false); + }); + Schema::table('service_databases', function (Blueprint $table) { + $table->boolean('is_log_drain_enabled')->default(false); + }); + + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('application_settings', function (Blueprint $table) { + $table->dropColumn('is_log_drain_enabled'); + }); + Schema::table('standalone_redis', function (Blueprint $table) { + $table->dropColumn('is_log_drain_enabled'); + }); + Schema::table('standalone_mysqls', function (Blueprint $table) { + $table->dropColumn('is_log_drain_enabled'); + }); + Schema::table('standalone_mariadbs', function (Blueprint $table) { + $table->dropColumn('is_log_drain_enabled'); + }); + Schema::table('standalone_postgresqls', function (Blueprint $table) { + $table->dropColumn('is_log_drain_enabled'); + }); + Schema::table('standalone_mongodbs', function (Blueprint $table) { + $table->dropColumn('is_log_drain_enabled'); + }); + Schema::table('service_applications', function (Blueprint $table) { + $table->dropColumn('is_log_drain_enabled'); + }); + Schema::table('service_databases', function (Blueprint $table) { + $table->dropColumn('is_log_drain_enabled'); + }); + + } +}; diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index 2753b4bf7..7d7b9c999 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -114,6 +114,8 @@

Advanced

+ diff --git a/resources/views/livewire/project/database/mariadb/general.blade.php b/resources/views/livewire/project/database/mariadb/general.blade.php index 520e29eaa..361f476df 100644 --- a/resources/views/livewire/project/database/mariadb/general.blade.php +++ b/resources/views/livewire/project/database/mariadb/general.blade.php @@ -59,5 +59,10 @@ @endif
+

Advanced

+
+ +
diff --git a/resources/views/livewire/project/database/mongodb/general.blade.php b/resources/views/livewire/project/database/mongodb/general.blade.php index 8aab8dd42..f55140bf2 100644 --- a/resources/views/livewire/project/database/mongodb/general.blade.php +++ b/resources/views/livewire/project/database/mongodb/general.blade.php @@ -16,8 +16,8 @@
- + @@ -44,14 +44,19 @@
@if ($db_url_public) - + @endif +

Advanced

+
+ +
diff --git a/resources/views/livewire/project/database/mysql/general.blade.php b/resources/views/livewire/project/database/mysql/general.blade.php index 6db2fd8eb..aef1b006d 100644 --- a/resources/views/livewire/project/database/mysql/general.blade.php +++ b/resources/views/livewire/project/database/mysql/general.blade.php @@ -59,5 +59,10 @@ @endif +

Advanced

+
+ +
diff --git a/resources/views/livewire/project/database/postgresql/general.blade.php b/resources/views/livewire/project/database/postgresql/general.blade.php index 3116620ea..7554ae17f 100644 --- a/resources/views/livewire/project/database/postgresql/general.blade.php +++ b/resources/views/livewire/project/database/postgresql/general.blade.php @@ -74,6 +74,11 @@ +

Advanced

+
+ +

Initialization scripts

@@ -87,4 +92,5 @@ @endforelse
+ diff --git a/resources/views/livewire/project/database/redis/general.blade.php b/resources/views/livewire/project/database/redis/general.blade.php index 9f709b656..0d2b7bb42 100644 --- a/resources/views/livewire/project/database/redis/general.blade.php +++ b/resources/views/livewire/project/database/redis/general.blade.php @@ -33,5 +33,10 @@ +

Advanced

+
+ +
diff --git a/resources/views/livewire/project/service/application.blade.php b/resources/views/livewire/project/service/application.blade.php index db1329f81..f8809686c 100644 --- a/resources/views/livewire/project/service/application.blade.php +++ b/resources/views/livewire/project/service/application.blade.php @@ -36,6 +36,8 @@ + diff --git a/resources/views/livewire/project/service/database.blade.php b/resources/views/livewire/project/service/database.blade.php index e9318e13c..7868c5b07 100644 --- a/resources/views/livewire/project/service/database.blade.php +++ b/resources/views/livewire/project/service/database.blade.php @@ -32,6 +32,8 @@ + diff --git a/versions.json b/versions.json index 394ef8d40..ae88d1617 100644 --- a/versions.json +++ b/versions.json @@ -4,7 +4,7 @@ "version": "3.12.36" }, "v4": { - "version": "4.0.0-beta.143" + "version": "4.0.0-beta.144" } } } From 689480003ac4f8e7b877d347dd4e9b60cd5b661c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 17 Nov 2023 21:16:25 +0100 Subject: [PATCH 2/3] feat: log drainer container check --- app/Actions/Server/InstallLogDrain.php | 11 ++- app/Console/Kernel.php | 4 + app/Http/Livewire/Server/LogDrains.php | 11 +-- app/Jobs/CheckLogDrainContainerJob.php | 83 +++++++++++++++++++ app/Jobs/ContainerStatusJob.php | 48 ++++++----- app/Models/Server.php | 4 - .../Container/ContainerRestarted.php | 6 +- .../Container/ContainerStopped.php | 6 +- ...160437_add_drain_log_enable_by_service.php | 8 +- .../emails/container-restarted.blade.php | 2 +- .../views/emails/container-stopped.blade.php | 2 +- .../livewire/server/log-drains.blade.php | 2 +- 12 files changed, 140 insertions(+), 47 deletions(-) create mode 100644 app/Jobs/CheckLogDrainContainerJob.php diff --git a/app/Actions/Server/InstallLogDrain.php b/app/Actions/Server/InstallLogDrain.php index 4db355aa8..11487d633 100644 --- a/app/Actions/Server/InstallLogDrain.php +++ b/app/Actions/Server/InstallLogDrain.php @@ -8,8 +8,17 @@ class InstallLogDrain { use AsAction; - public function handle(Server $server, string $type) + public function handle(Server $server) { + if ($server->settings->is_logdrain_newrelic_enabled) { + $type = 'newrelic'; + } else if ($server->settings->is_logdrain_highlight_enabled) { + $type = 'highlight'; + } else if ($server->settings->is_logdrain_axiom_enabled) { + $type = 'axiom'; + } else { + $type = 'none'; + } try { if ($type === 'none') { $command = [ diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index fa195aafd..e24d657a9 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,6 +2,7 @@ namespace App\Console; +use App\Jobs\CheckLogDrainContainerJob; use App\Jobs\CleanupInstanceStuffsJob; use App\Jobs\DatabaseBackupJob; use App\Jobs\InstanceAutoUpdateJob; @@ -61,6 +62,9 @@ private function check_resources($schedule) foreach ($servers as $server) { $schedule->job(new ServerStatusJob($server))->everyTenMinutes()->onOneServer(); $schedule->job(new ContainerStatusJob($server))->everyMinute()->onOneServer(); + if ($server->isLogDrainEnabled()) { + $schedule->job(new CheckLogDrainContainerJob($server))->everyMinute()->onOneServer(); + } } } private function instance_auto_update($schedule) diff --git a/app/Http/Livewire/Server/LogDrains.php b/app/Http/Livewire/Server/LogDrains.php index cb7a5138a..056beb584 100644 --- a/app/Http/Livewire/Server/LogDrains.php +++ b/app/Http/Livewire/Server/LogDrains.php @@ -2,6 +2,7 @@ namespace App\Http\Livewire\Server; +use App\Actions\Server\InstallLogDrain; use App\Models\Server; use Livewire\Component; @@ -46,14 +47,8 @@ public function mount() public function configureLogDrain() { try { - if ($this->server->settings->is_logdrain_newrelic_enabled) { - $this->server->logDrain('newrelic'); - } else if ($this->server->settings->is_logdrain_highlight_enabled) { - $this->server->logDrain('highlight'); - } else if ($this->server->settings->is_logdrain_axiom_enabled) { - $this->server->logDrain('axiom'); - } else { - $this->server->logDrain('none'); + InstallLogDrain::run($this->server); + if (!$this->server->isLogDrainEnabled()) { $this->emit('serverRefresh'); $this->emit('success', 'Log drain service stopped.'); return; diff --git a/app/Jobs/CheckLogDrainContainerJob.php b/app/Jobs/CheckLogDrainContainerJob.php new file mode 100644 index 000000000..2bf59913a --- /dev/null +++ b/app/Jobs/CheckLogDrainContainerJob.php @@ -0,0 +1,83 @@ +server->id))->dontRelease()]; + } + + public function uniqueId(): int + { + return $this->server->id; + } + public function healthcheck() + { + $status = instant_remote_process(["docker inspect --format='{{json .State.Status}}' coolify-log-drain"], $this->server, false); + if (str($status)->contains('running')) { + return true; + } else { + return false; + } + } + public function handle(): void + { + // ray("checking log drain statuses for {$this->server->id}"); + try { + if (!$this->server->isServerReady()) { + return; + }; + $containers = instant_remote_process(["docker container ls -q"], $this->server); + if (!$containers) { + return; + } + $containers = instant_remote_process(["docker container inspect $(docker container ls -q) --format '{{json .}}'"], $this->server); + $containers = format_docker_command_output_to_json($containers); + + $foundLogDrainContainer = $containers->filter(function ($value, $key) { + return data_get($value, 'Name') === '/coolify-log-drain'; + })->first(); + if (!$foundLogDrainContainer || !$this->healthcheck()) { + ray('Log drain container not found or unhealthy. Restarting...'); + InstallLogDrain::run($this->server); + Sleep::for(10)->seconds(); + if ($this->healthcheck()) { + if ($this->server->log_drain_notification_sent) { + $this->server->team->notify(new ContainerRestarted('Coolify Log Drainer', $this->server)); + $this->server->update(['log_drain_notification_sent' => false]); + } + return; + } + if (!$this->server->log_drain_notification_sent) { + ray('Log drain container still unhealthy. Sending notification...'); + $this->server->team->notify(new ContainerStopped('Coolify Log Drainer', $this->server, null)); + $this->server->update(['log_drain_notification_sent' => true]); + } + } + } catch (\Throwable $e) { + send_internal_notification("CheckLogDrainContainerJob failed on ({$this->server->id}) with: " . $e->getMessage()); + ray($e->getMessage()); + handleError($e); + } + } +} diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 1c66ef53f..34678b18a 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -52,29 +52,7 @@ public function handle(): void $databases = $this->server->databases(); $services = $this->server->services()->get(); $previews = $this->server->previews(); - $this->server->proxyType(); - /// Check if proxy is running - $foundProxyContainer = $containers->filter(function ($value, $key) { - return data_get($value, 'Name') === '/coolify-proxy'; - })->first(); - if (!$foundProxyContainer) { - try { - $shouldStart = CheckProxy::run($this->server); - if ($shouldStart) { - StartProxy::run($this->server, false); - $this->server->team->notify(new ContainerRestarted('coolify-proxy', $this->server)); - } else { - ray('Proxy could not be started.'); - } - } catch (\Throwable $e) { - ray($e); - } - } else { - $this->server->proxy->status = data_get($foundProxyContainer, 'State.Status'); - $this->server->save(); - $connectProxyToDockerNetworks = connectProxyToNetworks($this->server); - instant_remote_process($connectProxyToDockerNetworks, $this->server, false); - } + $foundApplications = []; $foundApplicationPreviews = []; $foundDatabases = []; @@ -267,6 +245,30 @@ public function handle(): void } $this->server->team->notify(new ContainerStopped($containerName, $this->server, $url)); } + + // Check if proxy is running + $this->server->proxyType(); + $foundProxyContainer = $containers->filter(function ($value, $key) { + return data_get($value, 'Name') === '/coolify-proxy'; + })->first(); + if (!$foundProxyContainer) { + try { + $shouldStart = CheckProxy::run($this->server); + if ($shouldStart) { + StartProxy::run($this->server, false); + $this->server->team->notify(new ContainerRestarted('coolify-proxy', $this->server)); + } else { + ray('Proxy could not be started.'); + } + } catch (\Throwable $e) { + ray($e); + } + } else { + $this->server->proxy->status = data_get($foundProxyContainer, 'State.Status'); + $this->server->save(); + $connectProxyToDockerNetworks = connectProxyToNetworks($this->server); + instant_remote_process($connectProxyToDockerNetworks, $this->server, false); + } } catch (\Throwable $e) { send_internal_notification("ContainerStatusJob failed on ({$this->server->id}) with: " . $e->getMessage()); ray($e->getMessage()); diff --git a/app/Models/Server.php b/app/Models/Server.php index 9d91ea123..02c3186c6 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -296,10 +296,6 @@ public function isProxyShouldRun() // } return true; } - public function logDrain($type) - { - InstallLogDrain::run($this, $type); - } public function isFunctional() { return $this->settings->is_reachable && $this->settings->is_usable; diff --git a/app/Notifications/Container/ContainerRestarted.php b/app/Notifications/Container/ContainerRestarted.php index dc55c05d2..723cad8f6 100644 --- a/app/Notifications/Container/ContainerRestarted.php +++ b/app/Notifications/Container/ContainerRestarted.php @@ -27,7 +27,7 @@ public function via(object $notifiable): array public function toMail(): MailMessage { $mail = new MailMessage(); - $mail->subject("Coolify: Container ({$this->name}) has been restarted automatically on {$this->server->name}"); + $mail->subject("Coolify: A service ({$this->name}) has been restarted automatically on {$this->server->name}"); $mail->view('emails.container-restarted', [ 'containerName' => $this->name, 'serverName' => $this->server->name, @@ -38,12 +38,12 @@ public function toMail(): MailMessage public function toDiscord(): string { - $message = "Coolify: Container ({$this->name}) has been restarted automatically on {$this->server->name}"; + $message = "Coolify: A service ({$this->name}) has been restarted automatically on {$this->server->name}"; return $message; } public function toTelegram(): array { - $message = "Coolify: Container ({$this->name}) has been restarted automatically on {$this->server->name}"; + $message = "Coolify: A service ({$this->name}) has been restarted automatically on {$this->server->name}"; $payload = [ "message" => $message, ]; diff --git a/app/Notifications/Container/ContainerStopped.php b/app/Notifications/Container/ContainerStopped.php index 4518698fb..ea474a3e9 100644 --- a/app/Notifications/Container/ContainerStopped.php +++ b/app/Notifications/Container/ContainerStopped.php @@ -26,7 +26,7 @@ public function via(object $notifiable): array public function toMail(): MailMessage { $mail = new MailMessage(); - $mail->subject("Coolify: Container ({$this->name}) has been stopped on {$this->server->name}"); + $mail->subject("Coolify: A service ({$this->name}) has been stopped on {$this->server->name}"); $mail->view('emails.container-stopped', [ 'containerName' => $this->name, 'serverName' => $this->server->name, @@ -37,12 +37,12 @@ public function toMail(): MailMessage public function toDiscord(): string { - $message = "Coolify: Container ({$this->name}) has been stopped on {$this->server->name}"; + $message = "Coolify: A service ({$this->name}) has been stopped on {$this->server->name}"; return $message; } public function toTelegram(): array { - $message = "Coolify: Container ($this->name} has been stopped on {$this->server->name}"; + $message = "Coolify: A service ($this->name} has been stopped on {$this->server->name}"; $payload = [ "message" => $message, ]; diff --git a/database/migrations/2023_11_17_160437_add_drain_log_enable_by_service.php b/database/migrations/2023_11_17_160437_add_drain_log_enable_by_service.php index f68a268b1..8d0853be3 100644 --- a/database/migrations/2023_11_17_160437_add_drain_log_enable_by_service.php +++ b/database/migrations/2023_11_17_160437_add_drain_log_enable_by_service.php @@ -35,7 +35,9 @@ public function up(): void Schema::table('service_databases', function (Blueprint $table) { $table->boolean('is_log_drain_enabled')->default(false); }); - + Schema::table('servers', function (Blueprint $table) { + $table->boolean('log_drain_notification_sent')->default(false); + }); } /** @@ -67,6 +69,8 @@ public function down(): void Schema::table('service_databases', function (Blueprint $table) { $table->dropColumn('is_log_drain_enabled'); }); - + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('log_drain_notification_sent'); + }); } }; diff --git a/resources/views/emails/container-restarted.blade.php b/resources/views/emails/container-restarted.blade.php index ebc7f99fb..085aafa53 100644 --- a/resources/views/emails/container-restarted.blade.php +++ b/resources/views/emails/container-restarted.blade.php @@ -1,6 +1,6 @@ -Container ({{ $containerName }}) has been restarted automatically on {{$serverName}}, because it was stopped unexpectedly. +A service ({{ $containerName }}) has been restarted automatically on {{$serverName}}, because it was stopped unexpectedly. @if ($containerName === 'coolify-proxy') Coolify Proxy should run on your server as you have FQDNs set up in one of your resources. diff --git a/resources/views/emails/container-stopped.blade.php b/resources/views/emails/container-stopped.blade.php index 575e740b2..bf7cc086a 100644 --- a/resources/views/emails/container-stopped.blade.php +++ b/resources/views/emails/container-stopped.blade.php @@ -1,6 +1,6 @@ -Container {{ $containerName }} has been stopped unexpectedly on {{$serverName}}. +A service ({{ $containerName }}) has been stopped unexpectedly on {{$serverName}}. @if ($url) Please check what is going on [here]({{ $url }}). diff --git a/resources/views/livewire/server/log-drains.blade.php b/resources/views/livewire/server/log-drains.blade.php index 60f51665c..2e1109dc7 100644 --- a/resources/views/livewire/server/log-drains.blade.php +++ b/resources/views/livewire/server/log-drains.blade.php @@ -1,7 +1,7 @@

Log Drains

-
Sends resource logs to external services.
+
Sends service logs to 3rd party tools.
From 8a9ee8492501be1db601a25f0dfe04f934a762e1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 17 Nov 2023 21:24:22 +0100 Subject: [PATCH 3/3] Fix log drain container notification bug --- app/Jobs/CheckLogDrainContainerJob.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Jobs/CheckLogDrainContainerJob.php b/app/Jobs/CheckLogDrainContainerJob.php index 2bf59913a..e315728ec 100644 --- a/app/Jobs/CheckLogDrainContainerJob.php +++ b/app/Jobs/CheckLogDrainContainerJob.php @@ -73,6 +73,11 @@ public function handle(): void $this->server->team->notify(new ContainerStopped('Coolify Log Drainer', $this->server, null)); $this->server->update(['log_drain_notification_sent' => true]); } + } else { + if ($this->server->log_drain_notification_sent) { + $this->server->team->notify(new ContainerRestarted('Coolify Log Drainer', $this->server)); + $this->server->update(['log_drain_notification_sent' => false]); + } } } catch (\Throwable $e) { send_internal_notification("CheckLogDrainContainerJob failed on ({$this->server->id}) with: " . $e->getMessage());