trafficmonitor init...1

This commit is contained in:
choi.jh 2025-11-13 09:30:08 +09:00
parent 855367d4ba
commit 194ac35d30

View File

@ -16,6 +16,8 @@ class CollectorService extends CommonService
const OID_IF_IN_OCTETS = '1.3.6.1.2.1.2.2.1.10.'; // ifInOctets (Raw Octets)
const OID_IF_OUT_OCTETS = '1.3.6.1.2.1.2.2.1.16.'; // ifOutOctets (Raw Octets)
const SNMP_VERSION = '2c';
// Counter32의 최대값 + 1 (오버플로우 보정을 위해 사용)
const MAX_COUNTER_32BIT = 4294967296;
public function __construct(CollectorModel $model)
{
parent::__construct($model);
@ -98,37 +100,65 @@ class CollectorService extends CommonService
{
$currentInOctets = $this->getSNMPOctets($trafficEntity, self::OID_IF_IN_OCTETS);
$currentOutOctets = $this->getSNMPOctets($trafficEntity, self::OID_IF_OUT_OCTETS);
if ($currentInOctets === null || $currentOutOctets === null) {
$message = "트래픽 수집 실패: {$trafficEntity->getIP()} - IF{$trafficEntity->getInterface()} (UID: {$trafficEntity->getPK()})";
log_message('warning', $message);
throw new \Exception($message);
throw new Exception($message);
}
// 이전 데이터를 조회하여 Rate 계산에 사용
// $this->model은 TrafficDataModel의 인스턴스라고 가정
$lastEntity = $this->model->getLastEntity($trafficEntity->getPK());
$inKbitsSec = 0;
$outKbitsSec = 0;
$inKbitsSec = 0.0;
$outKbitsSec = 0.0;
// 이전 데이터가 있어야만 Rate 계산 가능
if ($lastEntity !== null) {
$lastTime = Time::parse($lastEntity->getCreatedAt())->getTimestamp();
$deltaTime = Time::now()->getTimestamp() - $lastTime;
if ($deltaTime > 0) {
// Raw Octets 값의 차분 계산
$deltaInOctets = $currentInOctets - $lastEntity->getRawIn();
$deltaOutOctets = $currentOutOctets - $lastEntity->getRawOut();
$lastIn = $lastEntity->getRawIn();
$lastOut = $lastEntity->getRawOut();
// 💡 1. 인바운드 Octets 차분 계산 (오버플로우 처리)
if ($currentInOctets < $lastIn) {
// 카운터 롤오버 발생: Delta = (MAX - Last) + Current
$deltaInOctets = (self::MAX_COUNTER_32BIT - $lastIn) + $currentInOctets;
log_message('info', "Inbound Rollover Detected for UID: {$trafficEntity->getPK()}. Delta: {$deltaInOctets}");
} else {
// 정상적인 차분
$deltaInOctets = $currentInOctets - $lastIn;
}
// 💡 2. 아웃바운드 Octets 차분 계산 (오버플로우 처리)
if ($currentOutOctets < $lastOut) {
// 카운터 롤오버 발생
$deltaOutOctets = (self::MAX_COUNTER_32BIT - $lastOut) + $currentOutOctets;
log_message('info', "Outbound Rollover Detected for UID: {$trafficEntity->getPK()}. Delta: {$deltaOutOctets}");
} else {
// 정상적인 차분
$deltaOutOctets = $currentOutOctets - $lastOut;
}
// Kbit/s 계산: (Delta_Octets * 8 bits) / Delta_Time_Seconds / 1000 (-> Kbit/s)
$inKbitsSec = ($deltaInOctets * 8) / $deltaTime / 1000;
$outKbitsSec = ($deltaOutOctets * 8) / $deltaTime / 1000;
// 실수(float) 연산으로 정확도를 높입니다.
$inKbitsSec = ($deltaInOctets * 8.0) / $deltaTime / 1000.0;
$outKbitsSec = ($deltaOutOctets * 8.0) / $deltaTime / 1000.0;
} else {
log_message('error', "시간 차이 오류 발생: {$trafficEntity->getIP()} - {$deltaTime}초 (UID: {$trafficEntity->getPK()})");
}
}
// DB에 저장할 데이터를 배열로 반환
return [
// 💡 정수 캐스팅 대신 반올림을 사용하여 정밀도 유지 및 데이터 형식 일치
'trafficinfo_uid' => (int)$trafficEntity->getPK(),
'in' => (int)$inKbitsSec,
'out' => (int)$outKbitsSec,
'in' => round($inKbitsSec, 2), // 소수점 2자리까지 반올림
'out' => round($outKbitsSec, 2), // 소수점 2자리까지 반올림
'raw_in' => (int)$currentInOctets,
'raw_out' => (int)$currentOutOctets,
];
}
}