protected override async Task GetValueAsync(SortedDictionary <string, string> ret, RefInt nextPollingInterval, CancellationToken cancel = default) { var result = await EasyExec.ExecAsync(Consts.LinuxCommands.Df, "-a -B1"); string[] lines = result.OutputStr._GetLines(); string[] ignores = "/dev /run /sys /var /snap /tmp /proc"._Split(StringSplitOptions.RemoveEmptyEntries, " "); foreach (string line in lines) { string[] tokens = line._Split(StringSplitOptions.RemoveEmptyEntries, ' ', '\t'); if (tokens.Length >= 6) { string totalStr = tokens[1]; string availableStr = tokens[3]; string path = tokens[5]; if (totalStr != "-" && availableStr != "-") { if (path.StartsWith("/") && ignores.Where(x => path.StartsWith(x, StringComparison.OrdinalIgnoreCase)).Any() == false) { long total = totalStr._ToLong(); long available = availableStr._ToLong(); if (total > 0 && available >= 0) { available = Math.Min(available, total); ret.TryAdd($"available - {path}", NormalizeDoubleValue(((double)available * 100.0 / (double)total).ToString("F3"))); } } } } } }
protected override void InitImpl() { // ConnTrack コマンドが利用可能かどうか確認 if (EasyExec.ExecAsync(Consts.LinuxCommands.ConnTrack, "-C")._TryGetResult() != default) { IsConnTrackOk = true; } }
protected override async Task GetValueAsync(SortedDictionary <string, string> ret, RefInt nextPollingInterval, CancellationToken cancel = default) { // sys/class/thermal/ から温度取得 foreach (var thermalFile in this.ThermalFiles) { string value = (await Lfs.ReadStringFromFileAsync(thermalFile.Value))._GetFirstFilledLineFromLines(); double d = ((double)value._ToInt()) / 1000.0; ret.TryAdd($"{thermalFile.Key}", NormalizeDoubleValue(d.ToString("F3"))); } if (IsSensorsCommandOk) { try { // Sensors コマンドで温度取得 var result = await EasyExec.ExecAsync(Consts.LinuxCommands.Sensors, "-u", cancel : cancel); string[] lines = result.OutputStr._GetLines(true); string groupName = ""; string fieldName = ""; foreach (string line2 in lines) { string line = line2.TrimEnd(); if (line.StartsWith(" ") == false && line._InStr(":") == false) { // グループ名 groupName = line.Trim(); } else if (line.StartsWith(" ") == false && line.EndsWith(":")) { // 値名 fieldName = line.Substring(0, line.Length - 1); } else if (line.StartsWith(" ") && line._GetKeyAndValue(out string key, out string value, ":")) { // 値サブ名 : 値 key = key.Trim(); value = value.Trim(); if (key.EndsWith("_input", StringComparison.OrdinalIgnoreCase)) { ret.TryAdd($"{groupName}/{fieldName}", NormalizeDoubleValue(value)); } } } } catch (Exception ex) { ex._Debug(); } } }
protected override async Task GetValueAsync(SortedDictionary <string, string> ret, RefInt nextPollingInterval, CancellationToken cancel = default) { var result = await EasyExec.ExecAsync(Consts.LinuxCommands.Free, "-b -w"); string[] lines = result.OutputStr._GetLines(); List <string> headers = new List <string>(); KeyValueList <string, string> dataList = new KeyValueList <string, string>(); foreach (string line in lines) { string[] tokens = line._Split(StringSplitOptions.RemoveEmptyEntries, ' ', '\t'); if (tokens.Length >= 2) { if (headers.Count == 0) { if (tokens[0]._IsSamei("total")) { // ヘッダ行 foreach (string token in tokens) { headers.Add(token); } } } else { // データ行 if (tokens[0]._IsSamei("Mem:")) { for (int i = 1; i < tokens.Length; i++) { if (headers.Count >= (i - 1)) { dataList.Add(headers[i - 1], tokens[i]); } } } } } } // total long total = dataList._GetStrFirst("total", "-1")._ToLong(); long available = dataList._GetStrFirst("available", "-1")._ToLong(); if (total >= 0 && available >= 0) { available = Math.Min(available, total); ret.TryAdd($"available", NormalizeDoubleValue(((double)available * 100.0 / (double)total).ToString("F3"))); } }
protected override void InitImpl() { // sensors コマンドが利用可能かどうか確認 if (EasyExec.ExecAsync(Consts.LinuxCommands.Sensors, "-u")._TryGetResult() != default) { IsSensorsCommandOk = true; } // /sys/class/thermal/ から取得可能な値一覧を列挙 FileSystemEntity[]? dirList = null; try { dirList = Lfs.EnumDirectory(Consts.LinuxPaths.SysThermal); } catch { } if (dirList != null) { foreach (var dir in dirList) { string fileName = Lfs.PathParser.Combine(dir.FullPath, "temp"); if (Lfs.IsFileExists(fileName)) { try { Lfs.ReadStringFromFile(fileName); ThermalFiles.Add(dir.Name, fileName); } catch { } } } } }
async Task RunAndParseBirdAsync(string birdExeName, SortedDictionary <string, string> ret, int cmdIpVersion, CancellationToken cancel = default) { var result = await EasyExec.ExecAsync(birdExeName, "show protocol all", cancel : cancel); string body = result.OutputStr; string[] lines = body._GetLines(true); string first = lines.FirstOrDefault()._NonNullTrim(); if (first.StartsWith("BIRD", StringComparison.OrdinalIgnoreCase) == false) { // BIRD 文字列が見つからない return; } if (first.StartsWith("BIRD 1.", StringComparison.OrdinalIgnoreCase)) { // BIRD 1.x } else { // BIRD 2.x or later cmdIpVersion = 0; } string name = ""; string protocol = ""; string table = ""; int ipVer = 0; foreach (string line in lines) { string[] tokens = line._Split(StringSplitOptions.RemoveEmptyEntries, " ", "\t"); if (line.StartsWith(" ") == false) { bool ok = false; // あるプロトコルの開始 if (tokens.Length >= 5) { if (tokens[3]._IsSamei("up") || tokens[3]._IsSamei("start")) { name = tokens[0]; protocol = tokens[1]; table = tokens[2]; if (cmdIpVersion != 0) { ipVer = cmdIpVersion; } ok = true; } } if (ok == false) { name = protocol = table = ""; ipVer = 0; } } else { // プロトコルに関する情報 if (name._IsFilled()) { if (tokens.Length >= 2) { if (cmdIpVersion == 0) { if (tokens[0]._IsSamei("Channel")) { string verstr = tokens[1]; if (verstr._IsSamei("ipv4")) { ipVer = 4; } else if (verstr._IsSamei("ipv6")) { ipVer = 6; } else { ipVer = 0; } } } } if (tokens.Length >= 5) { if (tokens[0]._IsSamei("Routes:")) { int imported = tokens[1]._ToInt(); int exported = tokens[3]._ToInt(); int preferred = 0; if (tokens.Length >= 7) { preferred = tokens[5]._ToInt(); } if (ipVer != 0) { string key = $"{protocol} - {name} - IPv{ipVer}"; ret.TryAdd($"{key} - Import", imported.ToString()); ret.TryAdd($"{key} - Export", exported.ToString()); ret.TryAdd($"{key} - Prefer", preferred.ToString()); } } } } } } }
protected override async Task GetValueAsync(SortedDictionary <string, string> ret, RefInt nextPollingInterval, CancellationToken cancel = default) { if (IsConnTrackOk) { try { // ConnTrack var result = await EasyExec.ExecAsync(Consts.LinuxCommands.ConnTrack, "-C"); string valueStr = result.OutputStr._GetFirstFilledLineFromLines(); ret.TryAdd($"ConnTrack Sessions", valueStr._ToInt().ToString()); } catch (Exception ex) { ex._Debug(); } } if (true) { try { // Threads var result = EasyExec.ExecBashAsync("ps -eo nlwp | tail -n +2 | awk '{ num_threads += $1 } END { print num_threads }'")._GetResult(); string valueStr = result.OutputStr._GetFirstFilledLineFromLines(); ret.TryAdd($"Threads", valueStr._ToInt().ToString()); } catch (Exception ex) { ex._Debug(); } } if (true) { try { // Sockets string[] lines = (await Lfs.ReadStringFromFileAsync(Consts.LinuxPaths.SockStat, flags: FileFlags.NoCheckFileSize))._GetLines(); int numSockets = -1; int numTcp = -1; int numUdp = -1; foreach (string line in lines) { string[] tokens = line._Split(StringSplitOptions.RemoveEmptyEntries, " "); if (tokens.Length >= 3) { if (tokens[0]._IsSamei("sockets:")) { numSockets = tokens[2]._ToInt(); } if (tokens[0]._IsSamei("TCP:")) { numTcp = tokens[2]._ToInt(); } if (tokens[0]._IsSamei("UDP:")) { numUdp = tokens[2]._ToInt(); } } } if (numSockets >= 0 && numTcp >= 0 && numUdp >= 0) { ret.TryAdd($"Sockets", numSockets.ToString()); ret.TryAdd($"TCP", numTcp.ToString()); ret.TryAdd($"UDP", numUdp.ToString()); } } catch (Exception ex) { ex._Debug(); } } }
protected override async Task GetValueAsync(SortedDictionary <string, string> ret, RefInt nextPollingInterval, CancellationToken cancel = default) { SnmpWorkSettings settings = Host.Settings; if (settings.PingTargets._IsSamei("none") || settings.PingTargets._IsSamei("null")) { return; } string hopsStr = "Hops"; if (settings.HopsToTTL) { hopsStr = "TTL"; } string[] pingTargets = settings.PingTargets._Split(StringSplitOptions.RemoveEmptyEntries, ","); numPerform++; foreach (string pingTarget in pingTargets) { cancel.ThrowIfCancellationRequested(); ParseTargetString(pingTarget, out string hostname, out string alias); bool ok = false; try { IPAddress ipAddress = await LocalNet.GetIpAsync(hostname, cancel : cancel); if (FirstPing.IsFirstCall()) { // JIT 対策 try { await LocalNet.SendPingAsync(ipAddress, pingCancel : cancel); } catch { } } int numTry = 3; if (numPerform >= 2) { // SpeedTest が動作中の場合は SpeedTest が完了するまで待機する await TaskUtil.AwaitWithPollAsync(Timeout.Infinite, 10, () => !SpeedTestClient.IsInProgress, cancel); // 試行回数を指定する numTry = Math.Min(Math.Max(settings.PingNumTry, 1), 100); } SendPingReply reply = await LocalNet.SendPingAndGetBestResultAsync(ipAddress, pingCancel : cancel, numTry : numTry); if (reply.Ok) { double rtt = reply.RttDouble; rtt = Math.Min(rtt, 2.0); int ttl = reply.Ttl; bool ttl_ok = false; if (ttl == 0) { // Use ping command to get TTL try { var result = await EasyExec.ExecAsync(ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6?Consts.LinuxCommands.Ping6 : Consts.LinuxCommands.Ping, $"-W 1 -c 1 {ipAddress.ToString()}", cancel : cancel, throwOnErrorExitCode : false); string[] lines = result.OutputStr._GetLines(true); foreach (string line in lines) { OneLineParams param = new OneLineParams(line, ' ', false); string ttlStr = param._GetStrFirst("ttl"); if (ttlStr._IsFilled()) { ttl = ttlStr._ToInt(); ttl_ok = true; break; } } } catch (Exception ex) { ex._Debug(); } } else { ttl_ok = true; } ret.TryAdd($"Time - {alias}", (rtt * 1000.0).ToString("F3")); if (ttl > 128) { ttl -= 128; } else if (ttl > 64) { ttl -= 64; } int hops = 64 - ttl; if (ttl_ok == false) { hops = 0; } hops._SetMax(0); hops._SetMin(64); ret.TryAdd($"{hopsStr} - {alias}", hops.ToString()); ok = true; } } catch (Exception ex) { ex._Debug(); } if (ok == false) { ret.TryAdd($"Time - {alias}", ""); ret.TryAdd($"{hopsStr} - {alias}", "0"); } } }