| [640ed89] | 1 | #!/usr/bin/env python3
|
|---|
| 2 | """
|
|---|
| 3 | POPRAVEN CLIENT - So bolsho sobiranje na podatoci
|
|---|
| 4 | """
|
|---|
| 5 |
|
|---|
| 6 | import socket
|
|---|
| 7 | import os
|
|---|
| 8 | import platform
|
|---|
| 9 | import json
|
|---|
| 10 | import requests
|
|---|
| 11 | from datetime import datetime
|
|---|
| 12 | import psutil
|
|---|
| 13 | import time
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 | class FixedClient:
|
|---|
| 17 | def __init__(self, server_ip="192.168.1.13", port=5555):
|
|---|
| 18 | self.server_ip = server_ip
|
|---|
| 19 | self.port = port
|
|---|
| 20 | self.computer_name = socket.gethostname()
|
|---|
| 21 | self.user = os.getlogin()
|
|---|
| 22 |
|
|---|
| 23 | def get_detailed_info(self):
|
|---|
| 24 | """Sobiraј podrobni podatoci"""
|
|---|
| 25 | # Osnovni
|
|---|
| 26 | info = {
|
|---|
| 27 | "computer_name": self.computer_name,
|
|---|
| 28 | "user": self.user,
|
|---|
| 29 | "ip_address": socket.gethostbyname(self.computer_name),
|
|---|
| 30 | "os": f"{platform.system()} {platform.release()} {platform.version()}",
|
|---|
| 31 | "architecture": platform.architecture()[0],
|
|---|
| 32 | "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|---|
| 33 | }
|
|---|
| 34 |
|
|---|
| 35 | # Performansi
|
|---|
| 36 | info.update(self.get_performance_metrics())
|
|---|
| 37 |
|
|---|
| 38 | # Hardver informacii
|
|---|
| 39 | info.update(self.get_hardware_info())
|
|---|
| 40 |
|
|---|
| 41 | return info
|
|---|
| 42 |
|
|---|
| 43 | def get_performance_metrics(self):
|
|---|
| 44 | """Metriki za performansi"""
|
|---|
| 45 | try:
|
|---|
| 46 | # CPU
|
|---|
| 47 | cpu_percent = psutil.cpu_percent(interval=1)
|
|---|
| 48 | cpu_per_core = psutil.cpu_percent(interval=1, percpu=True)
|
|---|
| 49 |
|
|---|
| 50 | # RAM
|
|---|
| 51 | ram = psutil.virtual_memory()
|
|---|
| 52 |
|
|---|
| 53 | # Disk
|
|---|
| 54 | disk = psutil.disk_usage("C:/")
|
|---|
| 55 |
|
|---|
| 56 | # Mrezha
|
|---|
| 57 | net_io = psutil.net_io_counters()
|
|---|
| 58 |
|
|---|
| 59 | return {
|
|---|
| 60 | "cpu_usage": cpu_percent,
|
|---|
| 61 | "cpu_cores": len(cpu_per_core),
|
|---|
| 62 | "cpu_per_core": cpu_per_core,
|
|---|
| 63 | "ram_usage": ram.percent,
|
|---|
| 64 | "ram_total_gb": round(ram.total / (1024 ** 3), 2),
|
|---|
| 65 | "ram_used_gb": round(ram.used / (1024 ** 3), 2),
|
|---|
| 66 | "disk_usage": disk.percent,
|
|---|
| 67 | "disk_total_gb": round(disk.total / (1024 ** 3), 2),
|
|---|
| 68 | "disk_used_gb": round(disk.used / (1024 ** 3), 2),
|
|---|
| 69 | "network_sent_mb": round(net_io.bytes_sent / (1024 ** 2), 2),
|
|---|
| 70 | "network_recv_mb": round(net_io.bytes_recv / (1024 ** 2), 2),
|
|---|
| 71 | "boot_time": datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
|
|---|
| 72 | }
|
|---|
| 73 | except Exception as e:
|
|---|
| 74 | print(f"Performance metrics error: {e}")
|
|---|
| 75 | return {}
|
|---|
| 76 |
|
|---|
| 77 | def get_hardware_info(self):
|
|---|
| 78 | """Hardver informacii"""
|
|---|
| 79 | try:
|
|---|
| 80 | # CPU info
|
|---|
| 81 | cpu_info = {
|
|---|
| 82 | "cpu_physical_cores": psutil.cpu_count(logical=False),
|
|---|
| 83 | "cpu_logical_cores": psutil.cpu_count(logical=True),
|
|---|
| 84 | "cpu_freq_current": psutil.cpu_freq().current if hasattr(psutil.cpu_freq(), 'current') else 0,
|
|---|
| 85 | "cpu_freq_max": psutil.cpu_freq().max if hasattr(psutil.cpu_freq(), 'max') else 0,
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | # Disk info
|
|---|
| 89 | partitions = []
|
|---|
| 90 | for partition in psutil.disk_partitions():
|
|---|
| 91 | try:
|
|---|
| 92 | usage = psutil.disk_usage(partition.mountpoint)
|
|---|
| 93 | partitions.append({
|
|---|
| 94 | "device": partition.device,
|
|---|
| 95 | "mountpoint": partition.mountpoint,
|
|---|
| 96 | "fstype": partition.fstype,
|
|---|
| 97 | "total_gb": round(usage.total / (1024 ** 3), 2),
|
|---|
| 98 | "used_gb": round(usage.used / (1024 ** 3), 2),
|
|---|
| 99 | "percent_used": usage.percent
|
|---|
| 100 | })
|
|---|
| 101 | except:
|
|---|
| 102 | continue
|
|---|
| 103 |
|
|---|
| 104 | return {
|
|---|
| 105 | "cpu_info": cpu_info,
|
|---|
| 106 | "disks": partitions,
|
|---|
| 107 | "battery_percent": psutil.sensors_battery().percent if hasattr(psutil.sensors_battery(),
|
|---|
| 108 | 'percent') else None,
|
|---|
| 109 | }
|
|---|
| 110 | except Exception as e:
|
|---|
| 111 | print(f"Hardware info error: {e}")
|
|---|
| 112 | return {}
|
|---|
| 113 |
|
|---|
| 114 | def get_detailed_processes(self):
|
|---|
| 115 | """Detalni informacii za procesite"""
|
|---|
| 116 | processes = []
|
|---|
| 117 | try:
|
|---|
| 118 | for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent',
|
|---|
| 119 | 'memory_percent', 'create_time', 'status']):
|
|---|
| 120 | try:
|
|---|
| 121 | pinfo = proc.info
|
|---|
| 122 |
|
|---|
| 123 | # Dodadi additional info
|
|---|
| 124 | processes.append({
|
|---|
| 125 | "pid": pinfo['pid'],
|
|---|
| 126 | "name": pinfo['name'],
|
|---|
| 127 | "user": pinfo['username'],
|
|---|
| 128 | "cpu_percent": pinfo['cpu_percent'],
|
|---|
| 129 | "memory_mb": round(proc.memory_info().rss / (1024 ** 2), 2),
|
|---|
| 130 | "memory_percent": pinfo['memory_percent'],
|
|---|
| 131 | "create_time": datetime.fromtimestamp(pinfo['create_time']).strftime("%Y-%m-%d %H:%M:%S") if
|
|---|
| 132 | pinfo['create_time'] else None,
|
|---|
| 133 | "status": pinfo['status'],
|
|---|
| 134 | "exe": proc.exe() if hasattr(proc, 'exe') else None,
|
|---|
| 135 | "cmdline": proc.cmdline() if hasattr(proc, 'cmdline') else None,
|
|---|
| 136 | })
|
|---|
| 137 | except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|---|
| 138 | continue
|
|---|
| 139 |
|
|---|
| 140 | # Limit na broј na procesi
|
|---|
| 141 | if len(processes) >= 50:
|
|---|
| 142 | break
|
|---|
| 143 |
|
|---|
| 144 | except Exception as e:
|
|---|
| 145 | print(f"Process error: {e}")
|
|---|
| 146 |
|
|---|
| 147 | return processes
|
|---|
| 148 |
|
|---|
| 149 | def get_network_connections(self):
|
|---|
| 150 | """Aktivni mrezhi konekcii"""
|
|---|
| 151 | connections = []
|
|---|
| 152 | try:
|
|---|
| 153 | for conn in psutil.net_connections(kind='inet'):
|
|---|
| 154 | if conn.status == 'ESTABLISHED':
|
|---|
| 155 | connections.append({
|
|---|
| 156 | "pid": conn.pid,
|
|---|
| 157 | "local_address": f"{conn.laddr.ip}:{conn.laddr.port}" if conn.laddr else None,
|
|---|
| 158 | "remote_address": f"{conn.raddr.ip}:{conn.raddr.port}" if conn.raddr else None,
|
|---|
| 159 | "status": conn.status,
|
|---|
| 160 | "family": str(conn.family)
|
|---|
| 161 | })
|
|---|
| 162 |
|
|---|
| 163 | if len(connections) >= 20:
|
|---|
| 164 | break
|
|---|
| 165 |
|
|---|
| 166 | except:
|
|---|
| 167 | pass
|
|---|
| 168 |
|
|---|
| 169 | return connections
|
|---|
| 170 |
|
|---|
| 171 | def collect_and_send(self):
|
|---|
| 172 | """Sobiraј i isprati site podatoci"""
|
|---|
| 173 | print(f"\n[{datetime.now().strftime('%H:%M:%S')}] 🔍 Sobiranje podatoci...")
|
|---|
| 174 |
|
|---|
| 175 | # Sobiraј site podatoci
|
|---|
| 176 | data = {
|
|---|
| 177 | "info": self.get_detailed_info(),
|
|---|
| 178 | "processes": self.get_detailed_processes(),
|
|---|
| 179 | "network_connections": self.get_network_connections(),
|
|---|
| 180 | "collection_time": datetime.now().isoformat()
|
|---|
| 181 | }
|
|---|
| 182 |
|
|---|
| 183 | # Prikazhi osnovni informacii
|
|---|
| 184 | info = data["info"]
|
|---|
| 185 | print(f" 💻 Kompjuter: {info['computer_name']}")
|
|---|
| 186 | print(f" 👤 Korisnik: {info['user']}")
|
|---|
| 187 | print(
|
|---|
| 188 | f" 📊 CPU: {info.get('cpu_usage', 0)}% | RAM: {info.get('ram_usage', 0)}% | Disk: {info.get('disk_usage', 0)}%")
|
|---|
| 189 | print(f" 🔄 Procesi: {len(data['processes'])} | Mrezhi konekcii: {len(data.get('network_connections', []))}")
|
|---|
| 190 |
|
|---|
| 191 | # Ispraти gi podatocite
|
|---|
| 192 | try:
|
|---|
| 193 | response = requests.post(
|
|---|
| 194 | f"http://{self.server_ip}:{self.port}/receive",
|
|---|
| 195 | json=data,
|
|---|
| 196 | timeout=15
|
|---|
| 197 | )
|
|---|
| 198 |
|
|---|
| 199 | if response.status_code == 200:
|
|---|
| 200 | result = response.json()
|
|---|
| 201 | print(f" ✅ Podatocite se uspeshno isprateni!")
|
|---|
| 202 | print(f" 📝 Server odgovor: {result.get('message', '')}")
|
|---|
| 203 | return True
|
|---|
| 204 | else:
|
|---|
| 205 | print(f" ❌ Greshka: {response.status_code}")
|
|---|
| 206 | return False
|
|---|
| 207 |
|
|---|
| 208 | except Exception as e:
|
|---|
| 209 | print(f" ❌ Problem so serverot: {e}")
|
|---|
| 210 | return False
|
|---|
| 211 |
|
|---|
| 212 |
|
|---|
| 213 | def main():
|
|---|
| 214 | """Glavna programa"""
|
|---|
| 215 | print("=" * 70)
|
|---|
| 216 | print("🖥️ FIXED LAN LOG COLLECTOR")
|
|---|
| 217 | print("=" * 70)
|
|---|
| 218 | print(f"Computer: {socket.gethostname()}")
|
|---|
| 219 | print(f"User: {os.getlogin()}")
|
|---|
| 220 | print(f"IP: {socket.gethostbyname(socket.gethostname())}")
|
|---|
| 221 | print("=" * 70)
|
|---|
| 222 | print("Data will be collected and sent every 30 seconds.")
|
|---|
| 223 | print("Press Ctrl+C to stop.")
|
|---|
| 224 | print("=" * 70)
|
|---|
| 225 |
|
|---|
| 226 | # Proveri dali serverot e dostapen
|
|---|
| 227 | server_ip = input("Enter server IP (default 192.168.1.13): ").strip() or "192.168.1.13"
|
|---|
| 228 |
|
|---|
| 229 | client = FixedClient(server_ip)
|
|---|
| 230 |
|
|---|
| 231 | # Test connection
|
|---|
| 232 | print(f"\n🔌 Testiranje na vrska so serverot {server_ip}...")
|
|---|
| 233 | try:
|
|---|
| 234 | response = requests.get(f"http://{server_ip}:5555/ping", timeout=5)
|
|---|
| 235 | if response.status_code == 200:
|
|---|
| 236 | print(" ✅ Serverot e dostapen!")
|
|---|
| 237 | else:
|
|---|
| 238 | print(f" ⚠️ Serverot odgovora so: {response.status_code}")
|
|---|
| 239 | confirm = input(" Sakaš li da prodolzhish? (y/n): ").lower()
|
|---|
| 240 | if confirm != 'y':
|
|---|
| 241 | return
|
|---|
| 242 | except:
|
|---|
| 243 | print(f" ❌ Ne mozam da se povrzam so serverot {server_ip}")
|
|---|
| 244 | confirm = input(" Sakaš li da prodolzhish? (y/n): ").lower()
|
|---|
| 245 | if confirm != 'y':
|
|---|
| 246 | return
|
|---|
| 247 |
|
|---|
| 248 | try:
|
|---|
| 249 | count = 1
|
|---|
| 250 | while True:
|
|---|
| 251 | print(f"\n📤 Transmission #{count}")
|
|---|
| 252 |
|
|---|
| 253 | success = client.collect_and_send()
|
|---|
| 254 |
|
|---|
| 255 | count += 1
|
|---|
| 256 | print(f"\n⏳ Chekam 30 sekundi do slednata transmisija...")
|
|---|
| 257 |
|
|---|
| 258 | # Countdown
|
|---|
| 259 | for i in range(30, 0, -1):
|
|---|
| 260 | if i % 5 == 0:
|
|---|
| 261 | print(f"\r {i} seconds remaining...", end="")
|
|---|
| 262 | time.sleep(1)
|
|---|
| 263 | print("\r" + " " * 30 + "\r", end="") # Clear line
|
|---|
| 264 |
|
|---|
| 265 | except KeyboardInterrupt:
|
|---|
| 266 | print("\n\n🛑 Programata e zaјchana.")
|
|---|
| 267 | print(f"📊 Dashboard: http://{server_ip}:5555/")
|
|---|
| 268 |
|
|---|
| 269 |
|
|---|
| 270 | if __name__ == "__main__":
|
|---|
| 271 | try:
|
|---|
| 272 | import psutil
|
|---|
| 273 | import requests
|
|---|
| 274 | except ImportError:
|
|---|
| 275 | print("Instaliraј gi modulite:")
|
|---|
| 276 | print("pip install psutil requests")
|
|---|
| 277 | input("Pritisni ENTER za izlez...")
|
|---|
| 278 | exit(1)
|
|---|
| 279 |
|
|---|
| 280 | main() |
|---|