Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加自定义日志模型检索条件 #106

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
10 changes: 8 additions & 2 deletions LogDashboard.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.452
# Visual Studio Version 17
VisualStudioVersion = 17.7.34003.232
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogDashboard", "src\LogDashboard\LogDashboard.csproj", "{A005DD97-96F5-402D-935C-1232E6B41F5F}"
EndProject
Expand Down Expand Up @@ -38,6 +38,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UseAuthorization", "samples
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MySqlDatabase", "samples\MySqlDatabase\MySqlDatabase.csproj", "{EB0A1237-E9B8-4138-A8CE-DBD6C41771FC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SerilogTest", "..\SerilogTest\SerilogTest\SerilogTest.csproj", "{142FBB20-1F8A-4A4C-BA15-D6940235FFA3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -96,6 +98,10 @@ Global
{EB0A1237-E9B8-4138-A8CE-DBD6C41771FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB0A1237-E9B8-4138-A8CE-DBD6C41771FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB0A1237-E9B8-4138-A8CE-DBD6C41771FC}.Release|Any CPU.Build.0 = Release|Any CPU
{142FBB20-1F8A-4A4C-BA15-D6940235FFA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{142FBB20-1F8A-4A4C-BA15-D6940235FFA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{142FBB20-1F8A-4A4C-BA15-D6940235FFA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{142FBB20-1F8A-4A4C-BA15-D6940235FFA3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
76 changes: 76 additions & 0 deletions samples/UseSerilog/ApplicationLogModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using LogDashboard.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UseSerilog
{
/// <summary>
/// 自定义日志模型
/// </summary>
public class ApplicationLogModel : LogModel
{
/// <summary>
/// 服务器名称
/// </summary>
public string MachineName { get; set; } = "";
/// <summary>
/// 环境用户名称
/// </summary>
public string EnvironmentUserName { get; set; } = "";
/// <summary>
/// 进程ID
/// </summary>
public string ProcessId { get; set; } = "";
/// <summary>
/// 线程ID
/// </summary>
public string ThreadId { get; set; } = "";
/// <summary>
/// 客户端IP
/// </summary>
public string ClientIp { get; set; } = "";
/// <summary>
/// 客户端用户代理
/// </summary>
public string UserAgent { get; set; } = "";
/// <summary>
/// 企业ID
/// </summary>
public string Enterpriseid { get; set; } = "";
/// <summary>
/// 请求地址
/// </summary>
public string RequestPath { get; set; } = "";
/// <summary>
/// 请求方式
/// </summary>
public string RequestMethod { get; set; } = "";
/// <summary>
/// 来源页面
/// </summary>
public string Referer { get; set; } = "";
/// <summary>
/// 用户账户ID
/// </summary>
public string UserAccountId { get; set; } = "";
/// <summary>
/// 用户ID
/// </summary>
public string UserInfoId { get; set; } = "";
/// <summary>
/// 用户账户
/// </summary>
public string UserAccountName { get; set; } = "";
/// <summary>
/// 用户姓名
/// </summary>
public string UserInfoName { get; set; } = "";
/// <summary>
/// 登录AccessToken
/// </summary>
public string UserAccessToken { get; set; } = "";
}
}
2 changes: 1 addition & 1 deletion samples/UseSerilog/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static void Main(string[] args)
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.File($"{AppContext.BaseDirectory}Log/.log", rollingInterval:RollingInterval.Day,outputTemplate: "{Timestamp:HH:mm} || {Level} || {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")
.WriteTo.File($"{AppContext.BaseDirectory}Log/.log", rollingInterval:RollingInterval.Day,outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} || {Level} || {SourceContext:l} || {Message} || {Exception} || {MachineName} || {EnvironmentUserName} || {ProcessId} || {ThreadId} || {ClientIp} || {UserAgent} || {Enterpriseid} || {RequestPath} || {RequestMethod} || {Referer} || {UserAccountId} || {UserInfoId} || {UserAccountName} || {UserInfoName} || {UserAccessToken} || end {NewLine}")
.CreateLogger();

CreateWebHostBuilder(args).Build().Run();
Expand Down
6 changes: 3 additions & 3 deletions samples/UseSerilog/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51349",
"sslPort": 44370
Expand All @@ -18,7 +18,7 @@
"UseSerilog": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"applicationUrl": "https://localhost:5008",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
Expand Down
5 changes: 4 additions & 1 deletion samples/UseSerilog/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ public class Startup
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddLogDashboard();
services.AddLogDashboard(opt =>
{
opt.CustomLogModel<ApplicationLogModel>();
});
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down
9 changes: 9 additions & 0 deletions samples/UseSerilog/UseSerilog.csproj.user
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup>
<ActiveDebugProfile>UseSerilog</ActiveDebugProfile>
</PropertyGroup>
</Project>
58 changes: 58 additions & 0 deletions src/LogDashboard/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Text;

namespace LogDashboard.Extensions
Expand Down Expand Up @@ -76,5 +77,62 @@ private static IEnumerable<TResult> PairwiseImpl<TSource, TResult>(this IEnumera
}
}
}
/// <summary>
/// 动态组建Linq条件,例如 s=>s.id==1
/// </summary>
/// <typeparam name="T">泛型对象</typeparam>
/// <typeparam name="Tkey">泛型表达式值</typeparam>
/// <param name="propertyName">传入的属性名称</param>
/// <param name="Value">传入的属性值</param>
/// <returns>返回lambda表达式</returns>
public static Expression<Func<T, Tkey>> WhereEqualData<T, Tkey>(string propertyName, object Value)
{
Type cType = typeof(T);
ParameterExpression paramEx = Expression.Parameter(cType, "s");
Expression left = Expression.Property(paramEx, cType, propertyName);
Expression right = Expression.Constant(Value);
Expression fi = Expression.Equal(left, right);
Expression<Func<T, Tkey>> lambda = Expression.Lambda<Func<T, Tkey>>(fi, paramEx);
return lambda;
}
/// <summary>
/// 动态组建Linq条件,例如 s=>s.id!=1 s=>s.id>1
/// </summary>
/// <typeparam name="T">泛型对象</typeparam>
/// <typeparam name="Tkey">泛型表达式值</typeparam>
/// <param name="propertyName">传入的属性名称</param>
/// <param name="Value">传入的属性值</param>
/// <param name="func">连接符方法</param>
/// <returns>返回lambda表达式</returns>
public static Expression<Func<T, Tkey>> WhereData<T, Tkey>(string propertyName, object Value, Func<Expression, Expression, Expression> func)
{
Type cType = typeof(T);
ParameterExpression paramEx = Expression.Parameter(cType, "s");
Expression left = Expression.Property(paramEx, cType, propertyName);
Expression right = Expression.Constant(Value);
Expression fi = func(left, right);
Expression<Func<T, Tkey>> lambda = Expression.Lambda<Func<T, Tkey>>(fi, paramEx);
return lambda;
}
/// <summary>
/// 动态组建Linq条件,例如 s=>s.name.Contains("abc")
/// </summary>
/// <typeparam name="T">泛型对象</typeparam>
/// <typeparam name="Tkey">泛型表达式值</typeparam>
/// <param name="propertyName">传入的属性名称</param>
/// <param name="Value">传入的属性值</param>
/// <param name="methord">方法名称 例如:Contains</param>
/// <returns>返回lambda表达式</returns>
public static Expression<Func<T, Tkey>> WhereData<T, Tkey>(string propertyName, object Value, string methord)
{
Type cType = typeof(T);
ParameterExpression paramEx = Expression.Parameter(cType, "s");
Expression left = Expression.Property(paramEx, cType, propertyName);
Expression right = Expression.Constant(Value);
var method = typeof(string).GetMethod(methord, new[] { typeof(string) });
Expression fi = Expression.Call(left, method, right);
Expression<Func<T, Tkey>> lambda = Expression.Lambda<Func<T, Tkey>>(fi, paramEx);
return lambda;
}
}
}
33 changes: 27 additions & 6 deletions src/LogDashboard/Handle/DashboardHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Cryptography;
using System.Threading.Tasks;
using DapperExtensions;
using LogDashboard.Extensions;
using LogDashboard.Handle.LogChart;
using LogDashboard.Models;
using LogDashboard.Repository;
using LogDashboard.Views.Dashboard;
using Newtonsoft.Json;

namespace LogDashboard.Handle
{
Expand All @@ -29,7 +31,7 @@ public async Task<string> Home()
ViewData["basicLogNav"] = "";
var result = await _logRepository.GetPageListAsync(1, 10, sorts: new[] { new Sort { Ascending = false, PropertyName = "Id" } });

ViewData["unique"] = (await _logRepository.UniqueCountAsync()).Count;
//ViewData["unique"] = (await _logRepository.UniqueCountAsync()).Count;

var now = DateTime.Now;
var weeHours = now.Date.AddHours(23).AddMinutes(59).AddSeconds(59);
Expand Down Expand Up @@ -104,14 +106,33 @@ private async Task<PagedResultModel<T>> GetPageResult(SearchLogInput input)
{
return x => x.Message.Contains(input.Message) || x.Logger.Contains(input.Message);
});

if (input.Unique)
//自定义日志模型检索条件(反射实现)
if (!string.IsNullOrWhiteSpace(input.ApplicationLogModel))
{
var uniqueLogs = await _logRepository.UniqueCountAsync(expression);

return new PagedResultModel<T>(uniqueLogs.Count, await _logRepository.GetPageListAsync(input.Page, input.PageSize, expression, new[] { new Sort { Ascending = false, PropertyName = "Id" } }, uniqueLogs.ids));
var itemValue = JsonConvert.DeserializeObject<T>(input.ApplicationLogModel);
Type modelType = typeof(T);
var modelProperties = modelType.GetProperties().Where(p => !typeof(LogModel).GetProperties().Select(p => p.Name).Contains(p.Name)).ToArray();
foreach (var item in modelProperties)
{
var inputVal = itemValue.GetType().GetProperty(item.Name).GetValue(itemValue, null);
if (inputVal != null)
{
var inputValue = inputVal.ToString();
expression = expression.AndIf(!string.IsNullOrWhiteSpace(inputValue), () =>
{
return EnumerableExtensions.WhereData<T, bool>(item.Name, inputValue, "Contains");
});
}
}
}

//if (input.Unique)
//{
// var uniqueLogs = await _logRepository.UniqueCountAsync(expression);

// return new PagedResultModel<T>(uniqueLogs.Count, await _logRepository.GetPageListAsync(input.Page, input.PageSize, expression, new[] { new Sort { Ascending = false, PropertyName = "Id" } }, uniqueLogs.ids));
//}

var logs = await _logRepository.GetPageListAsync(input.Page, input.PageSize, expression, new[] { new Sort { Ascending = false, PropertyName = "Id" } });

var totalCount = await _logRepository.CountAsync(expression);
Expand Down
28 changes: 15 additions & 13 deletions src/LogDashboard/Handle/LogChart/DayLogChart.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using LogDashboard.Models;
using LogDashboard.Repository;
Expand All @@ -15,6 +19,9 @@ public async Task<GetLogChartsOutput> GetCharts<T>(IRepository<T> repository) wh
var output = new GetLogChartsOutput(24);

var date = now.Date;

var list = await repository.GetLevelCount(ChartDataType.Day, now.Date, now);

for (var i = 0; i < 24; i++)
{
if (i > hour)
Expand All @@ -29,22 +36,17 @@ public async Task<GetLogChartsOutput> GetCharts<T>(IRepository<T> repository) wh
}
else
{
var startTime = date.AddHours(i);
output.All[i] = await repository.CountAsync(x => x.LongDate >= startTime && x.LongDate <= startTime.AddMinutes(59).AddSeconds(59));
output.Error[i] = await CountAsync(LogLevelConst.Error, repository, startTime, i);
output.Info[i] = await CountAsync(LogLevelConst.Info, repository, startTime, i);
output.Debug[i] = await CountAsync(LogLevelConst.Debug, repository, startTime, i);
output.Fatal[i] = await CountAsync(LogLevelConst.Fatal, repository, startTime, i);
output.Trace[i] = await CountAsync(LogLevelConst.Trace, repository, startTime, i);
output.Warn[i] = await CountAsync(LogLevelConst.Warn, repository, startTime, i);
var thisList = list.Where(p => DateTime.Parse(p.LongDate).Hour == i);
output.All[i] = thisList.Sum(p => p.Count);
output.Error[i] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Error).Sum(p => p.Count);
output.Info[i] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Info).Sum(p => p.Count);
output.Debug[i] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Debug).Sum(p => p.Count);
output.Fatal[i] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Fatal).Sum(p => p.Count);
output.Trace[i] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Trace).Sum(p => p.Count);
output.Warn[i] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Warn).Sum(p => p.Count);
}
}
return output;
}

