| @@ -69,7 +69,7 @@ class StartMariadb | |||||||
|                 ] |                 ] | ||||||
|             ] |             ] | ||||||
|         ]; |         ]; | ||||||
|         if ($this->database->destination->server->isDrainLogActivated()) { |         if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { | ||||||
|             $docker_compose['services'][$container_name]['logging'] = [ |             $docker_compose['services'][$container_name]['logging'] = [ | ||||||
|                 'driver' => 'fluentd', |                 'driver' => 'fluentd', | ||||||
|                 'options' => [ |                 'options' => [ | ||||||
|   | |||||||
| @@ -76,7 +76,7 @@ class StartMongodb | |||||||
|                 ] |                 ] | ||||||
|             ] |             ] | ||||||
|         ]; |         ]; | ||||||
|         if ($this->database->destination->server->isDrainLogActivated()) { |         if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { | ||||||
|             $docker_compose['services'][$container_name]['logging'] = [ |             $docker_compose['services'][$container_name]['logging'] = [ | ||||||
|                 'driver' => 'fluentd', |                 'driver' => 'fluentd', | ||||||
|                 'options' => [ |                 'options' => [ | ||||||
|   | |||||||
| @@ -69,7 +69,7 @@ class StartMysql | |||||||
|                 ] |                 ] | ||||||
|             ] |             ] | ||||||
|         ]; |         ]; | ||||||
|         if ($this->database->destination->server->isDrainLogActivated()) { |         if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { | ||||||
|             $docker_compose['services'][$container_name]['logging'] = [ |             $docker_compose['services'][$container_name]['logging'] = [ | ||||||
|                 'driver' => 'fluentd', |                 'driver' => 'fluentd', | ||||||
|                 'options' => [ |                 'options' => [ | ||||||
|   | |||||||
| @@ -79,7 +79,8 @@ class StartPostgresql | |||||||
|                 ] |                 ] | ||||||
|             ] |             ] | ||||||
|         ]; |         ]; | ||||||
|         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'] = [ |             $docker_compose['services'][$container_name]['logging'] = [ | ||||||
|                 'driver' => 'fluentd', |                 'driver' => 'fluentd', | ||||||
|                 'options' => [ |                 'options' => [ | ||||||
|   | |||||||
| @@ -78,7 +78,7 @@ class StartRedis | |||||||
|                 ] |                 ] | ||||||
|             ] |             ] | ||||||
|         ]; |         ]; | ||||||
|         if ($this->database->destination->server->isDrainLogActivated()) { |         if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { | ||||||
|             $docker_compose['services'][$container_name]['logging'] = [ |             $docker_compose['services'][$container_name]['logging'] = [ | ||||||
|                 'driver' => 'fluentd', |                 'driver' => 'fluentd', | ||||||
|                 'options' => [ |                 'options' => [ | ||||||
| @@ -166,6 +166,5 @@ class StartRedis | |||||||
|         $content = $this->database->redis_conf; |         $content = $this->database->redis_conf; | ||||||
|         $content_base64 = base64_encode($content); |         $content_base64 = base64_encode($content); | ||||||
|         $this->commands[] = "echo '{$content_base64}' | base64 -d > $this->configuration_dir/{$filename}"; |         $this->commands[] = "echo '{$content_base64}' | base64 -d > $this->configuration_dir/{$filename}"; | ||||||
| 
 |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,8 +8,17 @@ use App\Models\Server; | |||||||
| class InstallLogDrain | class InstallLogDrain | ||||||
| { | { | ||||||
|     use AsAction; |     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 { |         try { | ||||||
|             if ($type === 'none') { |             if ($type === 'none') { | ||||||
|                 $command = [ |                 $command = [ | ||||||
| @@ -127,6 +136,7 @@ services: | |||||||
|       - ./parsers.conf:/parsers.conf |       - ./parsers.conf:/parsers.conf | ||||||
|     ports: |     ports: | ||||||
|       - 127.0.0.1:24224:24224 |       - 127.0.0.1:24224:24224 | ||||||
|  |     restart: unless-stopped | ||||||
| ");
 | ");
 | ||||||
|             $readme = base64_encode('# New Relic Log Drain
 |             $readme = base64_encode('# New Relic Log Drain
 | ||||||
| This log drain is based on [Fluent Bit](https://fluentbit.io/) and New Relic Log Forwarder. | This log drain is based on [Fluent Bit](https://fluentbit.io/) and New Relic Log Forwarder. | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| namespace App\Console; | namespace App\Console; | ||||||
| 
 | 
 | ||||||
|  | use App\Jobs\CheckLogDrainContainerJob; | ||||||
| use App\Jobs\CleanupInstanceStuffsJob; | use App\Jobs\CleanupInstanceStuffsJob; | ||||||
| use App\Jobs\DatabaseBackupJob; | use App\Jobs\DatabaseBackupJob; | ||||||
| use App\Jobs\InstanceAutoUpdateJob; | use App\Jobs\InstanceAutoUpdateJob; | ||||||
| @@ -61,6 +62,9 @@ class Kernel extends ConsoleKernel | |||||||
|         foreach ($servers as $server) { |         foreach ($servers as $server) { | ||||||
|             $schedule->job(new ServerStatusJob($server))->everyTenMinutes()->onOneServer(); |             $schedule->job(new ServerStatusJob($server))->everyTenMinutes()->onOneServer(); | ||||||
|             $schedule->job(new ContainerStatusJob($server))->everyMinute()->onOneServer(); |             $schedule->job(new ContainerStatusJob($server))->everyMinute()->onOneServer(); | ||||||
|  |             if ($server->isLogDrainEnabled()) { | ||||||
|  |                 $schedule->job(new CheckLogDrainContainerJob($server))->everyMinute()->onOneServer(); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     private function instance_auto_update($schedule) |     private function instance_auto_update($schedule) | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ class General extends Component | |||||||
|     public bool $is_preview_deployments_enabled; |     public bool $is_preview_deployments_enabled; | ||||||
|     public bool $is_auto_deploy_enabled; |     public bool $is_auto_deploy_enabled; | ||||||
|     public bool $is_force_https_enabled; |     public bool $is_force_https_enabled; | ||||||
| 
 |     public bool $is_log_drain_enabled; | ||||||
| 
 | 
 | ||||||
|     protected $rules = [ |     protected $rules = [ | ||||||
|         'application.name' => 'required', |         'application.name' => 'required', | ||||||
| @@ -101,6 +101,7 @@ class General extends Component | |||||||
|             $this->is_preview_deployments_enabled = $this->application->settings->is_preview_deployments_enabled; |             $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_auto_deploy_enabled = $this->application->settings->is_auto_deploy_enabled; | ||||||
|             $this->is_force_https_enabled = $this->application->settings->is_force_https_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(); |         $this->checkLabelUpdates(); | ||||||
|     } |     } | ||||||
| @@ -136,6 +137,14 @@ class General extends Component | |||||||
|         $this->application->settings->is_preview_deployments_enabled = $this->is_preview_deployments_enabled; |         $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_auto_deploy_enabled = $this->is_auto_deploy_enabled; | ||||||
|         $this->application->settings->is_force_https_enabled = $this->is_force_https_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->settings->save(); | ||||||
|         $this->application->save(); |         $this->application->save(); | ||||||
|         $this->application->refresh(); |         $this->application->refresh(); | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ class General extends Component | |||||||
|         'database.ports_mappings' => 'nullable', |         'database.ports_mappings' => 'nullable', | ||||||
|         'database.is_public' => 'nullable|boolean', |         'database.is_public' => 'nullable|boolean', | ||||||
|         'database.public_port' => 'nullable|integer', |         'database.public_port' => 'nullable|integer', | ||||||
|  |         'database.is_log_drain_enabled' => 'nullable|boolean', | ||||||
|     ]; |     ]; | ||||||
|     protected $validationAttributes = [ |     protected $validationAttributes = [ | ||||||
|         'database.name' => 'Name', |         'database.name' => 'Name', | ||||||
| @@ -50,6 +51,20 @@ class General extends Component | |||||||
|             $this->db_url_public = $this->database->getDbUrl(); |             $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() |     public function submit() | ||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ class General extends Component | |||||||
|         'database.ports_mappings' => 'nullable', |         'database.ports_mappings' => 'nullable', | ||||||
|         'database.is_public' => 'nullable|boolean', |         'database.is_public' => 'nullable|boolean', | ||||||
|         'database.public_port' => 'nullable|integer', |         'database.public_port' => 'nullable|integer', | ||||||
|  |         'database.is_log_drain_enabled' => 'nullable|boolean', | ||||||
|     ]; |     ]; | ||||||
|     protected $validationAttributes = [ |     protected $validationAttributes = [ | ||||||
|         'database.name' => 'Name', |         'database.name' => 'Name', | ||||||
| @@ -48,7 +49,21 @@ class General extends Component | |||||||
|             $this->db_url_public = $this->database->getDbUrl(); |             $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() |     public function submit() | ||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ class General extends Component | |||||||
|         'database.ports_mappings' => 'nullable', |         'database.ports_mappings' => 'nullable', | ||||||
|         'database.is_public' => 'nullable|boolean', |         'database.is_public' => 'nullable|boolean', | ||||||
|         'database.public_port' => 'nullable|integer', |         'database.public_port' => 'nullable|integer', | ||||||
|  |         'database.is_log_drain_enabled' => 'nullable|boolean', | ||||||
|     ]; |     ]; | ||||||
|     protected $validationAttributes = [ |     protected $validationAttributes = [ | ||||||
|         'database.name' => 'Name', |         'database.name' => 'Name', | ||||||
| @@ -50,6 +51,21 @@ class General extends Component | |||||||
|             $this->db_url_public = $this->database->getDbUrl(); |             $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() |     public function submit() | ||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ class General extends Component | |||||||
|         'database.ports_mappings' => 'nullable', |         'database.ports_mappings' => 'nullable', | ||||||
|         'database.is_public' => 'nullable|boolean', |         'database.is_public' => 'nullable|boolean', | ||||||
|         'database.public_port' => 'nullable|integer', |         'database.public_port' => 'nullable|integer', | ||||||
|  |         'database.is_log_drain_enabled' => 'nullable|boolean', | ||||||
|     ]; |     ]; | ||||||
|     protected $validationAttributes = [ |     protected $validationAttributes = [ | ||||||
|         'database.name' => 'Name', |         'database.name' => 'Name', | ||||||
| @@ -57,6 +58,20 @@ class General extends Component | |||||||
|             $this->db_url_public = $this->database->getDbUrl(); |             $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() |     public function instantSave() | ||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ class General extends Component | |||||||
|         'database.ports_mappings' => 'nullable', |         'database.ports_mappings' => 'nullable', | ||||||
|         'database.is_public' => 'nullable|boolean', |         'database.is_public' => 'nullable|boolean', | ||||||
|         'database.public_port' => 'nullable|integer', |         'database.public_port' => 'nullable|integer', | ||||||
|  |         'database.is_log_drain_enabled' => 'nullable|boolean', | ||||||
|     ]; |     ]; | ||||||
|     protected $validationAttributes = [ |     protected $validationAttributes = [ | ||||||
|         'database.name' => 'Name', |         'database.name' => 'Name', | ||||||
| @@ -43,6 +44,20 @@ class General extends Component | |||||||
|             $this->db_url_public = $this->database->getDbUrl(); |             $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() |     public function submit() | ||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ class Application extends Component | |||||||
|         'application.image' => 'required', |         'application.image' => 'required', | ||||||
|         'application.exclude_from_status' => 'required|boolean', |         'application.exclude_from_status' => 'required|boolean', | ||||||
|         'application.required_fqdn' => 'required|boolean', |         'application.required_fqdn' => 'required|boolean', | ||||||
|  |         'application.is_log_drain_enabled' => 'nullable|boolean', | ||||||
|     ]; |     ]; | ||||||
|     public function render() |     public function render() | ||||||
|     { |     { | ||||||
| @@ -25,7 +26,11 @@ class Application extends Component | |||||||
|     { |     { | ||||||
|         $this->submit(); |         $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() |     public function delete() | ||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
| @@ -44,6 +49,11 @@ class Application extends Component | |||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
|             $this->validate(); |             $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(); |             $this->application->save(); | ||||||
|             updateCompose($this->application); |             updateCompose($this->application); | ||||||
|             $this->emit('success', 'Application saved successfully.'); |             $this->emit('success', 'Application saved successfully.'); | ||||||
|   | |||||||
| @@ -21,18 +21,31 @@ class Database extends Component | |||||||
|         'database.exclude_from_status' => 'required|boolean', |         'database.exclude_from_status' => 'required|boolean', | ||||||
|         'database.public_port' => 'nullable|integer', |         'database.public_port' => 'nullable|integer', | ||||||
|         'database.is_public' => 'required|boolean', |         'database.is_public' => 'required|boolean', | ||||||
|  |         'database.is_log_drain_enabled' => 'required|boolean', | ||||||
|     ]; |     ]; | ||||||
|     public function render() |     public function render() | ||||||
|     { |     { | ||||||
|         return view('livewire.project.service.database'); |         return view('livewire.project.service.database'); | ||||||
|     } |     } | ||||||
|     public function mount() { |     public function mount() | ||||||
|  |     { | ||||||
|         if ($this->database->is_public) { |         if ($this->database->is_public) { | ||||||
|             $this->db_url_public = $this->database->getServiceDatabaseUrl(); |             $this->db_url_public = $this->database->getServiceDatabaseUrl(); | ||||||
|         } |         } | ||||||
|         $this->refreshFileStorages(); |         $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) { |         if ($this->database->is_public && !$this->database->public_port) { | ||||||
|             $this->emit('error', 'Public port is required.'); |             $this->emit('error', 'Public port is required.'); | ||||||
|             $this->database->is_public = false; |             $this->database->is_public = false; | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| namespace App\Http\Livewire\Server; | namespace App\Http\Livewire\Server; | ||||||
| 
 | 
 | ||||||
|  | use App\Actions\Server\InstallLogDrain; | ||||||
| use App\Models\Server; | use App\Models\Server; | ||||||
| use Livewire\Component; | use Livewire\Component; | ||||||
| 
 | 
 | ||||||
| @@ -46,14 +47,8 @@ class LogDrains extends Component | |||||||
|     public function configureLogDrain() |     public function configureLogDrain() | ||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
|             if ($this->server->settings->is_logdrain_newrelic_enabled) { |             InstallLogDrain::run($this->server); | ||||||
|                 $this->server->logDrain('newrelic'); |             if (!$this->server->isLogDrainEnabled()) { | ||||||
|             } 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'); |  | ||||||
|                 $this->emit('serverRefresh'); |                 $this->emit('serverRefresh'); | ||||||
|                 $this->emit('success', 'Log drain service stopped.'); |                 $this->emit('success', 'Log drain service stopped.'); | ||||||
|                 return; |                 return; | ||||||
|   | |||||||
| @@ -864,7 +864,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted | |||||||
|                 ] |                 ] | ||||||
|             ] |             ] | ||||||
|         ]; |         ]; | ||||||
|         if ($this->server->isDrainLogActivated()) { |         if ($this->server->isLogDrainEnabled() && $this->application->isLogDrainEnabled()) { | ||||||
|             $docker_compose['services'][$this->container_name]['logging'] = [ |             $docker_compose['services'][$this->container_name]['logging'] = [ | ||||||
|                 'driver' => 'fluentd', |                 'driver' => 'fluentd', | ||||||
|                 'options' => [ |                 'options' => [ | ||||||
|   | |||||||
							
								
								
									
										88
									
								
								app/Jobs/CheckLogDrainContainerJob.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/Jobs/CheckLogDrainContainerJob.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace App\Jobs; | ||||||
|  | 
 | ||||||
|  | use App\Actions\Server\InstallLogDrain; | ||||||
|  | use App\Models\Server; | ||||||
|  | use App\Notifications\Container\ContainerRestarted; | ||||||
|  | use App\Notifications\Container\ContainerStopped; | ||||||
|  | use Illuminate\Bus\Queueable; | ||||||
|  | use Illuminate\Contracts\Queue\ShouldBeEncrypted; | ||||||
|  | use Illuminate\Contracts\Queue\ShouldQueue; | ||||||
|  | use Illuminate\Foundation\Bus\Dispatchable; | ||||||
|  | use Illuminate\Queue\InteractsWithQueue; | ||||||
|  | use Illuminate\Queue\Middleware\WithoutOverlapping; | ||||||
|  | use Illuminate\Queue\SerializesModels; | ||||||
|  | use Illuminate\Support\Sleep; | ||||||
|  | 
 | ||||||
|  | class CheckLogDrainContainerJob implements ShouldQueue, ShouldBeEncrypted | ||||||
|  | { | ||||||
|  |     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | ||||||
|  | 
 | ||||||
|  |     public function __construct(public Server $server) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |     public function middleware(): array | ||||||
|  |     { | ||||||
|  |         return [(new WithoutOverlapping($this->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]); | ||||||
|  |                 } | ||||||
|  |             } 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()); | ||||||
|  |             ray($e->getMessage()); | ||||||
|  |             handleError($e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -52,29 +52,7 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted | |||||||
|             $databases = $this->server->databases(); |             $databases = $this->server->databases(); | ||||||
|             $services = $this->server->services()->get(); |             $services = $this->server->services()->get(); | ||||||
|             $previews = $this->server->previews(); |             $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 = []; |             $foundApplications = []; | ||||||
|             $foundApplicationPreviews = []; |             $foundApplicationPreviews = []; | ||||||
|             $foundDatabases = []; |             $foundDatabases = []; | ||||||
| @@ -267,6 +245,30 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted | |||||||
|                 } |                 } | ||||||
|                 $this->server->team->notify(new ContainerStopped($containerName, $this->server, $url)); |                 $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) { |         } catch (\Throwable $e) { | ||||||
|             send_internal_notification("ContainerStatusJob failed on ({$this->server->id}) with: " . $e->getMessage()); |             send_internal_notification("ContainerStatusJob failed on ({$this->server->id}) with: " . $e->getMessage()); | ||||||
|             ray($e->getMessage()); |             ray($e->getMessage()); | ||||||
|   | |||||||
| @@ -300,6 +300,9 @@ class Application extends BaseModel | |||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |     public function isLogDrainEnabled() { | ||||||
|  |        return data_get($this, 'settings.is_log_drain_enabled', false); | ||||||
|  |     } | ||||||
|     public function isConfigurationChanged($save = 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; |         $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; | ||||||
|   | |||||||
| @@ -296,15 +296,11 @@ class Server extends BaseModel | |||||||
|         // }
 |         // }
 | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|     public function logDrain($type) |  | ||||||
|     { |  | ||||||
|         InstallLogDrain::run($this, $type); |  | ||||||
|     } |  | ||||||
|     public function isFunctional() |     public function isFunctional() | ||||||
|     { |     { | ||||||
|         return $this->settings->is_reachable && $this->settings->is_usable; |         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; |         return $this->settings->is_logdrain_newrelic_enabled || $this->settings->is_logdrain_highlight_enabled || $this->settings->is_logdrain_axiom_enabled; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -797,7 +797,7 @@ class Service extends BaseModel | |||||||
|                         $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true)); |                         $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true)); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 if ($this->server->isDrainLogActivated()) { |                 if ($this->server->isLogDrainEnabled() && $savedService->isLogDrainEnabled()) { | ||||||
|                     data_set($service, 'logging', [ |                     data_set($service, 'logging', [ | ||||||
|                         'driver' => 'fluentd', |                         'driver' => 'fluentd', | ||||||
|                         'options' => [ |                         'options' => [ | ||||||
|   | |||||||
| @@ -18,6 +18,10 @@ class ServiceApplication extends BaseModel | |||||||
|             $service->fileStorages()->delete(); |             $service->fileStorages()->delete(); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |     public function isLogDrainEnabled() | ||||||
|  |     { | ||||||
|  |         return data_get($this, 'is_log_drain_enabled', false); | ||||||
|  |     } | ||||||
|     public function type() |     public function type() | ||||||
|     { |     { | ||||||
|         return 'service'; |         return 'service'; | ||||||
|   | |||||||
| @@ -16,6 +16,10 @@ class ServiceDatabase extends BaseModel | |||||||
|             $service->fileStorages()->delete(); |             $service->fileStorages()->delete(); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |     public function isLogDrainEnabled() | ||||||
|  |     { | ||||||
|  |         return data_get($this, 'is_log_drain_enabled', false); | ||||||
|  |     } | ||||||
|     public function type() |     public function type() | ||||||
|     { |     { | ||||||
|         return 'service'; |         return 'service'; | ||||||
|   | |||||||
| @@ -41,6 +41,10 @@ class StandaloneMariadb extends BaseModel | |||||||
|             $database->environment_variables()->delete(); |             $database->environment_variables()->delete(); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |     public function isLogDrainEnabled() | ||||||
|  |     { | ||||||
|  |         return data_get($this, 'is_log_drain_enabled', false); | ||||||
|  |     } | ||||||
|     public function type(): string |     public function type(): string | ||||||
|     { |     { | ||||||
|         return 'standalone-mariadb'; |         return 'standalone-mariadb'; | ||||||
|   | |||||||
| @@ -44,7 +44,10 @@ class StandaloneMongodb extends BaseModel | |||||||
|             $database->environment_variables()->delete(); |             $database->environment_variables()->delete(); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 |     public function isLogDrainEnabled() | ||||||
|  |     { | ||||||
|  |         return data_get($this, 'is_log_drain_enabled', false); | ||||||
|  |     } | ||||||
|     public function mongoInitdbRootPassword(): Attribute |     public function mongoInitdbRootPassword(): Attribute | ||||||
|     { |     { | ||||||
|         return Attribute::make( |         return Attribute::make( | ||||||
|   | |||||||
| @@ -46,6 +46,11 @@ class StandaloneMysql extends BaseModel | |||||||
|         return 'standalone-mysql'; |         return 'standalone-mysql'; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public function isLogDrainEnabled() | ||||||
|  |     { | ||||||
|  |         return data_get($this, 'is_log_drain_enabled', false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public function portsMappings(): Attribute |     public function portsMappings(): Attribute | ||||||
|     { |     { | ||||||
|         return Attribute::make( |         return Attribute::make( | ||||||
|   | |||||||
| @@ -42,6 +42,11 @@ class StandalonePostgresql extends BaseModel | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public function isLogDrainEnabled() | ||||||
|  |     { | ||||||
|  |         return data_get($this, 'is_log_drain_enabled', false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public function portsMappings(): Attribute |     public function portsMappings(): Attribute | ||||||
|     { |     { | ||||||
|         return Attribute::make( |         return Attribute::make( | ||||||
|   | |||||||
| @@ -37,6 +37,11 @@ class StandaloneRedis extends BaseModel | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public function isLogDrainEnabled() | ||||||
|  |     { | ||||||
|  |         return data_get($this, 'is_log_drain_enabled', false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public function portsMappings(): Attribute |     public function portsMappings(): Attribute | ||||||
|     { |     { | ||||||
|         return Attribute::make( |         return Attribute::make( | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ class ContainerRestarted extends Notification implements ShouldQueue | |||||||
|     public function toMail(): MailMessage |     public function toMail(): MailMessage | ||||||
|     { |     { | ||||||
|         $mail = new 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', [ |         $mail->view('emails.container-restarted', [ | ||||||
|             'containerName' => $this->name, |             'containerName' => $this->name, | ||||||
|             'serverName' => $this->server->name, |             'serverName' => $this->server->name, | ||||||
| @@ -38,12 +38,12 @@ class ContainerRestarted extends Notification implements ShouldQueue | |||||||
| 
 | 
 | ||||||
|     public function toDiscord(): string |     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; |         return $message; | ||||||
|     } |     } | ||||||
|     public function toTelegram(): array |     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 = [ |         $payload = [ | ||||||
|             "message" => $message, |             "message" => $message, | ||||||
|         ]; |         ]; | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ class ContainerStopped extends Notification implements ShouldQueue | |||||||
|     public function toMail(): MailMessage |     public function toMail(): MailMessage | ||||||
|     { |     { | ||||||
|         $mail = new 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', [ |         $mail->view('emails.container-stopped', [ | ||||||
|             'containerName' => $this->name, |             'containerName' => $this->name, | ||||||
|             'serverName' => $this->server->name, |             'serverName' => $this->server->name, | ||||||
| @@ -37,12 +37,12 @@ class ContainerStopped extends Notification implements ShouldQueue | |||||||
| 
 | 
 | ||||||
|     public function toDiscord(): string |     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; |         return $message; | ||||||
|     } |     } | ||||||
|     public function toTelegram(): array |     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 = [ |         $payload = [ | ||||||
|             "message" => $message, |             "message" => $message, | ||||||
|         ]; |         ]; | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ return [ | |||||||
| 
 | 
 | ||||||
|     // The release version of your application
 |     // The release version of your application
 | ||||||
|     // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
 |     // 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
 |     // When left empty or `null` the Laravel environment will be used
 | ||||||
|     'environment' => config('app.env'), |     'environment' => config('app.env'), | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -1,3 +1,3 @@ | |||||||
| <?php | <?php | ||||||
| 
 | 
 | ||||||
| return '4.0.0-beta.143'; | return '4.0.0-beta.144'; | ||||||
|   | |||||||
| @@ -0,0 +1,76 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | use Illuminate\Database\Migrations\Migration; | ||||||
|  | use Illuminate\Database\Schema\Blueprint; | ||||||
|  | use Illuminate\Support\Facades\Schema; | ||||||
|  | 
 | ||||||
|  | return new class extends Migration | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Run the migrations. | ||||||
|  |      */ | ||||||
|  |     public function up(): void | ||||||
|  |     { | ||||||
|  |         Schema::table('application_settings', function (Blueprint $table) { | ||||||
|  |             $table->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); | ||||||
|  |         }); | ||||||
|  |         Schema::table('servers', function (Blueprint $table) { | ||||||
|  |             $table->boolean('log_drain_notification_sent')->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'); | ||||||
|  |         }); | ||||||
|  |         Schema::table('servers', function (Blueprint $table) { | ||||||
|  |             $table->dropColumn('log_drain_notification_sent'); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | }; | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| <x-emails.layout> | <x-emails.layout> | ||||||
| 
 | 
 | ||||||
| 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') | @if ($containerName === 'coolify-proxy') | ||||||
| Coolify Proxy should run on your server as you have FQDNs set up in one of your resources. | Coolify Proxy should run on your server as you have FQDNs set up in one of your resources. | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| <x-emails.layout> | <x-emails.layout> | ||||||
| 
 | 
 | ||||||
| Container {{ $containerName }} has been stopped unexpectedly on {{$serverName}}. | A service ({{ $containerName }}) has been stopped unexpectedly on {{$serverName}}. | ||||||
| 
 | 
 | ||||||
| @if ($url) | @if ($url) | ||||||
| Please check what is going on [here]({{ $url }}). | Please check what is going on [here]({{ $url }}). | ||||||
|   | |||||||
| @@ -114,6 +114,8 @@ | |||||||
|         </div> |         </div> | ||||||
|         <h3>Advanced</h3> |         <h3>Advanced</h3> | ||||||
|         <div class="flex flex-col"> |         <div class="flex flex-col"> | ||||||
|  |             <x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." instantSave | ||||||
|  |                 id="is_log_drain_enabled" label="Drain Logs" /> | ||||||
|             <x-forms.checkbox |             <x-forms.checkbox | ||||||
|                 helper="Your application will be available only on https if your domain starts with https://..." |                 helper="Your application will be available only on https if your domain starts with https://..." | ||||||
|                 instantSave id="is_force_https_enabled" label="Force Https" /> |                 instantSave id="is_force_https_enabled" label="Force Https" /> | ||||||
|   | |||||||
| @@ -59,5 +59,10 @@ | |||||||
|             @endif |             @endif | ||||||
|         </div> |         </div> | ||||||
|         <x-forms.textarea label="Custom MariaDB Configuration" rows="10" id="database.mariadb_conf" /> |         <x-forms.textarea label="Custom MariaDB Configuration" rows="10" id="database.mariadb_conf" /> | ||||||
|  |         <h3 class="pt-4">Advanced</h3> | ||||||
|  |         <div class="flex flex-col"> | ||||||
|  |             <x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." | ||||||
|  |                 instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" /> | ||||||
|  |         </div> | ||||||
|     </form> |     </form> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -16,8 +16,8 @@ | |||||||
|             <div class="flex gap-2"> |             <div class="flex gap-2"> | ||||||
|                 <x-forms.input label="Initial Username" id="database.mongo_initdb_root_username" |                 <x-forms.input label="Initial Username" id="database.mongo_initdb_root_username" | ||||||
|                     placeholder="If empty: postgres" readonly helper="You can only change this in the database." /> |                     placeholder="If empty: postgres" readonly helper="You can only change this in the database." /> | ||||||
|                 <x-forms.input label="Initial Password" id="database.mongo_initdb_root_password" type="password" required |                 <x-forms.input label="Initial Password" id="database.mongo_initdb_root_password" type="password" | ||||||
|                     readonly helper="You can only change this in the database." /> |                     required readonly helper="You can only change this in the database." /> | ||||||
|                 <x-forms.input label="Initial Database" id="database.mongo_initdb_database" |                 <x-forms.input label="Initial Database" id="database.mongo_initdb_database" | ||||||
|                     placeholder="If empty, it will be the same as Username." readonly |                     placeholder="If empty, it will be the same as Username." readonly | ||||||
|                     helper="You can only change this in the database." /> |                     helper="You can only change this in the database." /> | ||||||
| @@ -53,5 +53,10 @@ | |||||||
|             @endif |             @endif | ||||||
|         </div> |         </div> | ||||||
|         <x-forms.textarea label="Custom MongoDB Configuration" rows="10" id="database.mongo_conf" /> |         <x-forms.textarea label="Custom MongoDB Configuration" rows="10" id="database.mongo_conf" /> | ||||||
|  |         <h3 class="pt-4">Advanced</h3> | ||||||
|  |         <div class="flex flex-col"> | ||||||
|  |             <x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." | ||||||
|  |                 instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" /> | ||||||
|  |         </div> | ||||||
|     </form> |     </form> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -59,5 +59,10 @@ | |||||||
|             @endif |             @endif | ||||||
|         </div> |         </div> | ||||||
|         <x-forms.textarea label="Custom Mysql Configuration" rows="10" id="database.mysql_conf" /> |         <x-forms.textarea label="Custom Mysql Configuration" rows="10" id="database.mysql_conf" /> | ||||||
|  |         <h3 class="pt-4">Advanced</h3> | ||||||
|  |         <div class="flex flex-col"> | ||||||
|  |             <x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." | ||||||
|  |                 instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" /> | ||||||
|  |         </div> | ||||||
|     </form> |     </form> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -74,6 +74,11 @@ | |||||||
|         </div> |         </div> | ||||||
|         <x-forms.textarea label="Custom PostgreSQL Configuration" rows="10" id="database.postgres_conf" /> |         <x-forms.textarea label="Custom PostgreSQL Configuration" rows="10" id="database.postgres_conf" /> | ||||||
|     </form> |     </form> | ||||||
|  |     <h3 class="pt-4">Advanced</h3> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |         <x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." instantSave="instantSaveAdvanced" | ||||||
|  |             id="database.is_log_drain_enabled" label="Drain Logs" /> | ||||||
|  |     </div> | ||||||
|     <div class="pb-16"> |     <div class="pb-16"> | ||||||
|         <div class="flex gap-2 pt-4 pb-2"> |         <div class="flex gap-2 pt-4 pb-2"> | ||||||
|             <h3>Initialization scripts</h3> |             <h3>Initialization scripts</h3> | ||||||
| @@ -87,4 +92,5 @@ | |||||||
|             @endforelse |             @endforelse | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|  | 
 | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -33,5 +33,10 @@ | |||||||
|         <x-forms.textarea |         <x-forms.textarea | ||||||
|             helper="<a target='_blank' class='text-white underline' href='https://raw.githubusercontent.com/redis/redis/7.2/redis.conf'>Redis Default Configuration</a>" |             helper="<a target='_blank' class='text-white underline' href='https://raw.githubusercontent.com/redis/redis/7.2/redis.conf'>Redis Default Configuration</a>" | ||||||
|             label="Custom Redis Configuration" rows="10" id="database.redis_conf" /> |             label="Custom Redis Configuration" rows="10" id="database.redis_conf" /> | ||||||
|  |         <h3 class="pt-4">Advanced</h3> | ||||||
|  |         <div class="flex flex-col"> | ||||||
|  |             <x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." | ||||||
|  |                 instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" /> | ||||||
|  |         </div> | ||||||
|     </form> |     </form> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -36,6 +36,8 @@ | |||||||
|             <x-forms.checkbox instantSave label="Exclude from service status" |             <x-forms.checkbox instantSave label="Exclude from service status" | ||||||
|                 helper="If you do not need to monitor this resource, enable. Useful if this service is optional." |                 helper="If you do not need to monitor this resource, enable. Useful if this service is optional." | ||||||
|                 id="application.exclude_from_status"></x-forms.checkbox> |                 id="application.exclude_from_status"></x-forms.checkbox> | ||||||
|  |             <x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." | ||||||
|  |                 instantSave="instantSaveAdvanced" id="application.is_log_drain_enabled" label="Drain Logs" /> | ||||||
|         </div> |         </div> | ||||||
|     </form> |     </form> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -32,6 +32,8 @@ | |||||||
|             <x-forms.checkbox instantSave label="Exclude from service status" |             <x-forms.checkbox instantSave label="Exclude from service status" | ||||||
|                 helper="If you do not need to monitor this resource, enable. Useful if this service is optional." |                 helper="If you do not need to monitor this resource, enable. Useful if this service is optional." | ||||||
|                 id="database.exclude_from_status"></x-forms.checkbox> |                 id="database.exclude_from_status"></x-forms.checkbox> | ||||||
|  |             <x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." | ||||||
|  |                 instantSave="instantSaveAdvanced" id="database.is_log_drain_enabled" label="Drain Logs" /> | ||||||
|         </div> |         </div> | ||||||
|     </form> |     </form> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| <div> | <div> | ||||||
|     <x-server.navbar :server="$server" :parameters="$parameters" /> |     <x-server.navbar :server="$server" :parameters="$parameters" /> | ||||||
|     <h2>Log Drains</h2> |     <h2>Log Drains</h2> | ||||||
|     <div class="pb-4">Sends resource logs to external services.</div> |     <div class="pb-4">Sends service logs to 3rd party tools.</div> | ||||||
|     <div class="flex flex-col gap-4 pt-4"> |     <div class="flex flex-col gap-4 pt-4"> | ||||||
|         <div class="p-4 border border-coolgray-500"> |         <div class="p-4 border border-coolgray-500"> | ||||||
|             <form wire:submit.prevent='submit("newrelic")' class="flex flex-col"> |             <form wire:submit.prevent='submit("newrelic")' class="flex flex-col"> | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|             "version": "3.12.36" |             "version": "3.12.36" | ||||||
|         }, |         }, | ||||||
|         "v4": { |         "v4": { | ||||||
|             "version": "4.0.0-beta.143" |             "version": "4.0.0-beta.144" | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Andras Bacsai
					Andras Bacsai