fajiao
2 years ago
5 changed files with 324 additions and 306 deletions
@ -1,312 +1,317 @@ |
|||||
using Cis.Application.Cb; |
using Cis.Application.Cb; |
||||
using Cis.Application.Cm; |
using Cis.Application.Cm; |
||||
using Cis.Application.Tb; |
using Cis.Application.Tb; |
||||
|
using Microsoft.Extensions.Logging; |
||||
using System.Collections.Concurrent; |
using System.Collections.Concurrent; |
||||
|
|
||||
namespace Cis.Application.Core; |
namespace Cis.Application.Core; |
||||
|
|
||||
public class CameraDataCenter |
public class CameraDataCenter |
||||
{ |
{ |
||||
#region Attr
|
#region Attr
|
||||
|
|
||||
private readonly SqlSugarRepository<CbCamera> _cbCameraRep; |
private readonly SqlSugarRepository<CbCamera> _cbCameraRep; |
||||
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep; |
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep; |
||||
private readonly SqlSugarRepository<TbPtzCamera> _tbPtzCameraRep; |
private readonly SqlSugarRepository<TbPtzCamera> _tbPtzCameraRep; |
||||
private readonly PtzServerApi _ptzServerApi; |
private readonly PtzServerApi _ptzServerApi; |
||||
private readonly CameraDataOptions options = App.GetOptions<CameraDataOptions>(); |
private readonly CameraDataOptions options; |
||||
|
|
||||
private Thread _thread { get; set; } |
private Thread _thread { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// (cbCameraId, cbCameraIp)
|
/// (cbCameraId, cbCameraIp)
|
||||
/// </summary>
|
/// </summary>
|
||||
private Dictionary<long, string> _cbCameraId2IpDict { get; set; } = new(); |
private Dictionary<long, string> _cbCameraId2IpDict { get; set; } = new(); |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// (cameraIp, TbPtzCamera)
|
/// (cameraIp, TbPtzCamera)
|
||||
/// </summary>
|
/// </summary>
|
||||
private ConcurrentDictionary<string, TbPtzCamera> _tbPtzCameraDict { get; set; } = new(); |
private ConcurrentDictionary<string, TbPtzCamera> _tbPtzCameraDict { get; set; } = new(); |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// (cameraIp, PtzInfo)
|
/// (cameraIp, PtzInfo)
|
||||
/// </summary>
|
/// </summary>
|
||||
private ConcurrentDictionary<string, PtzInfo> _cameraPtzInfoDict { get; set; } = new(); |
private ConcurrentDictionary<string, PtzInfo> _cameraPtzInfoDict { get; set; } = new(); |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// _markSearcherDict 锁对象,写锁
|
/// _markSearcherDict 锁对象,写锁
|
||||
/// </summary>
|
/// </summary>
|
||||
private static ReaderWriterLockSlim msDictLock { get; } = new(); |
private static ReaderWriterLockSlim msDictLock { get; } = new(); |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// (cbCameraId, MarkSearcherBase)
|
/// (cbCameraId, MarkSearcherBase)
|
||||
/// </summary>
|
/// </summary>
|
||||
private ConcurrentDictionary<long, MarkSearcherBase> _markSearcherDict { get; set; } = new(); |
private ConcurrentDictionary<long, MarkSearcherBase> _markSearcherDict { get; set; } = new(); |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// (cameraId, List(MarkLabelCalcResult))
|
/// (cameraId, List(MarkLabelCalcResult))
|
||||
/// </summary>
|
/// </summary>
|
||||
|
|
||||
private ConcurrentDictionary<long, List<MarkLabelCalcResult>> _markLabelCalcResultListDict { get; set; } = new(); |
private ConcurrentDictionary<long, List<MarkLabelCalcResult>> _markLabelCalcResultListDict { get; set; } = new(); |
||||
|
|
||||
#endregion Attr
|
#endregion Attr
|
||||
|
|
||||
public CameraDataCenter() |
private readonly ILogger<CameraDataCenter> _logger; |
||||
{ |
|
||||
_cbCameraRep = App.GetService<SqlSugarRepository<CbCamera>>(); |
public CameraDataCenter() |
||||
_cmMarkLableRep = App.GetService<SqlSugarRepository<CmMarkLabel>>(); |
{ |
||||
_tbPtzCameraRep = App.GetService<SqlSugarRepository<TbPtzCamera>>(); |
_cbCameraRep = App.GetService<SqlSugarRepository<CbCamera>>(); |
||||
_ptzServerApi = App.GetService<PtzServerApi>(); |
_cmMarkLableRep = App.GetService<SqlSugarRepository<CmMarkLabel>>(); |
||||
Init(); |
_tbPtzCameraRep = App.GetService<SqlSugarRepository<TbPtzCamera>>(); |
||||
} |
_ptzServerApi = App.GetService<PtzServerApi>(); |
||||
|
options = App.GetOptions<CameraDataOptions>(); |
||||
private void Init() |
_logger = App.GetService<ILogger<CameraDataCenter>>(); |
||||
{ |
Init(); |
||||
if (!options.LazyInit) |
} |
||||
{ |
|
||||
List<TbPtzCamera> list = _tbPtzCameraRep.GetList(); |
private void Init() |
||||
// 根据 Ip 去重
|
{ |
||||
foreach (TbPtzCamera item in list) |
if (!options.LazyInit) |
||||
{ |
{ |
||||
if (!_tbPtzCameraDict.ContainsKey(item.Ip)) |
List<TbPtzCamera> list = _tbPtzCameraRep.GetList(); |
||||
_tbPtzCameraDict[item.Ip] = item; |
// 根据 Ip 去重
|
||||
} |
foreach (TbPtzCamera item in list) |
||||
} |
{ |
||||
|
if (!_tbPtzCameraDict.ContainsKey(item.Ip)) |
||||
// 初始化 thread
|
_tbPtzCameraDict[item.Ip] = item; |
||||
_thread = new Thread(WorkLoop) |
} |
||||
{ |
} |
||||
IsBackground = true// 设置后台线程
|
|
||||
}; |
// 初始化 thread
|
||||
_thread.Start(); |
_thread = new Thread(WorkLoop) |
||||
} |
{ |
||||
|
IsBackground = true// 设置后台线程
|
||||
#region Loop
|
}; |
||||
|
_thread.Start(); |
||||
/// <summary>
|
} |
||||
/// 循环运行
|
|
||||
/// </summary>
|
#region Loop
|
||||
private void WorkLoop() |
|
||||
{ |
/// <summary>
|
||||
while (true) |
/// 循环运行
|
||||
{ |
/// </summary>
|
||||
RefreshPtzInfoByApi(); |
private void WorkLoop() |
||||
RefreshMarkSearcher(); |
{ |
||||
Thread.Sleep(options.LoopInterval); |
while (true) |
||||
} |
{ |
||||
} |
RefreshPtzInfoByApi(); |
||||
|
RefreshMarkSearcher(); |
||||
private void RefreshPtzInfoByApi() |
Thread.Sleep(options.LoopInterval); |
||||
{ |
} |
||||
foreach (TbPtzCamera item in _tbPtzCameraDict.Values) |
} |
||||
{ |
|
||||
PtzInfo ptzInfo = _ptzServerApi.GetPtzInfo(item.CameraId); |
private void RefreshPtzInfoByApi() |
||||
_cameraPtzInfoDict[item.Ip] = ptzInfo; |
{ |
||||
} |
foreach (TbPtzCamera item in _tbPtzCameraDict.Values) |
||||
} |
{ |
||||
|
PtzInfo ptzInfo = _ptzServerApi.GetPtzInfo(item.CameraId); |
||||
private void RefreshMarkSearcher() |
_cameraPtzInfoDict[item.Ip] = ptzInfo; |
||||
{ |
} |
||||
foreach (KeyValuePair<long, MarkSearcherBase> pair in _markSearcherDict) |
} |
||||
{ |
|
||||
long cameraId = pair.Key; |
private async void RefreshMarkSearcher() |
||||
MarkSearcherBase markSearcher = pair.Value; |
{ |
||||
bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp); |
foreach (KeyValuePair<long, MarkSearcherBase> pair in _markSearcherDict) |
||||
if (!ret) continue; |
{ |
||||
ret = _cameraPtzInfoDict.TryGetValue(cameraIp, out PtzInfo ptzInfo); |
long cameraId = pair.Key; |
||||
if (!ret) continue; |
MarkSearcherBase markSearcher = pair.Value; |
||||
markSearcher.UpdateCameraCalcInfo(ptzInfo); |
bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp); |
||||
List<MarkLabelCalcResult> resultList = markSearcher.Calc(); |
if (!ret) continue; |
||||
_markLabelCalcResultListDict[cameraId] = resultList; |
ret = _cameraPtzInfoDict.TryGetValue(cameraIp, out PtzInfo ptzInfo); |
||||
} |
if (!ret) continue; |
||||
} |
markSearcher.UpdateCameraCalcInfo(ptzInfo); |
||||
|
List<MarkLabelCalcResult> resultList = await markSearcher.CalcAsync(); |
||||
#endregion Loop
|
_markLabelCalcResultListDict[cameraId] = resultList; |
||||
|
} |
||||
#region external call
|
} |
||||
|
|
||||
/// <summary>
|
#endregion Loop
|
||||
/// 激活 cbCamera 进入运算
|
|
||||
/// </summary>
|
#region external call
|
||||
/// <param name="cameraId"></param>
|
|
||||
/// <returns></returns>
|
/// <summary>
|
||||
public bool ActivateSearcher(long cameraId) |
/// 激活 cbCamera 进入运算
|
||||
{ |
/// </summary>
|
||||
try |
/// <param name="cameraId"></param>
|
||||
{ |
/// <returns></returns>
|
||||
msDictLock.EnterWriteLock(); |
public bool ActivateSearcher(long cameraId) |
||||
if (_markSearcherDict.ContainsKey(cameraId)) |
{ |
||||
return false; |
try |
||||
// 获取 cbCamera
|
{ |
||||
CbCamera cbCamera = _cbCameraRep.GetById(cameraId); |
msDictLock.EnterWriteLock(); |
||||
if (cbCamera == null) return false; |
if (_markSearcherDict.ContainsKey(cameraId)) |
||||
// 获取 tbPtzCamera
|
return false; |
||||
string cameraIp = cbCamera.Ip; |
// 获取 cbCamera
|
||||
bool ret = _tbPtzCameraDict.TryGetValue(cameraIp, out TbPtzCamera tbPtzCamera); |
CbCamera cbCamera = _cbCameraRep.GetById(cameraId); |
||||
if (!ret) |
if (cbCamera == null) return false; |
||||
{ |
// 获取 tbPtzCamera
|
||||
tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp); |
string cameraIp = cbCamera.Ip; |
||||
if (tbPtzCamera == null) return false; |
bool ret = _tbPtzCameraDict.TryGetValue(cameraIp, out TbPtzCamera tbPtzCamera); |
||||
_tbPtzCameraDict[cameraIp] = tbPtzCamera; |
if (!ret) |
||||
} |
{ |
||||
// 存储 cbCamera id 对应 ip 关系
|
tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp); |
||||
_cbCameraId2IpDict[cbCamera.Id] = cameraIp; |
if (tbPtzCamera == null) return false; |
||||
// 创建 cameraCalcInfo
|
_tbPtzCameraDict[cameraIp] = tbPtzCamera; |
||||
CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id)); |
} |
||||
// 创建 markSeacher
|
// 存储 cbCamera id 对应 ip 关系
|
||||
HikMarkSeacher markSeacher = new(cameraCalcInfo); |
_cbCameraId2IpDict[cbCamera.Id] = cameraIp; |
||||
// 获取 cmMarkLabel 列表
|
// 创建 cameraCalcInfo
|
||||
List<CmMarkLabel> cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId); |
CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id)); |
||||
// 将 cmMarkLabel 一一添加到 markSeacher
|
// 创建 markSeacher
|
||||
foreach (CmMarkLabel item in cmMarkLabelList) |
HikMarkSeacher markSeacher = new(cameraCalcInfo); |
||||
{ |
// 获取 cmMarkLabel 列表
|
||||
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( |
List<CmMarkLabel> cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId); |
||||
item.Id, |
// 将 cmMarkLabel 一一添加到 markSeacher
|
||||
PtzInfo.New(item.PanPosition, item.TiltPosition, item.ZoomPosition), |
foreach (CmMarkLabel item in cmMarkLabelList) |
||||
item.VideoWidth, |
{ |
||||
item.VideoHeight, |
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( |
||||
item.CanvasLeftRatio, |
item.Id, |
||||
item.CanvasTopRatio |
PtzInfo.New(item.PanPosition, item.TiltPosition, item.ZoomPosition), |
||||
); |
item.VideoWidth, |
||||
markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo); |
item.VideoHeight, |
||||
} |
item.CanvasLeftRatio, |
||||
// 将 markSeacher 放入字典
|
item.CanvasTopRatio |
||||
_markSearcherDict[cameraId] = markSeacher; |
); |
||||
} |
markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo); |
||||
finally |
} |
||||
{ |
// 将 markSeacher 放入字典
|
||||
msDictLock.ExitWriteLock(); |
_markSearcherDict[cameraId] = markSeacher; |
||||
} |
} |
||||
return true; |
finally |
||||
} |
{ |
||||
|
msDictLock.ExitWriteLock(); |
||||
/// <summary>
|
} |
||||
/// 解除 cbCamera 进入运算
|
return true; |
||||
/// </summary>
|
} |
||||
/// <param name="cameraId"></param>
|
|
||||
/// <returns></returns>
|
/// <summary>
|
||||
public bool DeActivateSearcher(long cameraId) |
/// 解除 cbCamera 进入运算
|
||||
{ |
/// </summary>
|
||||
try |
/// <param name="cameraId"></param>
|
||||
{ |
/// <returns></returns>
|
||||
msDictLock.EnterWriteLock(); |
public bool DeActivateSearcher(long cameraId) |
||||
_markSearcherDict.Remove(cameraId); |
{ |
||||
_markLabelCalcResultListDict.Remove(cameraId); |
try |
||||
} |
{ |
||||
finally |
msDictLock.EnterWriteLock(); |
||||
{ |
_markSearcherDict.Remove(cameraId); |
||||
msDictLock.ExitWriteLock(); |
_markLabelCalcResultListDict.Remove(cameraId); |
||||
} |
} |
||||
return true; |
finally |
||||
} |
{ |
||||
|
msDictLock.ExitWriteLock(); |
||||
public bool IsExistSearcher(long cameraId) |
} |
||||
{ |
return true; |
||||
return _markSearcherDict.ContainsKey(cameraId); |
} |
||||
} |
|
||||
|
public bool IsExistSearcher(long cameraId) |
||||
public bool ActivateMarkLabel(long cameraId, long markLabelId) |
{ |
||||
{ |
return _markSearcherDict.ContainsKey(cameraId); |
||||
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); |
} |
||||
if (!ret) |
|
||||
return false; |
public bool ActivateMarkLabel(long cameraId, long markLabelId) |
||||
if (markSearcher.ExistsMarkLabelCalcInfo(markLabelId)) |
{ |
||||
return false; |
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); |
||||
CmMarkLabel label = _cmMarkLableRep.GetById(markLabelId); |
if (!ret) |
||||
if (label == null) |
return false; |
||||
return false; |
if (markSearcher.ExistsMarkLabelCalcInfo(markLabelId)) |
||||
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( |
return false; |
||||
label.Id, |
CmMarkLabel label = _cmMarkLableRep.GetById(markLabelId); |
||||
PtzInfo.New(label.PanPosition, label.TiltPosition, label.ZoomPosition), |
if (label == null) |
||||
label.VideoWidth, |
return false; |
||||
label.VideoHeight, |
MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( |
||||
label.CanvasLeftRatio, |
label.Id, |
||||
label.CanvasTopRatio |
PtzInfo.New(label.PanPosition, label.TiltPosition, label.ZoomPosition), |
||||
); |
label.VideoWidth, |
||||
return markSearcher.AddMarkLabelCalcInfo(markLabelCalcInfo); |
label.VideoHeight, |
||||
} |
label.CanvasLeftRatio, |
||||
|
label.CanvasTopRatio |
||||
public bool DectivateMarkLabel(long cameraId, long markLabelId) |
); |
||||
{ |
return markSearcher.AddMarkLabelCalcInfo(markLabelCalcInfo); |
||||
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); |
} |
||||
return ret ? markSearcher.DeleteMarkLabelCalcInfo(markLabelId) : false; |
|
||||
} |
public bool DectivateMarkLabel(long cameraId, long markLabelId) |
||||
|
{ |
||||
public bool IsExistCameraMarkLabel(long cameraId, long markLabelId) |
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); |
||||
{ |
return ret ? markSearcher.DeleteMarkLabelCalcInfo(markLabelId) : false; |
||||
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher) && |
} |
||||
markSearcher.ExistsMarkLabelCalcInfo(markLabelId); |
|
||||
return ret; |
public bool IsExistCameraMarkLabel(long cameraId, long markLabelId) |
||||
} |
{ |
||||
|
bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher) && |
||||
public List<MarkLabelCalcResult> GetMarkLabelCalcResultList(long cameraId) |
markSearcher.ExistsMarkLabelCalcInfo(markLabelId); |
||||
{ |
return ret; |
||||
bool ret = _markLabelCalcResultListDict.TryGetValue(cameraId, out List<MarkLabelCalcResult> list); |
} |
||||
return ret ? list : new(); |
|
||||
} |
public List<MarkLabelCalcResult> GetMarkLabelCalcResultList(long cameraId) |
||||
|
{ |
||||
public PtzInfo GetCameraPtzInfo(long cameraId) |
bool ret = _markLabelCalcResultListDict.TryGetValue(cameraId, out List<MarkLabelCalcResult> list); |
||||
{ |
return ret ? list : new(); |
||||
PtzInfo ptzInfo = null; |
} |
||||
bool ret = _cbCameraId2IpDict.TryGetValue(cameraId,out string cameraIp) && |
|
||||
_cameraPtzInfoDict.TryGetValue(cameraIp, out ptzInfo); |
public PtzInfo GetCameraPtzInfo(long cameraId) |
||||
return ret ? ptzInfo : null; |
{ |
||||
} |
PtzInfo ptzInfo = null; |
||||
|
bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp) && |
||||
public async Task<bool> ActivateSearcherAsync(long cameraId) |
_cameraPtzInfoDict.TryGetValue(cameraIp, out ptzInfo); |
||||
{ |
return ret ? ptzInfo : null; |
||||
return await Task.Run(() => |
} |
||||
{ |
|
||||
return ActivateSearcher(cameraId); |
public async Task<bool> ActivateSearcherAsync(long cameraId) |
||||
}); |
{ |
||||
} |
return await Task.Run(() => |
||||
|
{ |
||||
public async Task<bool> DeActivateSearcherAsync(long cameraId) |
return ActivateSearcher(cameraId); |
||||
{ |
}); |
||||
return await Task.Run(() => |
} |
||||
{ |
|
||||
return DeActivateSearcher(cameraId); |
public async Task<bool> DeActivateSearcherAsync(long cameraId) |
||||
}); |
{ |
||||
} |
return await Task.Run(() => |
||||
|
{ |
||||
public async Task<bool> IsExistSearcherAsync(long cameraId) |
return DeActivateSearcher(cameraId); |
||||
{ |
}); |
||||
return await Task.Run(() => |
} |
||||
{ |
|
||||
return IsExistSearcher(cameraId); |
public async Task<bool> IsExistSearcherAsync(long cameraId) |
||||
}); |
{ |
||||
} |
return await Task.Run(() => |
||||
|
{ |
||||
public async Task<bool> ActivateMarkLabelAsync(long cameraId, long markLabelId) |
return IsExistSearcher(cameraId); |
||||
{ |
}); |
||||
return await Task.Run(() => |
} |
||||
{ |
|
||||
return ActivateMarkLabel(cameraId, markLabelId); |
public async Task<bool> ActivateMarkLabelAsync(long cameraId, long markLabelId) |
||||
}); |
{ |
||||
} |
return await Task.Run(() => |
||||
|
{ |
||||
public async Task<bool> DeactivateMarkLabelAsync(long cameraId, long markLabelId) |
return ActivateMarkLabel(cameraId, markLabelId); |
||||
{ |
}); |
||||
return await Task.Run(() => |
} |
||||
{ |
|
||||
return DectivateMarkLabel(cameraId, markLabelId); |
public async Task<bool> DeactivateMarkLabelAsync(long cameraId, long markLabelId) |
||||
}); |
{ |
||||
} |
return await Task.Run(() => |
||||
|
{ |
||||
public async Task<bool> IsExistMarkLabelAysnc(long cameraId, long markLabelId) |
return DectivateMarkLabel(cameraId, markLabelId); |
||||
{ |
}); |
||||
return await Task.Run(() => |
} |
||||
{ |
|
||||
return IsExistCameraMarkLabel(cameraId, markLabelId); |
public async Task<bool> IsExistMarkLabelAysnc(long cameraId, long markLabelId) |
||||
}); |
{ |
||||
} |
return await Task.Run(() => |
||||
|
{ |
||||
public async Task<List<MarkLabelCalcResult>> GetMarkLabelCalcResultListAsync(long cameraId) |
return IsExistCameraMarkLabel(cameraId, markLabelId); |
||||
{ |
}); |
||||
return await Task.Run(() => |
} |
||||
{ |
|
||||
return GetMarkLabelCalcResultList(cameraId); |
public async Task<List<MarkLabelCalcResult>> GetMarkLabelCalcResultListAsync(long cameraId) |
||||
}); |
{ |
||||
} |
return await Task.Run(() => |
||||
|
{ |
||||
#endregion external call
|
return GetMarkLabelCalcResultList(cameraId); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
#endregion external call
|
||||
} |
} |
@ -1 +1,13 @@ |
|||||
Serve.Run(RunOptions.Default.WithArgs(args)); |
Serve.Run(RunOptions.Default.AddWebComponent<WebComponent>().WithArgs(args)); |
||||
|
|
||||
|
public class WebComponent : IWebComponent |
||||
|
{ |
||||
|
public void Load(WebApplicationBuilder builder, ComponentContext componentContext) |
||||
|
{ |
||||
|
// ÈÕÖ¾¹ýÂË
|
||||
|
builder.Logging.AddFilter((provider, category, logLevel) => |
||||
|
{ |
||||
|
return !new[] { "Microsoft.Hosting", "Microsoft.AspNetCore" }.Any(u => category.StartsWith(u)) && logLevel >= LogLevel.Information; |
||||
|
}); |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue