Logstash İle Loglama (UDP ve TCP) | PHP

Merhaba, bir önceki yazımızda kurduğumuz ELK Stack yapısını PHP’de iki farklı şekilde kullandık.
Birinciside TCP protokolü ile diğerinde UDP.
Bu tür loglama işlerinde UDP protokolü daha çok tercih ediliyormuş, onu öğrendim.
Veri kaybı sizin için müthiş kritik değilse, performans olarak bunun tercih edilmesi tavsiye ediliyor.

Bizim senaryomuzda middleware katmanı olarak bir MY_Controller.php sınıfı vardı.
Tüm istekler buraya geliyor.

// Gelen istek verilerini topla
        try {
            $post_params = $this->input->post();
            if (empty($post_params)) {
                $json_input = file_get_contents('php://input');
                $post_params = json_decode($json_input, true);
            }
            if (isset($post_params['password'])) {
                $post_params['password'] = '[FILTERED]';  // Şifreyi maskele
            }
            $request_data = [
                'method' => $this->input->method(), // GET mi POST mu kontrol eder
                'url' => current_url(), // İstek yapılan URL
                'get_params' => $this->input->get(), // GET parametreleri
                'post_params' => $post_params,  // POST parametreleri (JSON dahil)
                'headers' => $this->input->request_headers() // İstek başlıkları
            ];
            $log_data = ['content' => json_encode($request_data)];
            $log_type_request = $this->config->item('log_type_request');
            $log_level_info = $this->config->item('log_level_info');
            $this->log_to_logstash_udp($log_data, $log_type_request, $log_level_info);
            // Hataları loglamak için
            set_error_handler([$this, 'handle_php_errors']);
            set_exception_handler([$this, 'handle_exceptions']);
        } catch (Exception $e) {
            // Loglama sırasında bir hata olursa, sadece logla ve devam et
            log_message('error', 'Loglama sırasında bir hata oluştu: ' . $e->getMessage());
        }


		public function handle_php_errors($severity, $message, $filepath, $line)
		{
			try {
				$error_data = [
					'severity' => $severity,
					'message' => $message,
					'filepath' => $filepath,
					'line' => $line
				];
				$log_data = ['content' => json_encode($error_data)];
				$log_type_error = $this->config->item('log_type_error');
				$log_level_error = $this->config->item('log_level_error');
				$this->log_to_logstash_udp($log_data, $log_type_error, $log_level_error);
			} catch (Exception $e) {
				log_message('error', 'Loglama sırasında bir hata oluştu: ' . $e->getMessage());
			}
		}

		public function handle_exceptions($exception)
		{
			try {
				$exception_data = [
					'message' => $exception->getMessage(),
					'code' => $exception->getCode(),
					'filepath' => $exception->getFile(),
					'line' => $exception->getLine()
				];
				$log_data = ['content' => json_encode($exception_data)];
				$log_type_exception = $this->config->item('log_type_exception');
				$log_level_exception = $this->config->item('log_level_exception');
				$this->log_to_logstash_udp($log_data, $log_type_exception, $log_level_exception);
			} catch (Exception $e) {
				log_message('error', 'Loglama sırasında bir hata oluştu: ' . $e->getMessage());
			}
		}
	
		private function log_to_logstash_udp($log_data, $type = LOG_TYPE_REQUEST, $level = LOG_LEVEL_INFO)
		{
			try {
				$log_data['level'] = $level;
				$log_data['type'] = $type;
				$log_data['appcode'] = 'InApi';
				$json_data = json_encode($log_data);

				if ($json_data === false) {
					log_message('debug', 'Log verileri JSON\'a çevrilemedi: ' . json_last_error_msg());
					return;
				}
				$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
				if ($sock === false) {
					log_message('debug', 'UDP soketi oluşturulamadı: ' . socket_strerror(socket_last_error()));
					return;
				}
				$logstash_host = $this->config->item('logstash_url');
				$logstash_udpport = $this->config->item('logstash_udp_port');

				socket_sendto($sock, $json_data, strlen($json_data), 0, $logstash_host, $logstash_udpport);
				socket_close($sock);
			} catch (Exception $e) {
				if (ENVIRONMENT === 'development') {
					log_message('debug', 'Loglama sırasında bir hata oluştu: ' . $e->getMessage());
				}
			}
		}


		// Eger TCP ile loglamak icap ederse de sunu kullanabilirsiniz:
		private function log_to_logstash($log_data, $type = LOG_TYPE_REQUEST, $level = LOG_LEVEL_INFO)
		{
			$log_data['level'] = $level;
			$log_data['type'] = $type;
			$log_data['appcode'] = 'InApi';
			$json_data = json_encode($log_data);
			if ($json_data === false) {
				log_message('error', 'Log verileri JSON\'a çevrilemedi: ' . json_last_error_msg());
				return;
			}
			$ch = curl_init($this->config->item('logstash_url'));
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
			curl_setopt($ch, CURLOPT_POST, true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
			curl_setopt($ch, CURLOPT_TIMEOUT, 10);  // Timeout süresi 10 saniye
			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Yönlendirmeleri takip et
			$response = curl_exec($ch);
			if (curl_errno($ch)) {
				log_message('error', 'Curl error: ' . curl_error($ch));
			} else {
				$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
				if ($http_code !== 200) {
					log_message('error', 'Logstash yanıtı beklenen HTTP 200 olmadı. HTTP Kod: ' . $http_code . ' Yanıt: ' . $response);
				}
			}
			curl_close($ch);
		}

Selamlar.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top