private async Task<int> CountAsync<T>(string level, IRepository<T> repository, DateTime startTime, int i) where T : class, ILogModel
{
return await repository.CountAsync(x => x.LongDate >= startTime && x.LongDate <= startTime.AddMinutes(59).AddSeconds(59) && x.Level == level);
}
}
}
24 changes: 12 additions & 12 deletions src/LogDashboard/Handle/LogChart/HourChart.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using LogDashboard.Models;
using LogDashboard.Repository;
Expand All @@ -13,6 +14,9 @@ public async Task<GetLogChartsOutput> GetCharts<T>(IRepository<T> repository) wh
var minute = now.Minute;
var hourTime = DateTime.Now.Date.AddHours(now.Hour);
var output = new GetLogChartsOutput(6);

var list = await repository.GetLevelCount(ChartDataType.Hour, hourTime, now);

for (var i = 0; i < 60; i += 10)
{
if (i > minute)
Expand All @@ -27,21 +31,17 @@ public async Task<GetLogChartsOutput> GetCharts<T>(IRepository<T> repository) wh
}
else
{
output.All[i / 10] = await repository.CountAsync(x => x.LongDate >= hourTime.AddMinutes(i) && x.LongDate <= hourTime.AddMinutes(i + 9).AddSeconds(59));
output.Error[i / 10] = await CountAsync(LogLevelConst.Error, repository, hourTime, i);
output.Info[i / 10] = await CountAsync(LogLevelConst.Info, repository, hourTime, i);
output.Debug[i / 10] = await CountAsync(LogLevelConst.Debug, repository, hourTime, i);
output.Fatal[i / 10] = await CountAsync(LogLevelConst.Fatal, repository, hourTime, i);
output.Trace[i / 10] = await CountAsync(LogLevelConst.Trace, repository, hourTime, i);
output.Warn[i / 10] = await CountAsync(LogLevelConst.Warn, repository, hourTime, i);
var thisList = list.Where(p => DateTime.Parse(p.LongDate).Minute == i);
output.All[i / 10] = thisList.Sum(p => p.Count);
output.Error[i / 10] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Error).Sum(p => p.Count);
output.Info[i / 10] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Info).Sum(p => p.Count);
output.Debug[i / 10] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Debug).Sum(p => p.Count);
output.Fatal[i / 10] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Fatal).Sum(p => p.Count);
output.Trace[i / 10] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Trace).Sum(p => p.Count);
output.Warn[i / 10] = thisList.Where(p => p.Level.ToUpper() == LogLevelConst.Warn).Sum(p => p.Count);
}
}
return output;
}

private async Task<int> CountAsync<T>(string level, IRepository<T> repository, DateTime hourTime, int i) where T : class, ILogModel
{
return await repository.CountAsync(x => x.LongDate >= hourTime.AddMinutes(i) && x.LongDate <= hourTime.AddMinutes(i + 9).AddSeconds(59) && x.Level == level);
}
}
}
Loading