判断目标端口是否已使用,作为是否探测星尘代理的依据,加速应用启动。通过进程名判断是否存在,可能会误判,因为获取其它dotnet进程命令行需要管理员权限
This commit is contained in:
parent
79e401e7c5
commit
9830338c27
|
@ -1,27 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using NewLife.Log;
|
||||
using NewLife.Serialization;
|
||||
using Stardust.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace ClientTest
|
||||
{
|
||||
public class AppInfoTests
|
||||
{
|
||||
[Fact]
|
||||
public void Test()
|
||||
{
|
||||
//var p = Process.GetCurrentProcess();
|
||||
namespace ClientTest;
|
||||
|
||||
foreach (var item in Process.GetProcesses())
|
||||
{
|
||||
//Console.WriteLine(item);
|
||||
var pi = new AppInfo(item);
|
||||
if (pi.ProcessorTime > 0) XTrace.WriteLine(pi.ToJson());
|
||||
}
|
||||
public class AppInfoTests
|
||||
{
|
||||
[Fact]
|
||||
public void Test()
|
||||
{
|
||||
foreach (var p in Process.GetProcesses())
|
||||
{
|
||||
//Console.WriteLine(p);
|
||||
var pi = new AppInfo(p);
|
||||
if (pi.ProcessorTime > 0) XTrace.WriteLine(pi.ToJson());
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetProcessName()
|
||||
{
|
||||
var p = Process.GetCurrentProcess();
|
||||
|
||||
var name = AppInfo.GetProcessName(p);
|
||||
Assert.Equal("testhost", name);
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public void GetStarAgentName()
|
||||
//{
|
||||
// var flag = false;
|
||||
// foreach (var p in Process.GetProcesses())
|
||||
// {
|
||||
// if (p.ProcessName == "dotnet")
|
||||
// {
|
||||
// var name = AppInfo.GetProcessName(p);
|
||||
// if (name == "StarAgent")
|
||||
// {
|
||||
// flag = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Assert.True(flag);
|
||||
//}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using NewLife;
|
||||
using NewLife.Configuration;
|
||||
using NewLife.Http;
|
||||
|
@ -16,106 +12,105 @@ using Stardust.Monitors;
|
|||
using Stardust.Registry;
|
||||
using Xunit;
|
||||
|
||||
namespace ClientTest
|
||||
namespace ClientTest;
|
||||
|
||||
public class StarFactoryTests
|
||||
{
|
||||
public class StarFactoryTests
|
||||
[Fact]
|
||||
public void Normal()
|
||||
{
|
||||
[Fact]
|
||||
public void Normal()
|
||||
{
|
||||
var set = StarSetting.Current;
|
||||
var secret = Rand.NextString(8, true);
|
||||
set.Secret = secret;
|
||||
var set = StarSetting.Current;
|
||||
var secret = Rand.NextString(8, true);
|
||||
set.Secret = secret;
|
||||
|
||||
using var star = new StarFactory(null, "StarWeb", null);
|
||||
using var star = new StarFactory(null, "StarWeb", null);
|
||||
|
||||
Assert.NotNull(star.Local);
|
||||
Assert.Equal("http://star.newlifex.com:6600", star.Server);
|
||||
Assert.Equal("StarWeb", star.AppId);
|
||||
Assert.Equal(secret, star.Secret);
|
||||
Assert.NotNull(star.Local);
|
||||
Assert.Equal("http://127.0.0.1:6600", star.Server);
|
||||
Assert.Equal("StarWeb", star.AppId);
|
||||
Assert.Equal(secret, star.Secret);
|
||||
|
||||
var inf = star.Local.Info;
|
||||
Assert.NotNull(inf);
|
||||
var inf = star.Local.Info;
|
||||
Assert.NotNull(inf);
|
||||
|
||||
var tracer = star.Tracer as StarTracer;
|
||||
Assert.NotNull(tracer);
|
||||
Assert.NotEmpty(tracer.ClientId);
|
||||
var tracer = star.Tracer as StarTracer;
|
||||
Assert.NotNull(tracer);
|
||||
Assert.NotEmpty(tracer.ClientId);
|
||||
|
||||
var config = star.Config as HttpConfigProvider;
|
||||
Assert.NotNull(config);
|
||||
Assert.Equal("NewLife开发团队", config["Title"]);
|
||||
var config = star.Config as HttpConfigProvider;
|
||||
Assert.NotNull(config);
|
||||
Assert.Equal("NewLife开发团队", config["Title"]);
|
||||
|
||||
var dust = star.Service as AppClient;
|
||||
Assert.NotNull(dust);
|
||||
var dust = star.Service as AppClient;
|
||||
Assert.NotNull(dust);
|
||||
|
||||
var filter = star.GetValue("_tokenFilter") as TokenHttpFilter;
|
||||
Assert.NotNull(filter);
|
||||
Assert.Equal(star.AppId, filter.UserName);
|
||||
Assert.Equal(star.Secret, filter.Password);
|
||||
Assert.Equal(filter, (tracer.Client as ApiHttpClient).Filter);
|
||||
Assert.Equal(filter, (config.Client as ApiHttpClient).Filter);
|
||||
Assert.Equal(filter, (dust as ApiHttpClient).Filter);
|
||||
}
|
||||
var filter = star.GetValue("_tokenFilter") as TokenHttpFilter;
|
||||
Assert.NotNull(filter);
|
||||
Assert.Equal(star.AppId, filter.UserName);
|
||||
Assert.Equal(star.Secret, filter.Password);
|
||||
Assert.Equal(filter, (tracer.Client as ApiHttpClient).Filter);
|
||||
Assert.Equal(filter, (config.Client as ApiHttpClient).Filter);
|
||||
Assert.Equal(filter, (dust as ApiHttpClient).Filter);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void CreateForService()
|
||||
{
|
||||
using var star = new StarFactory("http://127.0.0.1:6600", "test", "xxx");
|
||||
await star.Service.RegisterAsync("testService", "http://localhost:1234", "tA,tagB,ttC");
|
||||
[Fact]
|
||||
public async void CreateForService()
|
||||
{
|
||||
using var star = new StarFactory("http://127.0.0.1:6600", "test", "xxx");
|
||||
await star.Service.RegisterAsync("testService", "http://localhost:1234", "tA,tagB,ttC");
|
||||
|
||||
var client = star.CreateForService("testService", "tagB") as ApiHttpClient;
|
||||
Assert.NotNull(client);
|
||||
Assert.True(client.RoundRobin);
|
||||
Assert.Equal("http://localhost:1234/", client.Services.Join(",", e => e.Address));
|
||||
}
|
||||
var client = star.CreateForService("testService", "tagB") as ApiHttpClient;
|
||||
Assert.NotNull(client);
|
||||
Assert.True(client.RoundRobin);
|
||||
Assert.Equal("http://localhost:1234/", client.Services.Join(",", e => e.Address));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void CreateForService2()
|
||||
{
|
||||
using var star = new StarFactory("http://127.0.0.1:6600", "test", "xxx");
|
||||
[Fact]
|
||||
public async void CreateForService2()
|
||||
{
|
||||
using var star = new StarFactory("http://127.0.0.1:6600", "test", "xxx");
|
||||
|
||||
var client = star.CreateForService("StarWeb", "tagB") as ApiHttpClient;
|
||||
Assert.NotNull(client);
|
||||
Assert.True(client.RoundRobin);
|
||||
Assert.Equal(0, client.Services.Count);
|
||||
var client = star.CreateForService("StarWeb", "tagB") as ApiHttpClient;
|
||||
Assert.NotNull(client);
|
||||
Assert.True(client.RoundRobin);
|
||||
Assert.Equal(0, client.Services.Count);
|
||||
|
||||
var client2 = star.CreateForService("StarWeb", "Development") as ApiHttpClient;
|
||||
Assert.NotNull(client2);
|
||||
Assert.True(client2.RoundRobin);
|
||||
Assert.Equal("https://localhost:5001/,http://localhost:5000/", client2.Services.Join(",", e => e.Address));
|
||||
}
|
||||
var client2 = star.CreateForService("StarWeb", "Development") as ApiHttpClient;
|
||||
Assert.NotNull(client2);
|
||||
Assert.True(client2.RoundRobin);
|
||||
Assert.Equal("https://localhost:5001/,http://localhost:5000/", client2.Services.Join(",", e => e.Address));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IocTest()
|
||||
{
|
||||
using var star = new StarFactory("http://127.0.0.1:6600", "test", null);
|
||||
[Fact]
|
||||
public void IocTest()
|
||||
{
|
||||
using var star = new StarFactory("http://127.0.0.1:6600", "test", null);
|
||||
|
||||
var provider = ObjectContainer.Provider;
|
||||
var provider = ObjectContainer.Provider;
|
||||
|
||||
var factory = provider.GetRequiredService<StarFactory>();
|
||||
Assert.NotNull(factory);
|
||||
Assert.Equal(star, factory);
|
||||
var factory = provider.GetRequiredService<StarFactory>();
|
||||
Assert.NotNull(factory);
|
||||
Assert.Equal(star, factory);
|
||||
|
||||
var tracer = provider.GetRequiredService<ITracer>();
|
||||
Assert.NotNull(tracer);
|
||||
Assert.Equal(star.Tracer, tracer);
|
||||
var tracer = provider.GetRequiredService<ITracer>();
|
||||
Assert.NotNull(tracer);
|
||||
Assert.Equal(star.Tracer, tracer);
|
||||
|
||||
var config = provider.GetRequiredService<IConfigProvider>();
|
||||
Assert.NotNull(config);
|
||||
Assert.Equal(star.Config, config);
|
||||
var config = provider.GetRequiredService<IConfigProvider>();
|
||||
Assert.NotNull(config);
|
||||
Assert.Equal(star.Config, config);
|
||||
|
||||
var service = provider.GetRequiredService<IRegistry>();
|
||||
Assert.NotNull(service);
|
||||
Assert.Equal(star.Service, service);
|
||||
}
|
||||
var service = provider.GetRequiredService<IRegistry>();
|
||||
Assert.NotNull(service);
|
||||
Assert.Equal(star.Service, service);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void SendNodeCommand()
|
||||
{
|
||||
using var star = new StarFactory("http://127.0.0.1:6600", "test", "xxx");
|
||||
[Fact]
|
||||
public async void SendNodeCommand()
|
||||
{
|
||||
using var star = new StarFactory("http://127.0.0.1:6600", "test", "xxx");
|
||||
|
||||
var rs = await star.SendNodeCommand("7F0F011A", "hello", "stone", 33);
|
||||
Assert.True(rs > 0);
|
||||
}
|
||||
var rs = await star.SendNodeCommand("7F0F011A", "hello", "stone", 33);
|
||||
Assert.True(rs > 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using NewLife;
|
||||
using NewLife.Http;
|
||||
using NewLife.Log;
|
||||
using NewLife.Messaging;
|
||||
using NewLife.Net;
|
||||
using NewLife.Remoting;
|
||||
using Stardust.Models;
|
||||
#if NET45_OR_GREATER || NETCOREAPP || NETSTANDARD
|
||||
|
@ -24,6 +26,9 @@ public class LocalStarClient
|
|||
/// <summary>本地服务端地址</summary>
|
||||
public String Server { get; set; }
|
||||
|
||||
/// <summary>本地星尘代理服务地址</summary>
|
||||
public static Int32 Port { get; set; } = 5500;
|
||||
|
||||
private AgentInfo _local;
|
||||
private ApiClient _client;
|
||||
#endregion
|
||||
|
@ -42,7 +47,7 @@ public class LocalStarClient
|
|||
{
|
||||
if (_client != null) return;
|
||||
|
||||
_client = new ApiClient("udp://127.0.0.1:5500")
|
||||
_client = new ApiClient($"udp://127.0.0.1:{Port}")
|
||||
{
|
||||
Timeout = 3_000,
|
||||
Log = Log,
|
||||
|
@ -59,14 +64,28 @@ public class LocalStarClient
|
|||
/// <returns></returns>
|
||||
public AgentInfo GetInfo()
|
||||
{
|
||||
// 检测进程是否存在,如果进程都不存在,没必要获取信息
|
||||
if (!Process.GetProcessesByName("StarAgent").Any())
|
||||
{
|
||||
var pis = Process.GetProcessesByName("dotnet");
|
||||
if (pis.Length == 0) return null;
|
||||
//!!! 通过进程名判断是否存在,可能会误判,因为获取其它dotnet进程命令行需要管理员权限
|
||||
//// 检测进程是否存在,如果进程都不存在,没必要获取信息
|
||||
//if (!Process.GetProcessesByName("StarAgent").Any())
|
||||
//{
|
||||
// var pis = Process.GetProcessesByName("dotnet");
|
||||
// if (pis.Length == 0) return null;
|
||||
|
||||
if (!pis.Any(p => AppInfo.GetProcessName(p).EqualIgnoreCase("StarAgent"))) return null;
|
||||
// if (!pis.Any(p => AppInfo.GetProcessName(p).EqualIgnoreCase("StarAgent"))) return null;
|
||||
//}
|
||||
|
||||
// 判断目标端口是否已使用,作为是否探测星尘代理的依据,加速应用启动
|
||||
//if (!IPAddress.Any.CheckPort(NetType.Udp, 5500) &&
|
||||
// !IPAddress.Loopback.CheckPort(NetType.Udp, 5500) &&
|
||||
// !IPAddress.IPv6Loopback.CheckPort(NetType.Udp, 5500)) return null;
|
||||
try
|
||||
{
|
||||
// 某些情况下检查端口占用会抛出异常,原因未知
|
||||
var gp = IPGlobalProperties.GetIPGlobalProperties();
|
||||
var eps = gp.GetActiveUdpListeners();
|
||||
if (!eps.Any(ep => ep.Port == Port)) return null;
|
||||
}
|
||||
catch { }
|
||||
|
||||
var task = TaskEx.Run(GetInfoAsync);
|
||||
return task.Wait(500) ? task.Result : null;
|
||||
|
@ -418,9 +437,9 @@ public class LocalStarClient
|
|||
|
||||
var buf = encoder.CreateRequest("Info", null).ToPacket().ToArray();
|
||||
|
||||
// 广播消息
|
||||
// 在局域网中广播消息
|
||||
var udp = new UdpClient();
|
||||
udp.Send(buf, buf.Length, new IPEndPoint(IPAddress.Broadcast, 5500));
|
||||
udp.Send(buf, buf.Length, new IPEndPoint(IPAddress.Broadcast, Port));
|
||||
|
||||
var end = DateTime.Now.AddSeconds(timeout);
|
||||
while (DateTime.Now < end)
|
||||
|
|
|
@ -214,17 +214,12 @@ public class AppInfo
|
|||
{
|
||||
try
|
||||
{
|
||||
var dic = ReadWmic("process", "processId=" + process.Id, "commandline");
|
||||
if (dic.TryGetValue("commandline", out var str))
|
||||
var dic = MachineInfo.ReadWmic("process where processId=" + process.Id, "commandline");
|
||||
if (dic.TryGetValue("commandline", out var str) && !str.IsNullOrEmpty())
|
||||
{
|
||||
var p = str.IndexOf('\"');
|
||||
if (p >= 0)
|
||||
{
|
||||
var p2 = str.IndexOf('\"', p + 1);
|
||||
if (p2 > 0) str = str.Substring(p2 + 1);
|
||||
}
|
||||
var ss = str.Split(' ');
|
||||
if (ss.Length >= 2) name = Path.GetFileNameWithoutExtension(ss[1]);
|
||||
var ss = str.Split(' ').Select(e => e.Trim('\"')).ToArray();
|
||||
str = ss.FirstOrDefault(e => e.EndsWithIgnoreCase(".dll"));
|
||||
if (!str.IsNullOrEmpty()) name = Path.GetFileNameWithoutExtension(str);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
@ -234,67 +229,5 @@ public class AppInfo
|
|||
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>通过WMIC命令读取信息</summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="where"></param>
|
||||
/// <param name="keys"></param>
|
||||
/// <returns></returns>
|
||||
public static IDictionary<String, String> ReadWmic(String type, String where, params String[] keys)
|
||||
{
|
||||
var dic = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var args = $"{type} where {where} get {keys.Join(",")} /format:list";
|
||||
var str = Execute("wmic", args)?.Trim();
|
||||
if (str.IsNullOrEmpty()) return dic;
|
||||
|
||||
var ss = str.Split(Environment.NewLine);
|
||||
foreach (var item in ss)
|
||||
{
|
||||
var ks = item.Split("=");
|
||||
if (ks != null && ks.Length >= 2)
|
||||
{
|
||||
var k = ks[0].Trim();
|
||||
var v = ks[1].Trim();
|
||||
if (dic.TryGetValue(k, out var val))
|
||||
dic[k] = val + "," + v;
|
||||
else
|
||||
dic[k] = v;
|
||||
}
|
||||
}
|
||||
|
||||
// 排序,避免多个磁盘序列号时,顺序变动
|
||||
foreach (var item in dic)
|
||||
{
|
||||
if (item.Value.Contains(','))
|
||||
dic[item.Key] = item.Value.Split(',').OrderBy(e => e).Join();
|
||||
}
|
||||
|
||||
return dic;
|
||||
}
|
||||
|
||||
private static String Execute(String cmd, String arguments = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var psi = new ProcessStartInfo(cmd, arguments)
|
||||
{
|
||||
// UseShellExecute 必须 false,以便于后续重定向输出流
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
RedirectStandardOutput = true,
|
||||
};
|
||||
var process = Process.Start(psi);
|
||||
if (!process.WaitForExit(3_000))
|
||||
{
|
||||
process.Kill();
|
||||
return null;
|
||||
}
|
||||
|
||||
return process.StandardOutput.ReadToEnd();
|
||||
}
|
||||
catch { return null; }
|
||||
}
|
||||
#endregion
|
||||
}
|
|
@ -165,6 +165,7 @@ public class StarFactory : DisposeBase
|
|||
if (AppId != "StarAgent")
|
||||
{
|
||||
// 借助本地StarAgent获取服务器地址
|
||||
var sw = Stopwatch.StartNew();
|
||||
try
|
||||
{
|
||||
//XTrace.WriteLine("正在探测本机星尘代理……");
|
||||
|
@ -173,7 +174,7 @@ public class StarFactory : DisposeBase
|
|||
if (!server.IsNullOrEmpty())
|
||||
{
|
||||
if (Server.IsNullOrEmpty()) Server = server;
|
||||
XTrace.WriteLine("星尘探测:{0}", server);
|
||||
XTrace.WriteLine("星尘探测:{0} Cost={1}ms", server, sw.ElapsedMilliseconds);
|
||||
|
||||
if (set.Server.IsNullOrEmpty())
|
||||
{
|
||||
|
@ -182,11 +183,11 @@ public class StarFactory : DisposeBase
|
|||
}
|
||||
}
|
||||
else
|
||||
XTrace.WriteLine("星尘探测:StarAgent Not Found");
|
||||
XTrace.WriteLine("星尘探测:StarAgent Not Found, Cost={0}ms", sw.ElapsedMilliseconds);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XTrace.Log.Error("星尘探测失败!{0}", ex.Message);
|
||||
XTrace.Log.Error("星尘探测失败!{0} Cost={1}ms", ex.Message, sw.ElapsedMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,45 +1,43 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel;
|
||||
using NewLife.Configuration;
|
||||
|
||||
namespace Stardust
|
||||
namespace Stardust;
|
||||
|
||||
/// <summary>星尘客户端配置</summary>
|
||||
[Config("Star")]
|
||||
public class StarSetting : Config<StarSetting>
|
||||
{
|
||||
/// <summary>星尘客户端配置</summary>
|
||||
[Config("Star")]
|
||||
public class StarSetting : Config<StarSetting>
|
||||
{
|
||||
#region 属性
|
||||
/// <summary>调试开关。默认false</summary>
|
||||
[Description("调试开关。默认false")]
|
||||
public Boolean Debug { get; set; }
|
||||
#region 属性
|
||||
/// <summary>调试开关。默认false</summary>
|
||||
[Description("调试开关。默认false")]
|
||||
public Boolean Debug { get; set; }
|
||||
|
||||
/// <summary>服务端地址。如http://star.newlifex.com:6600,默认为空</summary>
|
||||
[Description("服务端地址。如http://star.newlifex.com:6600,默认为空")]
|
||||
public String Server { get; set; } = "";
|
||||
/// <summary>服务端地址。如http://star.newlifex.com:6600,默认为空</summary>
|
||||
[Description("服务端地址。如http://star.newlifex.com:6600,默认为空")]
|
||||
public String Server { get; set; } = "";
|
||||
|
||||
/// <summary>应用标识</summary>
|
||||
[Description("应用标识")]
|
||||
public String AppKey { get; set; }
|
||||
/// <summary>应用标识</summary>
|
||||
[Description("应用标识")]
|
||||
public String AppKey { get; set; }
|
||||
|
||||
/// <summary>应用密钥</summary>
|
||||
[Description("应用密钥")]
|
||||
public String Secret { get; set; }
|
||||
/// <summary>应用密钥</summary>
|
||||
[Description("应用密钥")]
|
||||
public String Secret { get; set; }
|
||||
|
||||
/// <summary>服务地址。人工设定,用于提交注册中心,默认为空,自动识别外部访问地址</summary>
|
||||
[Description("服务地址。人工设定,用于提交注册中心,默认为空,自动识别外部访问地址")]
|
||||
public String ServiceAddress { get; set; }
|
||||
/// <summary>服务地址。人工设定,用于提交注册中心,默认为空,自动识别外部访问地址</summary>
|
||||
[Description("服务地址。人工设定,用于提交注册中心,默认为空,自动识别外部访问地址")]
|
||||
public String ServiceAddress { get; set; }
|
||||
|
||||
/// <summary>跟踪采样周期。默认60s</summary>
|
||||
[Description("跟踪采样周期。默认60s")]
|
||||
public Int32 TracerPeriod { get; set; } = 60;
|
||||
/// <summary>跟踪采样周期。默认60s</summary>
|
||||
[Description("跟踪采样周期。默认60s")]
|
||||
public Int32 TracerPeriod { get; set; } = 60;
|
||||
|
||||
/// <summary>最大正常采样数。采样周期内,最多只记录指定数量的正常事件,用于绘制依赖关系,默认1</summary>
|
||||
[Description("最大正常采样数。采样周期内,最多只记录指定数量的正常事件,用于绘制依赖关系,默认1")]
|
||||
public Int32 MaxSamples { get; set; } = 1;
|
||||
/// <summary>最大正常采样数。采样周期内,最多只记录指定数量的正常事件,用于绘制依赖关系,默认1</summary>
|
||||
[Description("最大正常采样数。采样周期内,最多只记录指定数量的正常事件,用于绘制依赖关系,默认1")]
|
||||
public Int32 MaxSamples { get; set; } = 1;
|
||||
|
||||
/// <summary>最大异常采样数。采样周期内,最多只记录指定数量的异常事件,默认10</summary>
|
||||
[Description("最大异常采样数。采样周期内,最多只记录指定数量的异常事件,默认10")]
|
||||
public Int32 MaxErrors { get; set; } = 10;
|
||||
#endregion
|
||||
}
|
||||
/// <summary>最大异常采样数。采样周期内,最多只记录指定数量的异常事件,默认10</summary>
|
||||
[Description("最大异常采样数。采样周期内,最多只记录指定数量的异常事件,默认10")]
|
||||
public Int32 MaxErrors { get; set; } = 10;
|
||||
#endregion
|
||||
}
|
Loading…
Reference in New Issue