using Microsoft.Extensions.Logging; using Remotely.Agent.Interfaces; using Remotely.Shared.Dtos; using Remotely.Shared.Services; using System; using System.Linq; using System.Threading.Tasks; namespace Remotely.Agent.Services.Linux; public class DeviceInfoGeneratorLinux : DeviceInfoGeneratorBase, IDeviceInformationService { private readonly IProcessInvoker _processInvoker; private readonly ICpuUtilizationSampler _cpuUtilSampler; public DeviceInfoGeneratorLinux( IProcessInvoker processInvoker, ICpuUtilizationSampler cpuUtilSampler, ILogger logger) : base(logger) { _processInvoker = processInvoker; _cpuUtilSampler = cpuUtilSampler; } public Task CreateDevice(string deviceId, string orgId) { var device = GetDeviceBase(deviceId, orgId); try { var (usedStorage, totalStorage) = GetSystemDriveInfo(); var (usedMemory, totalMemory) = GetMemoryInGB(); device.CurrentUser = GetCurrentUser(); device.Drives = GetAllDrives(); device.UsedStorage = usedStorage; device.TotalStorage = totalStorage; device.UsedMemory = usedMemory; device.TotalMemory = totalMemory; device.CpuUtilization = _cpuUtilSampler.CurrentUtilization; } catch (Exception ex) { _logger.LogError(ex, "Error getting device info."); } return Task.FromResult(device); } private string GetCurrentUser() { var users = _processInvoker.InvokeProcessOutput("users", ""); return users?.Split()?.FirstOrDefault()?.Trim() ?? string.Empty; } public (double usedGB, double totalGB) GetMemoryInGB() { try { var results = _processInvoker.InvokeProcessOutput("cat", "/proc/meminfo"); var resultsArr = results.Split("\n".ToCharArray()); var freeKB = resultsArr .FirstOrDefault(x => x.Trim().StartsWith("MemAvailable")) ?.Trim() ?.Split(" ".ToCharArray(), 2) ?.Last() // 9168236 kB ?.Trim() ?.Split(' ') ?.First() // 9168236 ?? "0"; var totalKB = resultsArr .FirstOrDefault(x => x.Trim().StartsWith("MemTotal")) ?.Trim() ?.Split(" ".ToCharArray(), 2) ?.Last() // 16637468 kB ?.Trim() ?.Split(' ') ?.First() // 16637468 ?? "0"; var freeGB = Math.Round(double.Parse(freeKB) / 1024 / 1024, 2); var totalGB = Math.Round(double.Parse(totalKB) / 1024 / 1024, 2); return (totalGB - freeGB, totalGB); } catch { return (0, 0); } } }