增加采集 FreeMemory,在Linux上表示空闲内存,具有较大意义智能大石头 authored at 2025-12-12 15:03:39
diff --git a/NewLife.Remoting/Clients/ClientBase.cs b/NewLife.Remoting/Clients/ClientBase.cs
index 7fd598d..b3e4ecd 100644
--- a/NewLife.Remoting/Clients/ClientBase.cs
+++ b/NewLife.Remoting/Clients/ClientBase.cs
@@ -839,6 +839,7 @@ public abstract class ClientBase : DisposeBase, IApiClient, ICommandClient, IEve
req.Memory = mi.Memory;
req.AvailableMemory = mi.AvailableMemory;
+ req.FreeMemory = mi.FreeMemory;
req.TotalSize = (UInt64)(driveInfo?.TotalSize ?? 0);
req.AvailableFreeSpace = (UInt64)(driveInfo?.AvailableFreeSpace ?? 0);
req.CpuRate = Math.Round(mi.CpuRate, 3);
diff --git a/NewLife.Remoting/Models/PingRequest.cs b/NewLife.Remoting/Models/PingRequest.cs
index 28c106b..d485928 100644
--- a/NewLife.Remoting/Models/PingRequest.cs
+++ b/NewLife.Remoting/Models/PingRequest.cs
@@ -22,6 +22,9 @@ public interface IPingRequest2 : IPingRequest
/// <summary>可用内存大小</summary>
UInt64 AvailableMemory { get; set; }
+ /// <summary>空闲内存大小。在Linux上空闲内存不一定可用,部分作为缓存</summary>
+ UInt64 FreeMemory { get; set; }
+
/// <summary>磁盘大小。应用所在盘</summary>
UInt64 TotalSize { get; set; }
@@ -60,6 +63,9 @@ public class PingRequest : IPingRequest, IPingRequest2
/// <summary>可用内存大小</summary>
public UInt64 AvailableMemory { get; set; }
+ /// <summary>空闲内存大小。在Linux上空闲内存不一定可用,部分作为缓存</summary>
+ public UInt64 FreeMemory { get; set; }
+
/// <summary>磁盘大小。应用所在盘</summary>
public UInt64 TotalSize { get; set; }
diff --git a/NewLife.Remoting/NewLife.Remoting.csproj b/NewLife.Remoting/NewLife.Remoting.csproj
index 0ad57ea..b2e9b78 100644
--- a/NewLife.Remoting/NewLife.Remoting.csproj
+++ b/NewLife.Remoting/NewLife.Remoting.csproj
@@ -54,7 +54,7 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="NewLife.Core" Version="11.9.2025.1112" />
+ <PackageReference Include="NewLife.Core" Version="11.9.2025.1212-beta0227" />
</ItemGroup>
<ItemGroup>
diff --git a/Samples/Zero.Desktop/Zero.Desktop.csproj b/Samples/Zero.Desktop/Zero.Desktop.csproj
index 11e32df..680a901 100644
--- a/Samples/Zero.Desktop/Zero.Desktop.csproj
+++ b/Samples/Zero.Desktop/Zero.Desktop.csproj
@@ -27,7 +27,7 @@
<ItemGroup>
<PackageReference Include="NewLife.Stardust" Version="3.5.2025.1113" />
- <PackageReference Include="System.Speech" Version="10.0.0" />
+ <PackageReference Include="System.Speech" Version="10.0.1" />
</ItemGroup>
<ItemGroup>
diff --git a/Samples/ZeroServer/Areas/Nodes/Controllers/NodeController.cs b/Samples/ZeroServer/Areas/Nodes/Controllers/NodeController.cs
index 014bf27..ffde17f 100644
--- a/Samples/ZeroServer/Areas/Nodes/Controllers/NodeController.cs
+++ b/Samples/ZeroServer/Areas/Nodes/Controllers/NodeController.cs
@@ -1,13 +1,9 @@
-using Microsoft.AspNetCore.Mvc;
-using Zero.Data.Nodes;
-using NewLife;
+using NewLife;
using NewLife.Cube;
-using NewLife.Cube.Extensions;
using NewLife.Cube.ViewModels;
-using NewLife.Log;
using NewLife.Web;
using XCode.Membership;
-using static Zero.Data.Nodes.Node;
+using Zero.Data.Nodes;
namespace ZeroServer.Areas.Nodes.Controllers;
diff --git a/Samples/ZeroServer/Nodes/Model.xml b/Samples/ZeroServer/Nodes/Model.xml
index cc2629a..be6c4e2 100644
--- a/Samples/ZeroServer/Nodes/Model.xml
+++ b/Samples/ZeroServer/Nodes/Model.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<EntityModel xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="https://newlifex.com https://newlifex.com/Model202407.xsd" Document="https://newlifex.com/xcode/model" xmlns="https://newlifex.com/Model202407.xsd">
+<EntityModel xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="https://newlifex.com https://newlifex.com/Model202509.xsd" Document="https://newlifex.com/xcode/model" xmlns="https://newlifex.com/Model202509.xsd">
<Option>
<!--类名模板。其中{name}替换为Table.Name,如{name}Model/I{name}Dto等-->
<ClassNameTemplate />
@@ -130,7 +130,8 @@
<Column Name="OSKind" DataType="Int32" Description="系统种类。主流操作系统类型,不考虑子版本" Type="Stardust.Models.OSKinds" />
<Column Name="Memory" DataType="Int32" Description="内存。单位M" />
<Column Name="AvailableMemory" DataType="Int32" Description="可用内存。单位M" />
- <Column Name="MemoryUsed" DataType="Int32" Description="已用内存。单位M" />
+ <Column Name="FreeMemory" DataType="Int32" Description="空闲内存。在Linux上空闲不一定可用,部分作为缓存,单位M" />
+ <Column Name="MemoryUsed" DataType="Int32" Description="已用内存。总内存减去空闲内存,单位M" />
<Column Name="AvailableFreeSpace" DataType="Int32" Description="可用磁盘。应用所在盘,单位M" />
<Column Name="SpaceUsed" DataType="Int32" Description="已用磁盘。应用所在盘,单位M" />
<Column Name="DriveInfo" DataType="String" Length="500" Description="驱动器信息。各分区大小,逗号分隔" Category="硬件信息" />
diff --git a/Samples/ZeroServer/Nodes/Zero.htm b/Samples/ZeroServer/Nodes/Zero.htm
index 92e8227..c9be17f 100644
--- a/Samples/ZeroServer/Nodes/Zero.htm
+++ b/Samples/ZeroServer/Nodes/Zero.htm
@@ -914,6 +914,17 @@
</tr>
<tr>
+ <td>FreeMemory</td>
+ <td>空闲内存</td>
+ <td>Int32</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>N</td>
+ <td>在Linux上空闲不一定可用,部分作为缓存,单位M</td>
+ </tr>
+
+ <tr>
<td>MemoryUsed</td>
<td>已用内存</td>
<td>Int32</td>
@@ -921,7 +932,7 @@
<td></td>
<td></td>
<td>N</td>
- <td>单位M</td>
+ <td>总内存减去空闲内存,单位M</td>
</tr>
<tr>
diff --git "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271.cs" "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271.cs"
index fab06ea..7792751 100644
--- "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271.cs"
+++ "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271.cs"
@@ -754,6 +754,44 @@ public partial class Node
}
#endregion
+ #region 高级查询
+ /// <summary>高级查询</summary>
+ /// <param name="code">编码。NodeKey</param>
+ /// <param name="productCode">产品。产品编码,用于区分不同类型节点</param>
+ /// <param name="category">分类</param>
+ /// <param name="ip">本地IP</param>
+ /// <param name="uuid">唯一标识</param>
+ /// <param name="machineGuid">机器标识</param>
+ /// <param name="mACs">网卡</param>
+ /// <param name="oSKind">系统种类。主流操作系统类型,不考虑子版本</param>
+ /// <param name="alarmOnOffline">下线告警。节点下线时,发送告警</param>
+ /// <param name="enable">启用</param>
+ /// <param name="start">更新时间开始</param>
+ /// <param name="end">更新时间结束</param>
+ /// <param name="key">关键字</param>
+ /// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
+ /// <returns>实体列表</returns>
+ public static IList<Node> Search(String code, String productCode, String category, String ip, String uuid, String machineGuid, String mACs, Stardust.Models.OSKinds oSKind, Boolean? alarmOnOffline, Boolean? enable, DateTime start, DateTime end, String key, PageParameter page)
+ {
+ var exp = new WhereExpression();
+
+ if (!code.IsNullOrEmpty()) exp &= _.Code == code;
+ if (!productCode.IsNullOrEmpty()) exp &= _.ProductCode == productCode;
+ if (!category.IsNullOrEmpty()) exp &= _.Category == category;
+ if (!ip.IsNullOrEmpty()) exp &= _.IP == ip;
+ if (!uuid.IsNullOrEmpty()) exp &= _.Uuid == uuid;
+ if (!machineGuid.IsNullOrEmpty()) exp &= _.MachineGuid == machineGuid;
+ if (!mACs.IsNullOrEmpty()) exp &= _.MACs == mACs;
+ if (oSKind >= 0) exp &= _.OSKind == oSKind;
+ if (alarmOnOffline != null) exp &= _.AlarmOnOffline == alarmOnOffline;
+ if (enable != null) exp &= _.Enable == enable;
+ exp &= _.UpdateTime.Between(start, end);
+ if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);
+
+ return FindAll(exp, page);
+ }
+ #endregion
+
#region 字段名
/// <summary>取得节点字段信息的快捷方式</summary>
public partial class _
diff --git "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\216\206\345\217\262.cs" "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\216\206\345\217\262.cs"
index 25dbeb9..7d8e39e 100644
--- "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\216\206\345\217\262.cs"
+++ "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\216\206\345\217\262.cs"
@@ -204,14 +204,39 @@ public partial class NodeHistory
}
#endregion
+ #region 高级查询
+ /// <summary>高级查询</summary>
+ /// <param name="nodeId">节点</param>
+ /// <param name="action">操作</param>
+ /// <param name="success">成功</param>
+ /// <param name="start">编号开始</param>
+ /// <param name="end">编号结束</param>
+ /// <param name="key">关键字</param>
+ /// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
+ /// <returns>实体列表</returns>
+ public static IList<NodeHistory> Search(Int32 nodeId, String action, Boolean? success, DateTime start, DateTime end, String key, PageParameter page)
+ {
+ var exp = new WhereExpression();
+
+ if (nodeId >= 0) exp &= _.NodeId == nodeId;
+ if (!action.IsNullOrEmpty()) exp &= _.Action == action;
+ if (success != null) exp &= _.Success == success;
+ exp &= _.Id.Between(start, end, Meta.Factory.Snow);
+ if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);
+
+ return FindAll(exp, page);
+ }
+ #endregion
+
#region 数据清理
/// <summary>清理指定时间段内的数据</summary>
/// <param name="start">开始时间。未指定时清理小于指定时间的所有数据</param>
/// <param name="end">结束时间</param>
+ /// <param name="maximumRows">最大删除行数。清理历史数据时,避免一次性删除过多导致数据库IO跟不上,0表示所有</param>
/// <returns>清理行数</returns>
- public static Int32 DeleteWith(DateTime start, DateTime end)
+ public static Int32 DeleteWith(DateTime start, DateTime end, Int32 maximumRows = 0)
{
- return Delete(_.Id.Between(start, end, Meta.Factory.Snow));
+ return Delete(_.Id.Between(start, end, Meta.Factory.Snow), maximumRows);
}
#endregion
diff --git "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.Biz.cs" "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.Biz.cs"
index 227daf4..7a8ed86 100644
--- "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.Biz.cs"
+++ "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.Biz.cs"
@@ -248,7 +248,8 @@ public partial class NodeOnline : Entity<NodeOnline>, IOnlineModel2
if (inf.Memory > 0) online.Memory = (Int32)(inf.Memory / 1024 / 1024);
if (inf.AvailableMemory > 0) online.AvailableMemory = (Int32)(inf.AvailableMemory / 1024 / 1024);
- MemoryUsed = online.Memory - online.AvailableMemory;
+ if (inf.FreeMemory > 0) online.FreeMemory = (Int32)(inf.FreeMemory / 1024 / 1024);
+ MemoryUsed = online.Memory - online.FreeMemory > 0 ? online.FreeMemory : online.AvailableMemory;
if (inf.AvailableFreeSpace > 0) online.AvailableFreeSpace = (Int32)(inf.AvailableFreeSpace / 1024 / 1024);
if (inf.TotalSize > 0) online.SpaceUsed = (Int32)(inf.TotalSize / 1024 / 1024) - online.AvailableFreeSpace;
if (inf.CpuRate > 0) online.CpuRate = inf.CpuRate;
diff --git "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.cs" "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.cs"
index 07247eb..8057f4f 100644
--- "a/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.cs"
+++ "b/Samples/ZeroServer/Nodes/\350\212\202\347\202\271\345\234\250\347\272\277.cs"
@@ -146,12 +146,20 @@ public partial class NodeOnline
[BindColumn("AvailableMemory", "可用内存。单位M", "")]
public Int32 AvailableMemory { get => _AvailableMemory; set { if (OnPropertyChanging("AvailableMemory", value)) { _AvailableMemory = value; OnPropertyChanged("AvailableMemory"); } } }
+ private Int32 _FreeMemory;
+ /// <summary>空闲内存。在Linux上空闲不一定可用,部分作为缓存,单位M</summary>
+ [DisplayName("空闲内存")]
+ [Description("空闲内存。在Linux上空闲不一定可用,部分作为缓存,单位M")]
+ [DataObjectField(false, false, false, 0)]
+ [BindColumn("FreeMemory", "空闲内存。在Linux上空闲不一定可用,部分作为缓存,单位M", "")]
+ public Int32 FreeMemory { get => _FreeMemory; set { if (OnPropertyChanging("FreeMemory", value)) { _FreeMemory = value; OnPropertyChanged("FreeMemory"); } } }
+
private Int32 _MemoryUsed;
- /// <summary>已用内存。单位M</summary>
+ /// <summary>已用内存。总内存减去空闲内存,单位M</summary>
[DisplayName("已用内存")]
- [Description("已用内存。单位M")]
+ [Description("已用内存。总内存减去空闲内存,单位M")]
[DataObjectField(false, false, false, 0)]
- [BindColumn("MemoryUsed", "已用内存。单位M", "")]
+ [BindColumn("MemoryUsed", "已用内存。总内存减去空闲内存,单位M", "")]
public Int32 MemoryUsed { get => _MemoryUsed; set { if (OnPropertyChanging("MemoryUsed", value)) { _MemoryUsed = value; OnPropertyChanged("MemoryUsed"); } } }
private Int32 _AvailableFreeSpace;
@@ -401,6 +409,7 @@ public partial class NodeOnline
"OSKind" => _OSKind,
"Memory" => _Memory,
"AvailableMemory" => _AvailableMemory,
+ "FreeMemory" => _FreeMemory,
"MemoryUsed" => _MemoryUsed,
"AvailableFreeSpace" => _AvailableFreeSpace,
"SpaceUsed" => _SpaceUsed,
@@ -450,6 +459,7 @@ public partial class NodeOnline
case "OSKind": _OSKind = (Stardust.Models.OSKinds)value.ToInt(); break;
case "Memory": _Memory = value.ToInt(); break;
case "AvailableMemory": _AvailableMemory = value.ToInt(); break;
+ case "FreeMemory": _FreeMemory = value.ToInt(); break;
case "MemoryUsed": _MemoryUsed = value.ToInt(); break;
case "AvailableFreeSpace": _AvailableFreeSpace = value.ToInt(); break;
case "SpaceUsed": _SpaceUsed = value.ToInt(); break;
@@ -502,6 +512,38 @@ public partial class NodeOnline
}
#endregion
+ #region 高级查询
+ /// <summary>高级查询</summary>
+ /// <param name="sessionId">会话</param>
+ /// <param name="nodeId">节点</param>
+ /// <param name="provinceId">省份</param>
+ /// <param name="cityId">城市</param>
+ /// <param name="token">令牌</param>
+ /// <param name="webSocket">长连接。WebSocket长连接</param>
+ /// <param name="oSKind">系统种类。主流操作系统类型,不考虑子版本</param>
+ /// <param name="start">更新时间开始</param>
+ /// <param name="end">更新时间结束</param>
+ /// <param name="key">关键字</param>
+ /// <param name="page">分页参数信息。可携带统计和数据权限扩展查询等信息</param>
+ /// <returns>实体列表</returns>
+ public static IList<NodeOnline> Search(String sessionId, Int32 nodeId, Int32 provinceId, Int32 cityId, String token, Boolean? webSocket, Stardust.Models.OSKinds oSKind, DateTime start, DateTime end, String key, PageParameter page)
+ {
+ var exp = new WhereExpression();
+
+ if (!sessionId.IsNullOrEmpty()) exp &= _.SessionId == sessionId;
+ if (nodeId >= 0) exp &= _.NodeId == nodeId;
+ if (provinceId >= 0) exp &= _.ProvinceID == provinceId;
+ if (cityId >= 0) exp &= _.CityID == cityId;
+ if (!token.IsNullOrEmpty()) exp &= _.Token == token;
+ if (webSocket != null) exp &= _.WebSocket == webSocket;
+ if (oSKind >= 0) exp &= _.OSKind == oSKind;
+ exp &= _.UpdateTime.Between(start, end);
+ if (!key.IsNullOrEmpty()) exp &= SearchWhereByKeys(key);
+
+ return FindAll(exp, page);
+ }
+ #endregion
+
#region 字段名
/// <summary>取得节点在线字段信息的快捷方式</summary>
public partial class _
@@ -551,7 +593,10 @@ public partial class NodeOnline
/// <summary>可用内存。单位M</summary>
public static readonly Field AvailableMemory = FindByName("AvailableMemory");
- /// <summary>已用内存。单位M</summary>
+ /// <summary>空闲内存。在Linux上空闲不一定可用,部分作为缓存,单位M</summary>
+ public static readonly Field FreeMemory = FindByName("FreeMemory");
+
+ /// <summary>已用内存。总内存减去空闲内存,单位M</summary>
public static readonly Field MemoryUsed = FindByName("MemoryUsed");
/// <summary>可用磁盘。应用所在盘,单位M</summary>
@@ -686,7 +731,10 @@ public partial class NodeOnline
/// <summary>可用内存。单位M</summary>
public const String AvailableMemory = "AvailableMemory";
- /// <summary>已用内存。单位M</summary>
+ /// <summary>空闲内存。在Linux上空闲不一定可用,部分作为缓存,单位M</summary>
+ public const String FreeMemory = "FreeMemory";
+
+ /// <summary>已用内存。总内存减去空闲内存,单位M</summary>
public const String MemoryUsed = "MemoryUsed";
/// <summary>可用磁盘。应用所在盘,单位M</summary>
diff --git a/Test/Test.csproj b/Test/Test.csproj
index 73a421b..1decd1e 100644
--- a/Test/Test.csproj
+++ b/Test/Test.csproj
@@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="NewLife.Core" Version="11.9.2025.1112" />
+ <PackageReference Include="NewLife.Core" Version="11.9.2025.1212-beta0227" />
</ItemGroup>
<ItemGroup>
diff --git a/XUnitTest/XUnitTest.csproj b/XUnitTest/XUnitTest.csproj
index 624de92..f65e206 100644
--- a/XUnitTest/XUnitTest.csproj
+++ b/XUnitTest/XUnitTest.csproj
@@ -9,10 +9,10 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="Moq" Version="4.20.72" />
- <PackageReference Include="NewLife.Core" Version="11.9.2025.1112" />
+ <PackageReference Include="NewLife.Core" Version="11.9.2025.1212-beta0227" />
<PackageReference Include="NewLife.UnitTest" Version="1.0.2025.101" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">