Stats fix
This commit is contained in:
114
api.py
114
api.py
@@ -139,73 +139,40 @@ class DockerService:
|
|||||||
"""Get system information optimized for Raspberry Pi"""
|
"""Get system information optimized for Raspberry Pi"""
|
||||||
try:
|
try:
|
||||||
# CPU usage - reduced interval for Pi
|
# CPU usage - reduced interval for Pi
|
||||||
cpu_percent = psutil.cpu_percent(interval=0.5)
|
try:
|
||||||
|
cpu_percent = psutil.cpu_percent(interval=0.1) # Even shorter for debugging
|
||||||
|
logging.info(f"CPU percent: {cpu_percent}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"CPU error: {e}")
|
||||||
|
cpu_percent = 0
|
||||||
|
|
||||||
# Memory usage
|
# Memory usage
|
||||||
memory = psutil.virtual_memory()
|
try:
|
||||||
|
memory = psutil.virtual_memory()
|
||||||
|
logging.info(f"Memory: total={memory.total}, used={memory.used}, percent={memory.percent}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Memory error: {e}")
|
||||||
|
memory = type('Memory', (), {
|
||||||
|
'total': 0,
|
||||||
|
'available': 0,
|
||||||
|
'used': 0,
|
||||||
|
'percent': 0
|
||||||
|
})()
|
||||||
|
|
||||||
# Disk usage - optimized for Pi filesystem
|
# Disk usage - optimized for Pi filesystem
|
||||||
disk_info = None
|
disk_info = None
|
||||||
|
|
||||||
# Try common Pi filesystem locations
|
# Always use root for debugging
|
||||||
disk_paths = ['/']
|
|
||||||
|
|
||||||
# Check for common Pi mount points
|
|
||||||
pi_mounts = ['/boot', '/home', '/opt', '/var']
|
|
||||||
for mount in pi_mounts:
|
|
||||||
if os.path.exists(mount):
|
|
||||||
disk_paths.append(mount)
|
|
||||||
|
|
||||||
# Try to get SD card usage (rootfs)
|
|
||||||
for path in disk_paths:
|
|
||||||
try:
|
|
||||||
disk_info = psutil.disk_usage(path)
|
|
||||||
break
|
|
||||||
except (OSError, IOError, PermissionError):
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Fallback to root
|
|
||||||
if disk_info is None:
|
|
||||||
try:
|
|
||||||
disk_info = psutil.disk_usage('/')
|
|
||||||
except (OSError, IOError) as e:
|
|
||||||
logging.warning(f"Cannot get disk usage on Pi: {e}")
|
|
||||||
disk_info = type('DiskInfo', (), {
|
|
||||||
'total': 0,
|
|
||||||
'used': 0,
|
|
||||||
'free': 0
|
|
||||||
})()
|
|
||||||
|
|
||||||
# ARM-specific optimizations
|
|
||||||
try:
|
try:
|
||||||
# Check if we're on ARM (Pi)
|
disk_info = psutil.disk_usage('/')
|
||||||
with open('/proc/cpuinfo', 'r') as f:
|
logging.info(f"Disk: total={disk_info.total}, used={disk_info.used}, free={disk_info.free}")
|
||||||
cpu_info = f.read()
|
except Exception as e:
|
||||||
is_arm = 'ARM' in cpu_info or 'arm' in cpu_info
|
logging.error(f"Disk error: {e}")
|
||||||
except:
|
disk_info = type('DiskInfo', (), {
|
||||||
is_arm = False
|
'total': 0,
|
||||||
|
'used': 0,
|
||||||
# Get temperature for Pi
|
'free': 0
|
||||||
cpu_temp = None
|
})()
|
||||||
try:
|
|
||||||
# Try Pi-specific temperature reading
|
|
||||||
temp_paths = [
|
|
||||||
'/sys/class/thermal/thermal_zone0/temp',
|
|
||||||
'/sys/class/hwmon/hwmon0/temp1_input',
|
|
||||||
'/sys/class/thermal/thermal_zone1/temp'
|
|
||||||
]
|
|
||||||
for temp_path in temp_paths:
|
|
||||||
try:
|
|
||||||
with open(temp_path, 'r') as f:
|
|
||||||
temp = int(f.read().strip())
|
|
||||||
if temp > 1000: # Convert millidegrees to degrees
|
|
||||||
temp = temp / 1000.0
|
|
||||||
cpu_temp = round(temp, 1)
|
|
||||||
break
|
|
||||||
except (IOError, OSError):
|
|
||||||
continue
|
|
||||||
except:
|
|
||||||
cpu_temp = None
|
|
||||||
|
|
||||||
# Memory optimization for Pi
|
# Memory optimization for Pi
|
||||||
def format_bytes_pi(bytes_value):
|
def format_bytes_pi(bytes_value):
|
||||||
@@ -219,12 +186,14 @@ class DockerService:
|
|||||||
else:
|
else:
|
||||||
return f"{bytes_value / (1024 * 1024 * 1024):.1f} GB"
|
return f"{bytes_value / (1024 * 1024 * 1024):.1f} GB"
|
||||||
|
|
||||||
return {
|
result = {
|
||||||
|
'cpu_percent': cpu_percent,
|
||||||
|
'memory_percent': memory.percent,
|
||||||
|
'disk_percent': round((disk_info.used / disk_info.total) * 100, 1) if disk_info.total > 0 else 0,
|
||||||
|
'uptime': self._get_system_uptime(),
|
||||||
'cpu': {
|
'cpu': {
|
||||||
'percent': cpu_percent,
|
'percent': cpu_percent,
|
||||||
'cores': psutil.cpu_count(),
|
'cores': psutil.cpu_count() or 1
|
||||||
'is_arm': is_arm,
|
|
||||||
'temperature': cpu_temp
|
|
||||||
},
|
},
|
||||||
'memory': {
|
'memory': {
|
||||||
'total': memory.total,
|
'total': memory.total,
|
||||||
@@ -243,24 +212,21 @@ class DockerService:
|
|||||||
'formatted_total': format_bytes_pi(disk_info.total),
|
'formatted_total': format_bytes_pi(disk_info.total),
|
||||||
'formatted_used': format_bytes_pi(disk_info.used),
|
'formatted_used': format_bytes_pi(disk_info.used),
|
||||||
'formatted_free': format_bytes_pi(disk_info.free)
|
'formatted_free': format_bytes_pi(disk_info.free)
|
||||||
},
|
|
||||||
'uptime': self._get_system_uptime(),
|
|
||||||
'platform': {
|
|
||||||
'system': platform.system(),
|
|
||||||
'release': platform.release(),
|
|
||||||
'machine': platform.machine(),
|
|
||||||
'is_raspberry_pi': self._is_raspberry_pi()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logging.info(f"System info result: {result}")
|
||||||
|
return result
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.warning(f"System info error on Pi: {e}")
|
logging.error(f"System info error: {e}")
|
||||||
return {
|
return {
|
||||||
'error': str(e),
|
'error': str(e),
|
||||||
'cpu': {'percent': 0, 'cores': 1, 'is_arm': True},
|
'cpu': {'percent': 0, 'cores': 1},
|
||||||
'memory': {'total': 0, 'available': 0, 'used': 0, 'percent': 0},
|
'memory': {'total': 0, 'available': 0, 'used': 0, 'percent': 0},
|
||||||
'disk': {'total': 0, 'used': 0, 'free': 0, 'percent': 0},
|
'disk': {'total': 0, 'used': 0, 'free': 0, 'percent': 0},
|
||||||
'uptime': 'Unknown',
|
'uptime': 'Unknown',
|
||||||
'platform': {'system': 'Linux', 'is_raspberry_pi': True}
|
'platform': {'system': 'Linux'}
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_system_uptime(self):
|
def _get_system_uptime(self):
|
||||||
|
|||||||
@@ -24,12 +24,21 @@ class DatabaseManager:
|
|||||||
color TEXT DEFAULT 'gray',
|
color TEXT DEFAULT 'gray',
|
||||||
description TEXT,
|
description TEXT,
|
||||||
url TEXT,
|
url TEXT,
|
||||||
|
status TEXT DEFAULT 'unknown',
|
||||||
custom_data TEXT, -- JSON for additional custom fields
|
custom_data TEXT, -- JSON for additional custom fields
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
)
|
)
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
# Add status column if it doesn't exist (for backward compatibility)
|
||||||
|
try:
|
||||||
|
cursor.execute("ALTER TABLE applications ADD COLUMN status TEXT DEFAULT 'unknown'")
|
||||||
|
print("Added status column to applications table")
|
||||||
|
except sqlite3.OperationalError as e:
|
||||||
|
if "duplicate column name" not in str(e).lower():
|
||||||
|
print(f"Note: {e}")
|
||||||
|
|
||||||
# Create settings table for general configuration
|
# Create settings table for general configuration
|
||||||
cursor.execute('''
|
cursor.execute('''
|
||||||
CREATE TABLE IF NOT EXISTS settings (
|
CREATE TABLE IF NOT EXISTS settings (
|
||||||
|
|||||||
Reference in New Issue
Block a user