mirror of
https://github.com/anjoy8/Blog.Core.git
synced 2024-09-20 23:48:27 +08:00
✨ 初步调整Serilog
This commit is contained in:
parent
d1288b103e
commit
0d2a95e0e9
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -356,3 +356,5 @@ Blog.Core/Blog.Core*.xml
|
|||
Blog.Core.Api/WMBlog.db
|
||||
Blog.Core.Api/wwwroot/ui/
|
||||
*.db
|
||||
/Blog.Core.Api/WMBlog.db-journal
|
||||
Logs
|
||||
|
|
|
@ -26,21 +26,25 @@
|
|||
<ItemGroup>
|
||||
<Compile Remove="Extensions\**" />
|
||||
<Compile Remove="Hubs\**" />
|
||||
<Compile Remove="Logs\**" />
|
||||
<Compile Remove="Log\**" />
|
||||
<Compile Remove="Middlewares\**" />
|
||||
<Compile Remove="wwwroot\ui\**" />
|
||||
<Content Remove="Extensions\**" />
|
||||
<Content Remove="Hubs\**" />
|
||||
<Content Remove="Logs\**" />
|
||||
<Content Remove="Log\**" />
|
||||
<Content Remove="Middlewares\**" />
|
||||
<Content Remove="wwwroot\ui\**" />
|
||||
<EmbeddedResource Remove="Extensions\**" />
|
||||
<EmbeddedResource Remove="Hubs\**" />
|
||||
<EmbeddedResource Remove="Logs\**" />
|
||||
<EmbeddedResource Remove="Log\**" />
|
||||
<EmbeddedResource Remove="Middlewares\**" />
|
||||
<EmbeddedResource Remove="wwwroot\ui\**" />
|
||||
<None Remove="Extensions\**" />
|
||||
<None Remove="Hubs\**" />
|
||||
<None Remove="Logs\**" />
|
||||
<None Remove="Log\**" />
|
||||
<None Remove="Middlewares\**" />
|
||||
<None Remove="wwwroot\ui\**" />
|
||||
|
@ -51,8 +55,6 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="log4mongo-netcore" Version="3.2.0" />
|
||||
<PackageReference Include="MicroKnights.Log4NetAdoNetAppender" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
|
||||
|
|
|
@ -760,7 +760,7 @@
|
|||
Values控制器
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Blog.Core.Controllers.ValuesController.#ctor(Blog.Core.IServices.IBlogArticleServices,AutoMapper.IMapper,Blog.Core.IServices.IAdvertisementServices,Blog.Core.Model.Love,Blog.Core.IServices.IRoleModulePermissionServices,Blog.Core.Common.HttpContextUser.IUser,Blog.Core.IServices.IPasswordLibServices,Blog.Core.Common.WebApiClients.HttpApis.IBlogApi,Blog.Core.Common.WebApiClients.HttpApis.IDoubanApi,Blog.Core.Common.HttpPolly.IHttpPollyHelper)">
|
||||
<member name="M:Blog.Core.Controllers.ValuesController.#ctor(Blog.Core.IServices.IBlogArticleServices,AutoMapper.IMapper,Blog.Core.IServices.IAdvertisementServices,Blog.Core.Model.Love,Blog.Core.IServices.IRoleModulePermissionServices,Blog.Core.Common.HttpContextUser.IUser,Blog.Core.IServices.IPasswordLibServices,Blog.Core.Common.WebApiClients.HttpApis.IBlogApi,Blog.Core.Common.WebApiClients.HttpApis.IDoubanApi,Blog.Core.Common.Https.HttpPolly.IHttpPollyHelper)">
|
||||
<summary>
|
||||
ValuesController
|
||||
</summary>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using AutoMapper;
|
||||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.HttpContextUser;
|
||||
using Blog.Core.Common.HttpPolly;
|
||||
using Blog.Core.Common.Https.HttpPolly;
|
||||
using Blog.Core.Common.WebApiClients.HttpApis;
|
||||
using Blog.Core.EventBus;
|
||||
using Blog.Core.EventBus.EventHandling;
|
||||
|
|
|
@ -3,14 +3,10 @@ using Blog.Core.Common.Helper;
|
|||
using Blog.Core.Common.LogHelper;
|
||||
using Blog.Core.Hubs;
|
||||
using Blog.Core.Model;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StackExchange.Profiling;
|
||||
using System;
|
||||
|
||||
namespace Blog.Core.Filter
|
||||
{
|
||||
|
@ -54,7 +50,7 @@ namespace Blog.Core.Filter
|
|||
MiniProfiler.Current.CustomTiming("Errors:", json.msg);
|
||||
|
||||
|
||||
//采用log4net 进行错误日志记录
|
||||
//进行错误日志记录
|
||||
_loggerHelper.LogError(json.msg + WriteLog(json.msg, context.Exception));
|
||||
if (AppSettings.app(new string[] { "Middleware", "SignalRSendLog", "Enabled" }).ObjToBool())
|
||||
{
|
||||
|
|
|
@ -1,364 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<log4net>
|
||||
<!--BEGIN*************** SQLite 结构化记录日志 *************************BEGIN -->
|
||||
<!--2022/11/23 原因:结构化日志SQLite支持,PR2022/11/23-->
|
||||
<appender name="SQLiteAdoNetAppenderStructured" type="MicroKnights.Logging.AdoNetAppender, MicroKnights.Log4NetAdoNetAppender">
|
||||
<bufferSize value="1" />
|
||||
<connectionType value="Microsoft.Data.Sqlite.SqliteConnection, Microsoft.Data.Sqlite, Version=7.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60" />
|
||||
<connectionStringName value="sqlite" />
|
||||
<connectionString value="Data Source=WMBlog.db" />
|
||||
<commandText value="INSERT INTO GblLogAudit ([Date],[Thread],[Level],[Logger],[LogType],[DataType],[Message],[Exception],[TraceId]) VALUES (@log_date, @thread, @log_level, @logger,@logType,@dataType, @message, @exception,@traceId)" />
|
||||
<parameter>
|
||||
<parameterName value="@log_date" />
|
||||
<dbType value="DateTime" />
|
||||
<layout type="log4net.Layout.RawTimeStampLayout" />
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@thread" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%thread" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@log_level" />
|
||||
<dbType value="String" />
|
||||
<size value="50" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%level" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@logger" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%logger" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@logType" />
|
||||
<dbType value="String" />
|
||||
<size value="50" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{LogType}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@dataType" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{DataType}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@message" />
|
||||
<dbType value="String" />
|
||||
<size value="999999999" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%message" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@exception" />
|
||||
<dbType value="String" />
|
||||
<size value="999999999" />
|
||||
<layout type="log4net.Layout.ExceptionLayout" />
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@traceId" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{TraceId}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<filter type="log4net.Filter.LevelRangeFilter">
|
||||
<levelMin value="DEBUG" />
|
||||
<levelMax value="FATAL" />
|
||||
</filter>
|
||||
</appender>
|
||||
<!--END***************** SQLite 结构化记录日志 ***********************END -->
|
||||
|
||||
<!--BEGIN*************** SQLServer 结构化记录日志 *************************BEGIN -->
|
||||
<!--2022/11/27 原因:结构化日志SQLServer支持,PR2022/11/27-->
|
||||
<!--如若使用请配置connectionString 节点,复制appsettings.json对应配置字符替换即可,-->
|
||||
<!--然后启用下方日志记录器(SQLServerAdoNetAppenderStructured)-->
|
||||
<appender name="SQLServerAdoNetAppenderStructured" type="MicroKnights.Logging.AdoNetAppender, MicroKnights.Log4NetAdoNetAppender">
|
||||
<bufferSize value="1" />
|
||||
<connectionType value="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient, Version=1.0.0.0,Culture=neutral,PublicKeyToken=23ec7fc2d6eaa4a5"/>
|
||||
<connectionStringName value="sqlserver" />
|
||||
<connectionString value="Server=xxxxxx;Database=xxxxxx;User Id=xx;Password=xxxxxx;" />
|
||||
<commandText value="INSERT INTO GblLogAudit ([Date],[Thread],[Level],[Logger],[LogType],[DataType],[Message],[Exception],[TraceId]) VALUES (@log_date, @thread, @log_level, @logger,@logType,@dataType, @message, @exception,@traceId)" />
|
||||
<parameter>
|
||||
<parameterName value="@log_date" />
|
||||
<dbType value="DateTime" />
|
||||
<layout type="log4net.Layout.RawTimeStampLayout" />
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@thread" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%thread" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@log_level" />
|
||||
<dbType value="String" />
|
||||
<size value="50" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%level" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@logger" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%logger" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@logType" />
|
||||
<dbType value="String" />
|
||||
<size value="50" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{LogType}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@dataType" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{DataType}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@message" />
|
||||
<dbType value="String" />
|
||||
<size value="999999999" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%message" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@exception" />
|
||||
<dbType value="String" />
|
||||
<size value="999999999" />
|
||||
<layout type="log4net.Layout.ExceptionLayout" />
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@traceId" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{TraceId}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<filter type="log4net.Filter.LevelRangeFilter">
|
||||
<levelMin value="DEBUG" />
|
||||
<levelMax value="FATAL" />
|
||||
</filter>
|
||||
</appender>
|
||||
<!--END***************** SQLServer 结构化记录日志 ***********************END -->
|
||||
|
||||
<!--******************** MySQL 结构化记录日志 ********************BEGIN -->
|
||||
<!--2022/11/27 原因:结构化日志MySQL支持,PR2022/11/27-->
|
||||
<!--如若使用请配置connectionString 节点,复制appsettings.json对应配置字符替换即可,-->
|
||||
<!--然后启用下方日志记录器(MySQLAdoNetAppenderStructured)-->
|
||||
<appender name="MySQLAdoNetAppenderStructured" type="MicroKnights.Logging.AdoNetAppender, MicroKnights.Log4NetAdoNetAppender">
|
||||
<bufferSize value="1" />
|
||||
<usetransactions value="false" />
|
||||
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data, Version=8.0.21, Culture=neutral" />
|
||||
<connectionStringName value="mysql" />
|
||||
<connectionString value="server=xxxxxx;Database=xxxxxx;Uid=root;Pwd=xxxxxx;Port=3306;Allow User Variables=True;" />
|
||||
<commandText value="INSERT INTO GblLogAudit (Date,Thread,Level,Logger,LogType,DataType,Message,Exception,TraceId) VALUES (@log_date, @thread, @log_level, @logger,@logType,@dataType, @message, @exception,@traceId)" />
|
||||
<parameter>
|
||||
<parameterName value="@log_date" />
|
||||
<dbType value="DateTime" />
|
||||
<layout type="log4net.Layout.RawTimeStampLayout" />
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@thread" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%thread" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@log_level" />
|
||||
<dbType value="String" />
|
||||
<size value="50" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%level" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@logger" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%logger" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@logType" />
|
||||
<dbType value="String" />
|
||||
<size value="50" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{LogType}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@dataType" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{DataType}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@message" />
|
||||
<dbType value="String" />
|
||||
<size value="999999999" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%message" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@exception" />
|
||||
<dbType value="String" />
|
||||
<size value="999999999" />
|
||||
<layout type="log4net.Layout.ExceptionLayout" />
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@traceId" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{TraceId}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<filter type="log4net.Filter.LevelRangeFilter">
|
||||
<levelMin value="DEBUG" />
|
||||
<levelMax value="FATAL" />
|
||||
</filter>
|
||||
</appender>
|
||||
<!--END***************** MySQL 结构化记录日志 ***********************END -->
|
||||
|
||||
|
||||
<!--BEGIN*************** PostgreSql 结构化记录日志 *************************BEGIN -->
|
||||
<!--2023/01/31 原因:结构化日志PostgreSql支持,PR2023/01/31-->
|
||||
<!--如若使用请配置connectionString 节点,复制appsettings.json对应配置字符替换即可,-->
|
||||
<!--然后启用下方日志记录器(PostgreSql)-->
|
||||
<appender name="PostgreSqlAdoNetAppenderStructured" type="MicroKnights.Logging.AdoNetAppender, MicroKnights.Log4NetAdoNetAppender">
|
||||
<!--bufferSize缓存大小-->
|
||||
<bufferSize value="1" />
|
||||
<connectionType value="Npgsql.NpgsqlConnection, Npgsql, Version=5.0.7, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7"/>
|
||||
<connectionStringName value="postgresql" />
|
||||
<connectionString value="PORT=5432;DATABASE=xxxxxx;HOST=xxxxxx;PASSWORD=xxxxxx;USER ID=postgres;" />
|
||||
<commandText value="INSERT INTO GblLogAudit (Date,Thread,Level,Logger,LogType,DataType,Message,Exception,TraceId) VALUES (:log_date, :thread, :log_level, :logger,:logType,:dataType, :message, :exception,:traceId)" />
|
||||
<!--参数(eg:value="@log_date")名前面的@ 可删可不删,测试都可以正常写入日志,这里保持和上面sqlserver一致不删除-->
|
||||
<parameter>
|
||||
<parameterName value="@log_date" />
|
||||
<dbType value="DateTime" />
|
||||
<layout type="log4net.Layout.RawTimeStampLayout" />
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@thread" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%thread" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@log_level" />
|
||||
<dbType value="String" />
|
||||
<size value="50" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%level" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@logger" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%logger" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@logType" />
|
||||
<dbType value="String" />
|
||||
<size value="50" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{LogType}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@dataType" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{DataType}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@message" />
|
||||
<dbType value="String" />
|
||||
<size value="999999999" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%message" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@exception" />
|
||||
<dbType value="String" />
|
||||
<size value="999999999" />
|
||||
<layout type="log4net.Layout.ExceptionLayout" />
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="@traceId" />
|
||||
<dbType value="String" />
|
||||
<size value="255" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%property{TraceId}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<filter type="log4net.Filter.LevelRangeFilter">
|
||||
<levelMin value="DEBUG" />
|
||||
<levelMax value="FATAL" />
|
||||
</filter>
|
||||
</appender>
|
||||
<!--END***************** PostgreSql 结构化记录日志 ***********************END -->
|
||||
|
||||
<!--启用记录器-->
|
||||
<root>
|
||||
<!-- 控制级别,由低到高:ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF -->
|
||||
<!-- 比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录 -->
|
||||
<!-- 如果没有定义LEVEL的值,则缺省为DEBUG -->
|
||||
<level value="ALL" />
|
||||
|
||||
<!--启用日志记录器,目前提供三种日志记录器-->
|
||||
<!--SQLite日志-->
|
||||
<appender-ref ref="SQLiteAdoNetAppenderStructured" />
|
||||
|
||||
<!--SQLServer日志记录器-->
|
||||
<!--<appender-ref ref="SQLServerAdoNetAppenderStructured" />-->
|
||||
|
||||
<!--MySQL日志记录器-->
|
||||
<!--<appender-ref ref="MySQLAdoNetAppenderStructured" />-->
|
||||
|
||||
<!--PostgreSql日志记录器-->
|
||||
<!--<appender-ref ref="PostgreSqlAdoNetAppenderStructured" />-->
|
||||
<!--启用日志记录器,目前提供三种日志记录器-->
|
||||
|
||||
</root>
|
||||
<!--启用记录器-->
|
||||
</log4net>
|
|
@ -1,20 +1,16 @@
|
|||
// 以下为asp.net 6.0的写法,如果用5.0,请看Program.five.cs文件
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using Autofac;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Blog.Core;
|
||||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.Core;
|
||||
using Blog.Core.Common.LogHelper;
|
||||
using Blog.Core.Extensions;
|
||||
using Blog.Core.Extensions.Apollo;
|
||||
using Blog.Core.Extensions.Middlewares;
|
||||
using Blog.Core.Extensions.ServiceExtensions;
|
||||
using Blog.Core.Filter;
|
||||
using Blog.Core.Hubs;
|
||||
using Blog.Core.IServices;
|
||||
using Blog.Core.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
|
@ -22,34 +18,38 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Serilog;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Blog.Core.Common.Https;
|
||||
using Blog.Core.Serilog.Utility;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
|
||||
|
||||
// 1、配置host与容器
|
||||
builder.Host
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
||||
.ConfigureContainer<ContainerBuilder>(builder =>
|
||||
{
|
||||
builder.RegisterModule(new AutofacModuleRegister());
|
||||
builder.RegisterModule<AutofacPropertityModuleReg>();
|
||||
})
|
||||
.ConfigureLogging((hostingContext, builder) =>
|
||||
{
|
||||
builder.AddFilter("System", LogLevel.Error);
|
||||
builder.AddFilter("Microsoft", LogLevel.Error);
|
||||
builder.SetMinimumLevel(LogLevel.Error);
|
||||
builder.AddLog4Net(Path.Combine(Directory.GetCurrentDirectory(), "Log4net.config"));
|
||||
})
|
||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
config.Sources.Clear();
|
||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false);
|
||||
config.AddConfigurationApollo("appsettings.apollo.json");
|
||||
});
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
||||
.ConfigureContainer<ContainerBuilder>(builder =>
|
||||
{
|
||||
builder.RegisterModule(new AutofacModuleRegister());
|
||||
builder.RegisterModule<AutofacPropertityModuleReg>();
|
||||
})
|
||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
config.Sources.Clear();
|
||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false);
|
||||
config.AddConfigurationApollo("appsettings.apollo.json");
|
||||
});
|
||||
builder.ConfigureApplication();
|
||||
|
||||
// 2、配置服务
|
||||
builder.Services.AddSingleton(new AppSettings(builder.Configuration));
|
||||
builder.Services.AddSingleton(new LogLock(builder.Environment.ContentRootPath));
|
||||
|
||||
|
||||
|
||||
builder.Services.AddUiFilesZipSetup(builder.Environment);
|
||||
|
||||
Permissions.IsUseIds4 = AppSettings.app(new string[] { "Startup", "IdentityServer4", "Enabled" }).ObjToBool();
|
||||
|
@ -62,6 +62,9 @@ builder.Services.AddMemoryCacheSetup();
|
|||
builder.Services.AddRedisCacheSetup();
|
||||
builder.Services.AddSqlsugarSetup();
|
||||
builder.Services.AddDbSetup();
|
||||
|
||||
builder.Host.AddSerilogSetup();
|
||||
|
||||
builder.Services.AddAutoMapperSetup();
|
||||
builder.Services.AddCorsSetup();
|
||||
builder.Services.AddMiniProfilerSetup();
|
||||
|
@ -92,34 +95,34 @@ builder.Services.AddIpPolicyRateLimitSetup(builder.Configuration);
|
|||
builder.Services.AddSignalR().AddNewtonsoftJsonProtocol();
|
||||
builder.Services.AddScoped<UseServiceDIAttribute>();
|
||||
builder.Services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true)
|
||||
.Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);
|
||||
.Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);
|
||||
|
||||
builder.Services.AddDistributedMemoryCache();
|
||||
builder.Services.AddSession();
|
||||
builder.Services.AddHttpPollySetup();
|
||||
builder.Services.AddControllers(o =>
|
||||
{
|
||||
o.Filters.Add(typeof(GlobalExceptionsFilter));
|
||||
//o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention());
|
||||
o.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name)));
|
||||
})
|
||||
.AddNewtonsoftJson(options =>
|
||||
{
|
||||
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
||||
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
|
||||
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
||||
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
||||
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
|
||||
options.SerializerSettings.Converters.Add(new StringEnumConverter());
|
||||
})
|
||||
//.AddFluentValidation(config =>
|
||||
//{
|
||||
// //程序集方式添加验证
|
||||
// config.RegisterValidatorsFromAssemblyContaining(typeof(UserRegisterVoValidator));
|
||||
// //是否与MvcValidation共存
|
||||
// config.DisableDataAnnotationsValidation = true;
|
||||
//})
|
||||
;
|
||||
{
|
||||
o.Filters.Add(typeof(GlobalExceptionsFilter));
|
||||
//o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention());
|
||||
o.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name)));
|
||||
})
|
||||
.AddNewtonsoftJson(options =>
|
||||
{
|
||||
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
||||
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
|
||||
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
||||
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
|
||||
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
|
||||
options.SerializerSettings.Converters.Add(new StringEnumConverter());
|
||||
})
|
||||
//.AddFluentValidation(config =>
|
||||
//{
|
||||
// //程序集方式添加验证
|
||||
// config.RegisterValidatorsFromAssemblyContaining(typeof(UserRegisterVoValidator));
|
||||
// //是否与MvcValidation共存
|
||||
// config.DisableDataAnnotationsValidation = true;
|
||||
//})
|
||||
;
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
|
||||
|
@ -159,12 +162,23 @@ app.UseDefaultFiles(defaultFilesOptions);
|
|||
app.UseStaticFiles();
|
||||
app.UseCookiePolicy();
|
||||
app.UseStatusCodePages();
|
||||
app.UseSerilogRequestLogging(options =>
|
||||
{
|
||||
options.GetLevel = SerilogRequestUtility.GetRequestLevel;
|
||||
options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
|
||||
{
|
||||
diagnosticContext.Set("RequestHost", httpContext.Request.Host.Value);
|
||||
diagnosticContext.Set("RequestScheme", httpContext.Request.Scheme);
|
||||
diagnosticContext.Set("RequestIp", httpContext.GetRequestIp());
|
||||
};
|
||||
});
|
||||
app.UseRouting();
|
||||
|
||||
if (builder.Configuration.GetValue<bool>("AppSettings:UseLoadTest"))
|
||||
{
|
||||
app.UseMiddleware<ByPassAuthMiddleware>();
|
||||
}
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseMiniProfilerMiddleware();
|
||||
|
|
|
@ -39,7 +39,6 @@ namespace Blog.Core
|
|||
{
|
||||
// 以下code可能与文章中不一样,对代码做了封装,具体查看右侧 Extensions 文件夹.
|
||||
services.AddSingleton(new AppSettings(Configuration));
|
||||
services.AddSingleton(new LogLock(Env.ContentRootPath));
|
||||
services.AddUiFilesZipSetup(Env);
|
||||
|
||||
Permissions.IsUseIds4 = AppSettings.app(new string[] { "Startup", "IdentityServer4", "Enabled" }).ObjToBool();
|
||||
|
|
|
@ -1,98 +1,92 @@
|
|||
{
|
||||
"urls": "http://*:9291", //web服务端口,如果用IIS部署,把这个去掉
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information", //加入Default否则log4net本地写入不了日志
|
||||
"Blog.Core.AuthHelper.ApiResponseHandler": "Error"
|
||||
},
|
||||
"Debug": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
},
|
||||
"Console": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Debug"
|
||||
}
|
||||
},
|
||||
"Log4Net": {
|
||||
"Name": "Blog.Core"
|
||||
}
|
||||
"urls": "http://*:9291", //web服务端口,如果用IIS部署,把这个去掉
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Debug",
|
||||
"Override": {
|
||||
"Microsoft": "Information",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"System": "Warning",
|
||||
"System.Net.Http.HttpClient": "Warning",
|
||||
"Hangfire": "Information",
|
||||
"Magicodes": "Warning",
|
||||
"DotNetCore.CAP": "Information",
|
||||
"Savorboard.CAP": "Information",
|
||||
"Quartz": "Information"
|
||||
}
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"Redis": {
|
||||
"ConnectionString": "127.0.0.1:6319,password=admin"
|
||||
},
|
||||
"RabbitMQ": {
|
||||
"Enabled": false,
|
||||
"Connection": "118.25.251.13",
|
||||
"UserName": "",
|
||||
"Password": "!",
|
||||
"RetryCount": 3
|
||||
},
|
||||
"Kafka": {
|
||||
"Enabled": false,
|
||||
"Servers": "localhost:9092",
|
||||
"Topic": "blog",
|
||||
"GroupId": "blog-consumer",
|
||||
"NumPartitions": 3 //主题分区数量
|
||||
},
|
||||
"EventBus": {
|
||||
"Enabled": false,
|
||||
"SubscriptionClientName": "Blog.Core"
|
||||
},
|
||||
"AppSettings": {
|
||||
"RedisCachingAOP": {
|
||||
"Enabled": false
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"Redis": {
|
||||
"ConnectionString": "127.0.0.1:6319,password=admin"
|
||||
"MemoryCachingAOP": {
|
||||
"Enabled": true
|
||||
},
|
||||
"RabbitMQ": {
|
||||
"Enabled": false,
|
||||
"Connection": "118.25.251.13",
|
||||
"UserName": "",
|
||||
"Password": "!",
|
||||
"RetryCount": 3
|
||||
"LogAOP": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"Kafka": {
|
||||
"Enabled": false,
|
||||
"Servers": "localhost:9092",
|
||||
"Topic": "blog",
|
||||
"GroupId": "blog-consumer",
|
||||
"NumPartitions": 3 //主题分区数量
|
||||
"TranAOP": {
|
||||
"Enabled": true
|
||||
},
|
||||
"EventBus": {
|
||||
"Enabled": false,
|
||||
"SubscriptionClientName": "Blog.Core"
|
||||
},
|
||||
"AppSettings": {
|
||||
"RedisCachingAOP": {
|
||||
"Enabled": false
|
||||
},
|
||||
"MemoryCachingAOP": {
|
||||
"Enabled": true
|
||||
},
|
||||
"LogAOP": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"TranAOP": {
|
||||
"Enabled": true
|
||||
},
|
||||
"SqlAOP": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToConsole": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"Date": "2018-08-28",
|
||||
"SeedDBEnabled": true, //只生成表结构
|
||||
"SeedDBDataEnabled": true, //生成表,并初始化数据
|
||||
"Author": "Blog.Core",
|
||||
"SvcName": "", // /svc/blog
|
||||
"UseLoadTest": false
|
||||
"SqlAOP": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": true
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToConsole": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"Date": "2018-08-28",
|
||||
"SeedDBEnabled": true, //只生成表结构
|
||||
"SeedDBDataEnabled": true, //生成表,并初始化数据
|
||||
"Author": "Blog.Core",
|
||||
"SvcName": "", // /svc/blog
|
||||
"UseLoadTest": false
|
||||
},
|
||||
|
||||
// 请配置MainDB为你想要的主库的ConnId值,并设置对应的Enabled为true;
|
||||
// *** 单库操作,把 MutiDBEnabled 设为false ***;
|
||||
// *** 多库操作,把 MutiDBEnabled 设为true,其他的从库Enabled也为true **;
|
||||
// 具体配置看视频:https://www.bilibili.com/video/BV1BJ411B7mn?p=6
|
||||
|
||||
"MainDB": "WMBLOG_SQLITE", //当前项目的主库,所对应的连接字符串的Enabled必须为true
|
||||
"MutiDBEnabled": false, //是否开启多库模式
|
||||
"CQRSEnabled": false, //是否开启读写分离模式,必须是单库模式,且数据库类型一致,比如都是SqlServer
|
||||
"DBS": [
|
||||
/*
|
||||
// 请配置MainDB为你想要的主库的ConnId值,并设置对应的Enabled为true;
|
||||
// *** 单库操作,把 MutiDBEnabled 设为false ***;
|
||||
// *** 多库操作,把 MutiDBEnabled 设为true,其他的从库Enabled也为true **;
|
||||
// 具体配置看视频:https://www.bilibili.com/video/BV1BJ411B7mn?p=6
|
||||
//Log:日志库;
|
||||
"MainDB": "WMBLOG_SQLITE", //当前项目的主库,所对应的连接字符串的Enabled必须为true
|
||||
"MutiDBEnabled": true, //是否开启多库模式
|
||||
"CQRSEnabled": false, //是否开启读写分离模式,必须是单库模式,且数据库类型一致,比如都是SqlServer
|
||||
"DBS": [
|
||||
/*
|
||||
对应下边的 DBType
|
||||
MySql = 0,
|
||||
SqlServer = 1,
|
||||
|
@ -102,225 +96,232 @@
|
|||
Dm = 5,//达梦
|
||||
Kdbndp = 6,//人大金仓
|
||||
*/
|
||||
{
|
||||
"ConnId": "WMBLOG_SQLITE",
|
||||
"DBType": 2,
|
||||
"Enabled": true,
|
||||
"HitRate": 50, // 值越大,优先级越高
|
||||
"Connection": "WMBlog.db" //sqlite只写数据库名就行
|
||||
},
|
||||
{
|
||||
"ConnId": "WMBLOG_MSSQL_1",
|
||||
"DBType": 1,
|
||||
"Enabled": false,
|
||||
"HitRate": 40,
|
||||
"Connection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_1;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
|
||||
"ProviderName": "System.Data.SqlClient"
|
||||
},
|
||||
{
|
||||
"ConnId": "WMBLOG_MSSQL_2",
|
||||
"DBType": 1,
|
||||
"Enabled": false,
|
||||
"HitRate": 30,
|
||||
"Connection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_2;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
|
||||
"ProviderName": "System.Data.SqlClient"
|
||||
},
|
||||
{
|
||||
"ConnId": "WMBLOG_MYSQL",
|
||||
"DBType": 0,
|
||||
"Enabled": false,
|
||||
"HitRate": 20,
|
||||
"Connection": "server=localhost;Database=blog;Uid=root;Pwd=root;Port=3306;Allow User Variables=True;"
|
||||
},
|
||||
{
|
||||
"ConnId": "WMBLOG_MYSQL_2",
|
||||
"DBType": 0,
|
||||
"Enabled": false,
|
||||
"HitRate": 20,
|
||||
"Connection": "server=localhost;Database=blogcore001;Uid=root;Pwd=root;Port=3306;Allow User Variables=True;"
|
||||
},
|
||||
{
|
||||
"ConnId": "WMBLOG_ORACLE",
|
||||
"DBType": 3,
|
||||
"Enabled": false,
|
||||
"HitRate": 10,
|
||||
"Connection": "Data Source=127.0.0.1/ops;User ID=OPS;Password=123456;Persist Security Info=True;Connection Timeout=60;"
|
||||
},
|
||||
{
|
||||
"ConnId": "WMBLOG_DM",
|
||||
"DBType": 5,
|
||||
"Enabled": false,
|
||||
"HitRate": 10,
|
||||
"Connection": "PORT=5236;DATABASE=DAMENG;HOST=localhost;PASSWORD=SYSDBA;USER ID=SYSDBA;"
|
||||
},
|
||||
{
|
||||
"ConnId": "WMBLOG_KDBNDP",
|
||||
"DBType": 6,
|
||||
"Enabled": false,
|
||||
"HitRate": 10,
|
||||
"Connection": "Server=127.0.0.1;Port=54321;UID=SYSTEM;PWD=system;database=SQLSUGAR4XTEST1;"
|
||||
}
|
||||
],
|
||||
"Audience": {
|
||||
"Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", //不要太短,16位+
|
||||
"SecretFile": "C:\\my-file\\blog.core.audience.secret.txt", //安全。内容就是Secret
|
||||
"Issuer": "Blog.Core",
|
||||
"Audience": "wr"
|
||||
{
|
||||
"ConnId": "WMBLOG_SQLITE",
|
||||
"DBType": 2,
|
||||
"Enabled": true,
|
||||
"HitRate": 50, // 值越大,优先级越高
|
||||
"Connection": "WMBlog.db" //sqlite只写数据库名就行
|
||||
},
|
||||
"Mongo": {
|
||||
"ConnectionString": "mongodb://nosql.data",
|
||||
"Database": "BlogCoreDb"
|
||||
{
|
||||
"ConnId": "Log",
|
||||
"DBType": 2,
|
||||
"Enabled": true,
|
||||
"HitRate": 50, // 值越大,优先级越高
|
||||
"Connection": "WMBlogLog.db" //sqlite只写数据库名就行
|
||||
},
|
||||
"Startup": {
|
||||
"Domain": "http://localhost:9291",
|
||||
"Cors": {
|
||||
"PolicyName": "CorsIpAccess", //策略名称
|
||||
"EnableAllIPs": false, //当为true时,开放所有IP均可访问。
|
||||
// 支持多个域名端口,注意端口号后不要带/斜杆:比如localhost:8000/,是错的
|
||||
// 注意,http://127.0.0.1:1818 和 http://localhost:1818 是不一样的
|
||||
"IPs": "http://127.0.0.1:2364,http://localhost:2364,http://127.0.0.1:6688,http://localhost:6688"
|
||||
},
|
||||
"AppConfigAlert": {
|
||||
"Enabled": true
|
||||
},
|
||||
"ApiName": "Blog.Core",
|
||||
"IdentityServer4": {
|
||||
"Enabled": false, // 这里默认是false,表示使用jwt,如果设置为true,则表示系统使用Ids4模式
|
||||
"AuthorizationUrl": "http://localhost:5004", // 认证中心域名
|
||||
"ApiName": "blog.core.api" // 资源服务器
|
||||
},
|
||||
"Authing": {
|
||||
"Enabled": false,
|
||||
"Issuer": "https://uldr24esx31h-demo.authing.cn/oidc",
|
||||
"Audience": "63d51c4205c2849803be5178",
|
||||
"JwksUri": "https://uldr24esx31h-demo.authing.cn/oidc/.well-known/jwks.json"
|
||||
},
|
||||
"RedisMq": {
|
||||
"Enabled": false //redis 消息队列
|
||||
},
|
||||
"MiniProfiler": {
|
||||
"Enabled": false //性能分析开启
|
||||
},
|
||||
"Nacos": {
|
||||
"Enabled": false //Nacos注册中心
|
||||
}
|
||||
{
|
||||
"ConnId": "WMBLOG_MSSQL_1",
|
||||
"DBType": 1,
|
||||
"Enabled": false,
|
||||
"HitRate": 40,
|
||||
"Connection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_1;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
|
||||
"ProviderName": "System.Data.SqlClient"
|
||||
},
|
||||
"Middleware": {
|
||||
"RequestResponseLog": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"IPLog": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"RecordAccessLogs": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": true
|
||||
},
|
||||
"IgnoreApis": "/api/permission/getnavigationbar,/api/monitor/getids4users,/api/monitor/getaccesslogs,/api/monitor/server,/api/monitor/getactiveusers,/api/monitor/server,"
|
||||
},
|
||||
"SignalR": {
|
||||
"Enabled": false
|
||||
},
|
||||
"SignalRSendLog": {
|
||||
"Enabled": false
|
||||
},
|
||||
"QuartzNetJob": {
|
||||
"Enabled": true
|
||||
},
|
||||
"Consul": {
|
||||
"Enabled": false
|
||||
},
|
||||
"IpRateLimit": {
|
||||
"Enabled": true
|
||||
}
|
||||
{
|
||||
"ConnId": "WMBLOG_MSSQL_2",
|
||||
"DBType": 1,
|
||||
"Enabled": false,
|
||||
"HitRate": 30,
|
||||
"Connection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_2;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
|
||||
"ProviderName": "System.Data.SqlClient"
|
||||
},
|
||||
"IpRateLimiting": {
|
||||
"EnableEndpointRateLimiting": true, //False: globally executed, true: executed for each
|
||||
"StackBlockedRequests": false, //False: Number of rejections should be recorded on another counter
|
||||
"RealIpHeader": "X-Real-IP",
|
||||
"ClientIdHeader": "X-ClientId",
|
||||
"IpWhitelist": [], //白名单
|
||||
"EndpointWhitelist": [ "get:/api/xxx", "*:/api/yyy" ],
|
||||
"ClientWhitelist": [ "dev-client-1", "dev-client-2" ],
|
||||
"QuotaExceededResponse": {
|
||||
"Content": "{{\"status\":429,\"msg\":\"访问过于频繁,请稍后重试\",\"success\":false}}",
|
||||
"ContentType": "application/json",
|
||||
"StatusCode": 429
|
||||
},
|
||||
"HttpStatusCode": 429, //返回状态码
|
||||
"GeneralRules": [ //api规则,结尾一定要带*
|
||||
{
|
||||
"Endpoint": "*:/api/blog*",
|
||||
"Period": "1m",
|
||||
"Limit": 20
|
||||
},
|
||||
{
|
||||
"Endpoint": "*/api/*",
|
||||
"Period": "1s",
|
||||
"Limit": 3
|
||||
},
|
||||
{
|
||||
"Endpoint": "*/api/*",
|
||||
"Period": "1m",
|
||||
"Limit": 30
|
||||
},
|
||||
{
|
||||
"Endpoint": "*/api/*",
|
||||
"Period": "12h",
|
||||
"Limit": 500
|
||||
}
|
||||
]
|
||||
|
||||
{
|
||||
"ConnId": "WMBLOG_MYSQL",
|
||||
"DBType": 0,
|
||||
"Enabled": false,
|
||||
"HitRate": 20,
|
||||
"Connection": "server=localhost;Database=blog;Uid=root;Pwd=root;Port=3306;Allow User Variables=True;"
|
||||
},
|
||||
"ConsulSetting": {
|
||||
"ServiceName": "BlogCoreService",
|
||||
"ServiceIP": "localhost",
|
||||
"ServicePort": "9291",
|
||||
"ServiceHealthCheck": "/healthcheck",
|
||||
"ConsulAddress": "http://localhost:8500"
|
||||
{
|
||||
"ConnId": "WMBLOG_MYSQL_2",
|
||||
"DBType": 0,
|
||||
"Enabled": false,
|
||||
"HitRate": 20,
|
||||
"Connection": "server=localhost;Database=blogcore001;Uid=root;Pwd=root;Port=3306;Allow User Variables=True;"
|
||||
},
|
||||
"PayInfo": { //建行聚合支付信息
|
||||
"MERCHANTID": "", //商户号
|
||||
"POSID": "", //柜台号
|
||||
"BRANCHID": "", //分行号
|
||||
"pubKey": "", //公钥
|
||||
"USER_ID": "", //操作员号
|
||||
"PASSWORD": "", //密码
|
||||
"OutAddress": "http://127.0.0.1:12345" //外联地址
|
||||
{
|
||||
"ConnId": "WMBLOG_ORACLE",
|
||||
"DBType": 3,
|
||||
"Enabled": false,
|
||||
"HitRate": 10,
|
||||
"Connection": "Data Source=127.0.0.1/ops;User ID=OPS;Password=123456;Persist Security Info=True;Connection Timeout=60;"
|
||||
},
|
||||
"nacos": {
|
||||
"ServerAddresses": [ "http://localhost:8848" ], // nacos 连接地址
|
||||
"DefaultTimeOut": 15000, // 默认超时时间
|
||||
"Namespace": "public", // 命名空间
|
||||
"ListenInterval": 10000, // 监听的频率
|
||||
"ServiceName": "blog.Core.Api", // 服务名
|
||||
"Port": "9291", // 服务端口号
|
||||
"RegisterEnabled": true // 是否直接注册nacos
|
||||
{
|
||||
"ConnId": "WMBLOG_DM",
|
||||
"DBType": 5,
|
||||
"Enabled": false,
|
||||
"HitRate": 10,
|
||||
"Connection": "PORT=5236;DATABASE=DAMENG;HOST=localhost;PASSWORD=SYSDBA;USER ID=SYSDBA;"
|
||||
},
|
||||
"LogFiedOutPutConfigs": {
|
||||
"tcpAddressHost": "", // 输出elk的tcp连接地址
|
||||
"tcpAddressPort": 0, // 输出elk的tcp端口号
|
||||
"ConfigsInfo": [ // 配置的输出elk节点内容 常用语动态标识
|
||||
{
|
||||
"FiedName": "applicationName",
|
||||
"FiedValue": "Blog.Core.Api"
|
||||
}
|
||||
]
|
||||
{
|
||||
"ConnId": "WMBLOG_KDBNDP",
|
||||
"DBType": 6,
|
||||
"Enabled": false,
|
||||
"HitRate": 10,
|
||||
"Connection": "Server=127.0.0.1;Port=54321;UID=SYSTEM;PWD=system;database=SQLSUGAR4XTEST1;"
|
||||
}
|
||||
],
|
||||
"Audience": {
|
||||
"Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", //不要太短,16位+
|
||||
"SecretFile": "C:\\my-file\\blog.core.audience.secret.txt", //安全。内容就是Secret
|
||||
"Issuer": "Blog.Core",
|
||||
"Audience": "wr"
|
||||
},
|
||||
"Mongo": {
|
||||
"ConnectionString": "mongodb://nosql.data",
|
||||
"Database": "BlogCoreDb"
|
||||
},
|
||||
"Startup": {
|
||||
"Domain": "http://localhost:9291",
|
||||
"Cors": {
|
||||
"PolicyName": "CorsIpAccess", //策略名称
|
||||
"EnableAllIPs": false, //当为true时,开放所有IP均可访问。
|
||||
// 支持多个域名端口,注意端口号后不要带/斜杆:比如localhost:8000/,是错的
|
||||
// 注意,http://127.0.0.1:1818 和 http://localhost:1818 是不一样的
|
||||
"IPs": "http://127.0.0.1:2364,http://localhost:2364,http://127.0.0.1:6688,http://localhost:6688"
|
||||
},
|
||||
"AppConfigAlert": {
|
||||
"Enabled": true
|
||||
},
|
||||
"ApiName": "Blog.Core",
|
||||
"IdentityServer4": {
|
||||
"Enabled": false, // 这里默认是false,表示使用jwt,如果设置为true,则表示系统使用Ids4模式
|
||||
"AuthorizationUrl": "http://localhost:5004", // 认证中心域名
|
||||
"ApiName": "blog.core.api" // 资源服务器
|
||||
},
|
||||
"Authing": {
|
||||
"Enabled": false,
|
||||
"Issuer": "https://uldr24esx31h-demo.authing.cn/oidc",
|
||||
"Audience": "63d51c4205c2849803be5178",
|
||||
"JwksUri": "https://uldr24esx31h-demo.authing.cn/oidc/.well-known/jwks.json"
|
||||
},
|
||||
"RedisMq": {
|
||||
"Enabled": false //redis 消息队列
|
||||
},
|
||||
"MiniProfiler": {
|
||||
"Enabled": false //性能分析开启
|
||||
},
|
||||
"Nacos": {
|
||||
"Enabled": false //Nacos注册中心
|
||||
}
|
||||
},
|
||||
"Middleware": {
|
||||
"RequestResponseLog": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"IPLog": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"RecordAccessLogs": {
|
||||
"Enabled": true,
|
||||
"LogToFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"LogToDB": {
|
||||
"Enabled": true
|
||||
},
|
||||
"IgnoreApis": "/api/permission/getnavigationbar,/api/monitor/getids4users,/api/monitor/getaccesslogs,/api/monitor/server,/api/monitor/getactiveusers,/api/monitor/server,"
|
||||
},
|
||||
"SignalR": {
|
||||
"Enabled": false
|
||||
},
|
||||
"SignalRSendLog": {
|
||||
"Enabled": false
|
||||
},
|
||||
"QuartzNetJob": {
|
||||
"Enabled": true
|
||||
},
|
||||
"Consul": {
|
||||
"Enabled": false
|
||||
},
|
||||
"IpRateLimit": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"IpRateLimiting": {
|
||||
"EnableEndpointRateLimiting": true, //False: globally executed, true: executed for each
|
||||
"StackBlockedRequests": false, //False: Number of rejections should be recorded on another counter
|
||||
"RealIpHeader": "X-Real-IP",
|
||||
"ClientIdHeader": "X-ClientId",
|
||||
"IpWhitelist": [], //白名单
|
||||
"EndpointWhitelist": [ "get:/api/xxx", "*:/api/yyy" ],
|
||||
"ClientWhitelist": [ "dev-client-1", "dev-client-2" ],
|
||||
"QuotaExceededResponse": {
|
||||
"Content": "{{\"status\":429,\"msg\":\"访问过于频繁,请稍后重试\",\"success\":false}}",
|
||||
"ContentType": "application/json",
|
||||
"StatusCode": 429
|
||||
},
|
||||
"HttpStatusCode": 429, //返回状态码
|
||||
"GeneralRules": [ //api规则,结尾一定要带*
|
||||
{
|
||||
"Endpoint": "*:/api/blog*",
|
||||
"Period": "1m",
|
||||
"Limit": 20
|
||||
},
|
||||
{
|
||||
"Endpoint": "*/api/*",
|
||||
"Period": "1s",
|
||||
"Limit": 3
|
||||
},
|
||||
{
|
||||
"Endpoint": "*/api/*",
|
||||
"Period": "1m",
|
||||
"Limit": 30
|
||||
},
|
||||
{
|
||||
"Endpoint": "*/api/*",
|
||||
"Period": "12h",
|
||||
"Limit": 500
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
"ConsulSetting": {
|
||||
"ServiceName": "BlogCoreService",
|
||||
"ServiceIP": "localhost",
|
||||
"ServicePort": "9291",
|
||||
"ServiceHealthCheck": "/healthcheck",
|
||||
"ConsulAddress": "http://localhost:8500"
|
||||
},
|
||||
"PayInfo": { //建行聚合支付信息
|
||||
"MERCHANTID": "", //商户号
|
||||
"POSID": "", //柜台号
|
||||
"BRANCHID": "", //分行号
|
||||
"pubKey": "", //公钥
|
||||
"USER_ID": "", //操作员号
|
||||
"PASSWORD": "", //密码
|
||||
"OutAddress": "http://127.0.0.1:12345" //外联地址
|
||||
},
|
||||
"nacos": {
|
||||
"ServerAddresses": [ "http://localhost:8848" ], // nacos 连接地址
|
||||
"DefaultTimeOut": 15000, // 默认超时时间
|
||||
"Namespace": "public", // 命名空间
|
||||
"ListenInterval": 10000, // 监听的频率
|
||||
"ServiceName": "blog.Core.Api", // 服务名
|
||||
"Port": "9291", // 服务端口号
|
||||
"RegisterEnabled": true // 是否直接注册nacos
|
||||
},
|
||||
"LogFiedOutPutConfigs": {
|
||||
"tcpAddressHost": "", // 输出elk的tcp连接地址
|
||||
"tcpAddressPort": 0, // 输出elk的tcp端口号
|
||||
"ConfigsInfo": [ // 配置的输出elk节点内容 常用语动态标识
|
||||
{
|
||||
"FiedName": "applicationName",
|
||||
"FiedValue": "Blog.Core.Api"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
"Logging": {
|
||||
"Level": "Information",
|
||||
"FilePath": "Log/skyapm-{Date}.log"
|
||||
"FilePath": "Logs/Skyapm/skyapm-{Date}.log"
|
||||
},
|
||||
"Transport": {
|
||||
"Interval": 3000,
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
using Blog.Core.Common.Core;
|
||||
using Blog.Core.Common.HttpContextUser;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Blog.Core.Common;
|
||||
|
||||
public class App
|
||||
{
|
||||
public static IServiceProvider RootServices => InternalApp.RootServices ;
|
||||
public static IServiceProvider RootServices => InternalApp.RootServices;
|
||||
|
||||
/// <summary>获取Web主机环境,如,是否是开发环境,生产环境等</summary>
|
||||
public static IWebHostEnvironment WebHostEnvironment => InternalApp.WebHostEnvironment;
|
||||
|
||||
/// <summary>获取泛型主机环境,如,是否是开发环境,生产环境等</summary>
|
||||
public static IHostEnvironment HostEnvironment => InternalApp.HostEnvironment;
|
||||
|
||||
/// <summary>
|
||||
/// 获取请求上下文
|
||||
|
@ -16,4 +26,55 @@ public class App
|
|||
public static HttpContext HttpContext => RootServices?.GetService<IHttpContextAccessor>()?.HttpContext;
|
||||
|
||||
public static IUser User => HttpContext == null ? null : RootServices?.GetService<IUser>();
|
||||
|
||||
/// <summary>解析服务提供器</summary>
|
||||
/// <param name="serviceType"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceProvider GetServiceProvider(Type serviceType, bool mustBuild = false)
|
||||
{
|
||||
if (App.HostEnvironment == null || App.RootServices != null &&
|
||||
InternalApp.InternalServices
|
||||
.Where((u => u.ServiceType == (serviceType.IsGenericType ? serviceType.GetGenericTypeDefinition() : serviceType)))
|
||||
.Any((u => u.Lifetime == ServiceLifetime.Singleton)))
|
||||
return App.RootServices;
|
||||
HttpContext httpContext = App.HttpContext;
|
||||
if (httpContext?.RequestServices != null)
|
||||
return httpContext.RequestServices;
|
||||
if (App.RootServices != null)
|
||||
{
|
||||
IServiceScope scope = App.RootServices.CreateScope();
|
||||
return scope.ServiceProvider;
|
||||
}
|
||||
|
||||
if (mustBuild)
|
||||
{
|
||||
throw new ApplicationException("当前不可用,必须要等到 WebApplication Build后");
|
||||
}
|
||||
|
||||
ServiceProvider serviceProvider = InternalApp.InternalServices.BuildServiceProvider();
|
||||
return serviceProvider;
|
||||
}
|
||||
|
||||
|
||||
public static TService GetService<TService>(bool mustBuild = true) where TService : class => App.GetService(typeof(TService), null, mustBuild) as TService;
|
||||
|
||||
/// <summary>获取请求生存周期的服务</summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <param name="serviceProvider"></param>
|
||||
/// <param name="mustBuild"></param>
|
||||
/// <returns></returns>
|
||||
public static TService GetService<TService>(IServiceProvider serviceProvider, bool mustBuild = true) where TService : class => App.GetService(typeof(TService), serviceProvider, mustBuild) as TService;
|
||||
|
||||
/// <summary>获取请求生存周期的服务</summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="serviceProvider"></param>
|
||||
/// <param name="mustBuild"></param>
|
||||
/// <returns></returns>
|
||||
public static object GetService(Type type, IServiceProvider serviceProvider = null, bool mustBuild = true) => (serviceProvider ?? App.GetServiceProvider(type, mustBuild)).GetService(type);
|
||||
|
||||
public static TOptions GetOptions<TOptions>(IServiceProvider serviceProvider = null) where TOptions : class, new()
|
||||
{
|
||||
IOptions<TOptions> service = App.GetService<IOptions<TOptions>>(serviceProvider ?? App.RootServices, false);
|
||||
return service?.Value;
|
||||
}
|
||||
}
|
|
@ -18,20 +18,23 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Magicodes.IE.Excel" Version="2.6.4" />
|
||||
<PackageReference Include="InitQ" Version="1.0.0.12" />
|
||||
<PackageReference Include="log4net" Version="2.0.15" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||
<PackageReference Include="MiniProfiler.Shared" Version="4.2.22" />
|
||||
<PackageReference Include="PinYinConverterCore" Version="1.0.2" />
|
||||
<PackageReference Include="RestSharp" Version="108.0.1" />
|
||||
<PackageReference Include="RSAExtensions" Version="1.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="8.4.1" />
|
||||
<PackageReference Include="Serilog.Expressions" Version="3.4.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.6.48" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.22.1" />
|
||||
|
||||
<PackageReference Include="Serilog" Version="2.11.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.1-dev-00771" />
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="6.1.0" />
|
||||
<PackageReference Include="WebApiClient.Extensions.DependencyInjection" Version="2.0.3" />
|
||||
<PackageReference Include="WebApiClient.JIT" Version="1.1.4" />
|
||||
|
||||
|
@ -45,6 +48,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Folder Include="Core\" />
|
||||
<Folder Include="Const\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
9
Blog.Core.Common/Const/SqlSugarConst.cs
Normal file
9
Blog.Core.Common/Const/SqlSugarConst.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Blog.Core.Common.Const;
|
||||
|
||||
public class SqlSugarConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认Log数据库标识
|
||||
/// </summary>
|
||||
public const string LogConfigId = "Log";
|
||||
}
|
|
@ -1,17 +1,34 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace Blog.Core.Common.Core;
|
||||
|
||||
public static class InternalApp
|
||||
{
|
||||
public static IServiceCollection InternalServices;
|
||||
|
||||
/// <summary>根服务</summary>
|
||||
public static IServiceProvider RootServices;
|
||||
|
||||
public static void ConfigureApplication(this WebApplication app)
|
||||
{
|
||||
app.Lifetime.ApplicationStarted.Register(() => { InternalApp.RootServices = app.Services; });
|
||||
/// <summary>获取Web主机环境</summary>
|
||||
public static IWebHostEnvironment WebHostEnvironment;
|
||||
|
||||
app.Lifetime.ApplicationStopped.Register(() => { InternalApp.RootServices = null; });
|
||||
/// <summary>获取泛型主机环境</summary>
|
||||
public static IHostEnvironment HostEnvironment;
|
||||
|
||||
public static void ConfigureApplication(this WebApplicationBuilder wab)
|
||||
{
|
||||
HostEnvironment = wab.Environment;
|
||||
WebHostEnvironment = wab.Environment;
|
||||
InternalServices = wab.Services;
|
||||
}
|
||||
|
||||
|
||||
public static void ConfigureApplication(this IHost app)
|
||||
{
|
||||
RootServices = app.Services;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,40 @@
|
|||
using Blog.Core.Model.Models.RootTkey;
|
||||
using Blog.Core.Common.LogHelper;
|
||||
using Blog.Core.Model.Models.RootTkey;
|
||||
using Blog.Core.Model.Tenants;
|
||||
using SqlSugar;
|
||||
using StackExchange.Profiling;
|
||||
using System;
|
||||
using Serilog;
|
||||
|
||||
namespace Blog.Core.Common.DB.Aop;
|
||||
|
||||
public static class SqlSugarAop
|
||||
{
|
||||
public static void OnLogExecuting(ISqlSugarClient sqlSugarScopeProvider, string sql, SugarParameter[] p, ConnectionConfig config)
|
||||
{
|
||||
try
|
||||
{
|
||||
MiniProfiler.Current.CustomTiming($"ConnId:[{config.ConfigId}] SQL:", GetParas(p) + "【SQL语句】:" + sql);
|
||||
|
||||
if (!AppSettings.app(new string[] { "AppSettings", "SqlAOP", "Enabled" }).ObjToBool()) return;
|
||||
|
||||
if (AppSettings.app(new string[] { "AppSettings", "SqlAOP", "LogToConsole", "Enabled" }).ObjToBool() ||
|
||||
AppSettings.app(new string[] { "AppSettings", "SqlAOP", "LogToFile", "Enabled" }).ObjToBool() ||
|
||||
AppSettings.app(new string[] { "AppSettings", "SqlAOP", "LogToDB", "Enabled" }).ObjToBool())
|
||||
{
|
||||
using (LogContextExtension.Create.SqlAopPushProperty(sqlSugarScopeProvider))
|
||||
{
|
||||
Log.Information("------------------ \r\n ConnId:[{ConnId}]【SQL语句】: \r\n {Sql}",
|
||||
config.ConfigId, UtilMethods.GetSqlString(config.DbType, sql, p));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error("Error occured OnLogExcuting:" + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DataExecuting(object oldValue, DataFilterModel entityInfo)
|
||||
{
|
||||
if (entityInfo.EntityValue is BaseEntity root)
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace Blog.Core.Common.DB
|
|||
* 目前是多库操作,默认加载的是appsettings.json设置为true的第一个db连接。
|
||||
*/
|
||||
public static (List<MutiDBOperate> allDbs, List<MutiDBOperate> slaveDbs) MutiConnectionString => MutiInitConn();
|
||||
public static ConnectionConfig LogConfig; //日志库
|
||||
|
||||
private static string DifDBConnOfSecurity(params string[] conn)
|
||||
{
|
||||
|
@ -107,8 +108,6 @@ namespace Blog.Core.Common.DB
|
|||
|
||||
return mutiDBOperate;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Blog.Core.Common.Helper
|
||||
|
@ -8,9 +9,8 @@ namespace Blog.Core.Common.Helper
|
|||
/// </summary>
|
||||
public static class RecursionHelper
|
||||
{
|
||||
public static void LoopToAppendChildren(List<PermissionTree> all, PermissionTree curItem, int pid, bool needbtn)
|
||||
public static void LoopToAppendChildren(List<PermissionTree> all, PermissionTree curItem, long pid, bool needbtn)
|
||||
{
|
||||
|
||||
var subItems = all.Where(ee => ee.Pid == curItem.value).ToList();
|
||||
|
||||
var btnItems = subItems.Where(ss => ss.isbtn == true).ToList();
|
||||
|
@ -28,6 +28,7 @@ namespace Blog.Core.Common.Helper
|
|||
{
|
||||
subItems = subItems.Where(ss => ss.isbtn == false).ToList();
|
||||
}
|
||||
|
||||
if (subItems.Count > 0)
|
||||
{
|
||||
curItem.children = new List<PermissionTree>();
|
||||
|
@ -49,14 +50,15 @@ namespace Blog.Core.Common.Helper
|
|||
{
|
||||
//subItem.disabled = true;//禁用当前节点
|
||||
}
|
||||
|
||||
LoopToAppendChildren(all, subItem, pid, needbtn);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoopToAppendChildren(List<DepartmentTree> all, DepartmentTree curItem, int pid)
|
||||
{
|
||||
|
||||
var subItems = all.Where(ee => ee.Pid == curItem.value).ToList();
|
||||
|
||||
|
||||
if (subItems.Count > 0)
|
||||
{
|
||||
curItem.children = new List<DepartmentTree>();
|
||||
|
@ -73,15 +75,14 @@ namespace Blog.Core.Common.Helper
|
|||
{
|
||||
//subItem.disabled = true;//禁用当前节点
|
||||
}
|
||||
|
||||
LoopToAppendChildren(all, subItem, pid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void LoopNaviBarAppendChildren(List<NavigationBar> all, NavigationBar curItem)
|
||||
{
|
||||
|
||||
var subItems = all.Where(ee => ee.pid == curItem.id).ToList();
|
||||
|
||||
if (subItems.Count > 0)
|
||||
|
@ -102,7 +103,6 @@ namespace Blog.Core.Common.Helper
|
|||
}
|
||||
|
||||
|
||||
|
||||
public static void LoopToAppendChildrenT<T>(List<T> all, T curItem, string parentIdName = "Pid", string idName = "value", string childrenName = "children")
|
||||
{
|
||||
var subItems = all.Where(ee => ee.GetType().GetProperty(parentIdName).GetValue(ee, null).ToString() == curItem.GetType().GetProperty(idName).GetValue(curItem, null).ToString()).ToList();
|
||||
|
@ -113,12 +113,47 @@ namespace Blog.Core.Common.Helper
|
|||
LoopToAppendChildrenT(all, subItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将父子级数据结构转换为普通list
|
||||
/// </summary>
|
||||
/// <param name="list"></param>
|
||||
/// <returns></returns>
|
||||
public static List<T> TreeToList<T>(List<T> list, Action<T, T, List<T>> action = null)
|
||||
{
|
||||
List<T> results = new List<T>();
|
||||
foreach (var item in list)
|
||||
{
|
||||
results.Add(item);
|
||||
OperationChildData(results, item, action);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归子级数据
|
||||
/// </summary>
|
||||
/// <param name="allList">树形列表数据</param>
|
||||
/// <param name="item">Item</param>
|
||||
public static void OperationChildData<T>(List<T> allList, T item, Action<T, T, List<T>> action)
|
||||
{
|
||||
dynamic dynItem = item;
|
||||
if (dynItem.Children == null) return;
|
||||
if (dynItem.Children.Count <= 0) return;
|
||||
allList.AddRange(dynItem.Children);
|
||||
foreach (var subItem in dynItem.Children)
|
||||
{
|
||||
action?.Invoke(item, subItem, allList);
|
||||
OperationChildData(allList, subItem, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PermissionTree
|
||||
{
|
||||
public int value { get; set; }
|
||||
public int Pid { get; set; }
|
||||
public long value { get; set; }
|
||||
public long Pid { get; set; }
|
||||
public string label { get; set; }
|
||||
public int order { get; set; }
|
||||
public bool isbtn { get; set; }
|
||||
|
@ -139,8 +174,8 @@ namespace Blog.Core.Common.Helper
|
|||
|
||||
public class NavigationBar
|
||||
{
|
||||
public int id { get; set; }
|
||||
public int pid { get; set; }
|
||||
public long id { get; set; }
|
||||
public long pid { get; set; }
|
||||
public int order { get; set; }
|
||||
public string name { get; set; }
|
||||
public bool IsHide { get; set; } = false;
|
||||
|
@ -158,15 +193,13 @@ namespace Blog.Core.Common.Helper
|
|||
public bool requireAuth { get; set; } = true;
|
||||
public bool NoTabPage { get; set; } = false;
|
||||
public bool keepAlive { get; set; } = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class NavigationBarPro
|
||||
{
|
||||
public int id { get; set; }
|
||||
public int parentId { get; set; }
|
||||
public long id { get; set; }
|
||||
public long parentId { get; set; }
|
||||
public int order { get; set; }
|
||||
public string name { get; set; }
|
||||
public bool IsHide { get; set; } = false;
|
||||
|
@ -184,4 +217,4 @@ namespace Blog.Core.Common.Helper
|
|||
public string icon { get; set; }
|
||||
public bool show { get; set; } = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ using System.Net.Http;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Blog.Core.Common.HttpPolly
|
||||
namespace Blog.Core.Common.Https.HttpPolly
|
||||
{
|
||||
public class HttpPollyHelper : IHttpPollyHelper
|
||||
{
|
||||
|
@ -35,7 +35,7 @@ namespace Blog.Core.Common.HttpPolly
|
|||
|
||||
var stringContent = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");
|
||||
var response = await client.PostAsync(url, stringContent);
|
||||
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
string result = await response.Content.ReadAsStringAsync();
|
||||
|
@ -72,7 +72,7 @@ namespace Blog.Core.Common.HttpPolly
|
|||
|
||||
var stringContent = new StringContent(request, Encoding.UTF8, "application/json");
|
||||
var response = await client.PostAsync(url, stringContent);
|
||||
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
string result = await response.Content.ReadAsStringAsync();
|
||||
|
@ -110,7 +110,7 @@ namespace Blog.Core.Common.HttpPolly
|
|||
|
||||
var stringContent = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");
|
||||
var response = await client.PostAsync(url, stringContent);
|
||||
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
|
@ -146,7 +146,7 @@ namespace Blog.Core.Common.HttpPolly
|
|||
|
||||
var stringContent = new StringContent(request, Encoding.UTF8, "application/json");
|
||||
var response = await client.PostAsync(url, stringContent);
|
||||
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
|
@ -182,7 +182,7 @@ namespace Blog.Core.Common.HttpPolly
|
|||
}
|
||||
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
string result = await response.Content.ReadAsStringAsync();
|
||||
|
@ -219,7 +219,7 @@ namespace Blog.Core.Common.HttpPolly
|
|||
}
|
||||
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
return await response.Content.ReadAsStringAsync(); ;
|
||||
|
@ -256,7 +256,7 @@ namespace Blog.Core.Common.HttpPolly
|
|||
|
||||
var stringContent = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");
|
||||
var response = await client.PutAsync(url, stringContent);
|
||||
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
string result = await response.Content.ReadAsStringAsync();
|
||||
|
@ -294,7 +294,7 @@ namespace Blog.Core.Common.HttpPolly
|
|||
|
||||
var stringContent = new StringContent(request, Encoding.UTF8, "application/json");
|
||||
var response = await client.PutAsync(url, stringContent);
|
||||
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
string result = await response.Content.ReadAsStringAsync();
|
||||
|
@ -331,7 +331,7 @@ namespace Blog.Core.Common.HttpPolly
|
|||
}
|
||||
|
||||
var response = await client.DeleteAsync(url);
|
||||
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
string result = await response.Content.ReadAsStringAsync();
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Blog.Core.Common.HttpPolly
|
||||
namespace Blog.Core.Common.Https.HttpPolly
|
||||
{
|
||||
public interface IHttpPollyHelper
|
||||
{
|
83
Blog.Core.Common/Https/RequestIpUtility.cs
Normal file
83
Blog.Core.Common/Https/RequestIpUtility.cs
Normal file
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Blog.Core.Common.Https;
|
||||
|
||||
public static class RequestIpUtility
|
||||
{
|
||||
public static string GetRequestIp(this HttpContext context)
|
||||
{
|
||||
string ip = SplitCsv(GetHeaderValueAs<string>(context, "X-Forwarded-For")).FirstOrDefault();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ip))
|
||||
ip = SplitCsv(GetHeaderValueAs<string>(context, "X-Real-IP")).FirstOrDefault();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ip) && context.Connection?.RemoteIpAddress != null)
|
||||
ip = context.Connection.RemoteIpAddress.ToString();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ip))
|
||||
ip = GetHeaderValueAs<string>(context, "REMOTE_ADDR");
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
public static bool IsLocal(this HttpContext context)
|
||||
{
|
||||
return GetRequestIp(context) is "127.0.0.1" or "::1" || context.Request?.IsLocal() == true;
|
||||
}
|
||||
|
||||
|
||||
public static bool IsLocal(this HttpRequest req)
|
||||
{
|
||||
var connection = req.HttpContext.Connection;
|
||||
if (connection.RemoteIpAddress != null)
|
||||
{
|
||||
if (connection.LocalIpAddress != null)
|
||||
{
|
||||
return connection.RemoteIpAddress.Equals(connection.LocalIpAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
return IPAddress.IsLoopback(connection.RemoteIpAddress);
|
||||
}
|
||||
}
|
||||
|
||||
// for in memory TestServer or when dealing with default connection info
|
||||
if (connection.RemoteIpAddress == null && connection.LocalIpAddress == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static T GetHeaderValueAs<T>(HttpContext context, string headerName)
|
||||
{
|
||||
if (context.Request?.Headers?.TryGetValue(headerName, out var values) ?? false)
|
||||
{
|
||||
string rawValues = values.ToString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(rawValues))
|
||||
return (T) Convert.ChangeType(values.ToString(), typeof(T));
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
private static List<string> SplitCsv(string csvList)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(csvList))
|
||||
return new List<string>();
|
||||
|
||||
return csvList
|
||||
.TrimEnd(',')
|
||||
.Split(',')
|
||||
.AsEnumerable<string>()
|
||||
.Select(s => s.Trim())
|
||||
.ToList();
|
||||
}
|
||||
}
|
|
@ -83,7 +83,8 @@ namespace Blog.Core.Hubs
|
|||
//2、服务端主动向客户端发送数据,名字千万不能错
|
||||
if (AppSettings.app(new string[] { "Middleware", "SignalRSendLog", "Enabled" }).ObjToBool())
|
||||
{
|
||||
await Clients.All.ReceiveUpdate(LogLock.GetLogData());
|
||||
//TODO 主动发送错误消息
|
||||
//await Clients.All.ReceiveUpdate(LogLock.GetLogData());
|
||||
}
|
||||
|
||||
|
||||
|
|
42
Blog.Core.Common/LogHelper/LogContextExtension.cs
Normal file
42
Blog.Core.Common/LogHelper/LogContextExtension.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using Serilog.Context;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Blog.Core.Common.LogHelper;
|
||||
|
||||
public class LogContextExtension : IDisposable
|
||||
{
|
||||
private readonly Stack<IDisposable> _disposableStack = new Stack<IDisposable>();
|
||||
|
||||
public static LogContextExtension Create => new();
|
||||
|
||||
public void AddStock(IDisposable disposable)
|
||||
{
|
||||
_disposableStack.Push(disposable);
|
||||
}
|
||||
|
||||
public IDisposable SqlAopPushProperty(ISqlSugarClient db)
|
||||
{
|
||||
AddStock(LogContext.PushProperty(LogContextStatic.LogSource, LogContextStatic.AopSql));
|
||||
AddStock(LogContext.PushProperty(LogContextStatic.SqlOutToConsole,
|
||||
AppSettings.app(new string[] { "AppSettings", "SqlAOP", "LogToConsole", "Enabled" }).ObjToBool()));
|
||||
AddStock(LogContext.PushProperty(LogContextStatic.SqlOutToFile,
|
||||
AppSettings.app(new string[] { "AppSettings", "SqlAOP", "LogToFile", "Enabled" }).ObjToBool()));
|
||||
AddStock(LogContext.PushProperty(LogContextStatic.OutToDb,
|
||||
AppSettings.app(new string[] { "AppSettings", "SqlAOP", "LogToDb", "Enabled" }).ObjToBool()));
|
||||
|
||||
AddStock(LogContext.PushProperty(LogContextStatic.SugarActionType, db.SugarActionType));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
while (_disposableStack.Count > 0)
|
||||
{
|
||||
_disposableStack.Pop().Dispose();
|
||||
}
|
||||
}
|
||||
}
|
42
Blog.Core.Common/LogHelper/LogContextStatic.cs
Normal file
42
Blog.Core.Common/LogHelper/LogContextStatic.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using System.IO;
|
||||
|
||||
namespace Blog.Core.Common.LogHelper;
|
||||
|
||||
public class LogContextStatic
|
||||
{
|
||||
static LogContextStatic()
|
||||
{
|
||||
if (!Directory.Exists(BaseLogs))
|
||||
{
|
||||
Directory.CreateDirectory(BaseLogs);
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly string BaseLogs = "Logs";
|
||||
public static readonly string BasePathLogs = @"Logs";
|
||||
|
||||
public static readonly string LogSource = "LogSource";
|
||||
public static readonly string AopSql = "AopSql";
|
||||
public static readonly string SqlOutToConsole = "OutToConsole";
|
||||
public static readonly string SqlOutToFile = "SqlOutToFile";
|
||||
public static readonly string OutToDb = "OutToDb";
|
||||
public static readonly string SugarActionType = "SugarActionType";
|
||||
|
||||
public static readonly string FileMessageTemplate = "{NewLine}Date:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}LogLevel:{Level}{NewLine}Message:{Message}{NewLine}{Exception}" + new string('-', 100);
|
||||
|
||||
|
||||
public static string Combine(string path1)
|
||||
{
|
||||
return Path.Combine(BaseLogs, path1);
|
||||
}
|
||||
|
||||
public static string Combine(string path1, string path2)
|
||||
{
|
||||
return Path.Combine(BaseLogs, path1, path2);
|
||||
}
|
||||
|
||||
public static string Combine(string path1, string path2, string path3)
|
||||
{
|
||||
return Path.Combine(BaseLogs, path1, path2, path3);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using Blog.Core.Common.Helper;
|
||||
using log4net;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -7,12 +6,12 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Serilog;
|
||||
|
||||
namespace Blog.Core.Common.LogHelper
|
||||
{
|
||||
public class LogLock
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(LogLock));
|
||||
static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
|
||||
static int WritedCount = 0;
|
||||
static int FailedCount = 0;
|
||||
|
@ -53,12 +52,14 @@ namespace Blog.Core.Common.LogHelper
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (AppSettings.app(new string[] { AppSetingNodeName, AppSetingName, "Enabled" }).ObjToBool())
|
||||
{
|
||||
if (AppSettings.app(new string[] { AppSetingNodeName, AppSetingName, "LogToDB", "Enabled" }).ObjToBool())
|
||||
{
|
||||
OutSql2LogToDB(prefix, traceId, dataParas, IsHeader);
|
||||
}
|
||||
|
||||
if (AppSettings.app(new string[] { AppSetingNodeName, AppSetingName, "LogToFile", "Enabled" }).ObjToBool())
|
||||
{
|
||||
OutSql2LogToFile(prefix, traceId, dataParas, IsHeader);
|
||||
|
@ -90,6 +91,7 @@ namespace Blog.Core.Common.LogHelper
|
|||
{
|
||||
Directory.CreateDirectory(folderPath);
|
||||
}
|
||||
|
||||
//string logFilePath = Path.Combine(path, $@"{filename}.log");
|
||||
var logFilePath = FileHelper.GetAvailableFileWithPrefixOrderSize(folderPath, prefix);
|
||||
switch (prefix)
|
||||
|
@ -98,47 +100,48 @@ namespace Blog.Core.Common.LogHelper
|
|||
AOPLogInfo apiLogAopInfo = JsonConvert.DeserializeObject<AOPLogInfo>(dataParas[1]);
|
||||
//记录被拦截方法信息的日志信息
|
||||
var dataIntercept = "" +
|
||||
$"【操作时间】:{apiLogAopInfo.RequestTime}\r\n" +
|
||||
$"【当前操作用户】:{ apiLogAopInfo.OpUserName} \r\n" +
|
||||
$"【当前执行方法】:{ apiLogAopInfo.RequestMethodName} \r\n" +
|
||||
$"【携带的参数有】: {apiLogAopInfo.RequestParamsName} \r\n" +
|
||||
$"【携带的参数JSON】: {apiLogAopInfo.RequestParamsData} \r\n" +
|
||||
$"【响应时间】:{apiLogAopInfo.ResponseIntervalTime}\r\n" +
|
||||
$"【执行完成时间】:{apiLogAopInfo.ResponseTime}\r\n" +
|
||||
$"【执行完成结果】:{apiLogAopInfo.ResponseJsonData}\r\n";
|
||||
$"【操作时间】:{apiLogAopInfo.RequestTime}\r\n" +
|
||||
$"【当前操作用户】:{apiLogAopInfo.OpUserName} \r\n" +
|
||||
$"【当前执行方法】:{apiLogAopInfo.RequestMethodName} \r\n" +
|
||||
$"【携带的参数有】: {apiLogAopInfo.RequestParamsName} \r\n" +
|
||||
$"【携带的参数JSON】: {apiLogAopInfo.RequestParamsData} \r\n" +
|
||||
$"【响应时间】:{apiLogAopInfo.ResponseIntervalTime}\r\n" +
|
||||
$"【执行完成时间】:{apiLogAopInfo.ResponseTime}\r\n" +
|
||||
$"【执行完成结果】:{apiLogAopInfo.ResponseJsonData}\r\n";
|
||||
dataParas = new string[] { dataIntercept };
|
||||
break;
|
||||
case "AOPLogEx":
|
||||
AOPLogExInfo apiLogAopExInfo = JsonConvert.DeserializeObject<AOPLogExInfo>(dataParas[1]);
|
||||
var dataInterceptEx = "" +
|
||||
$"【操作时间】:{apiLogAopExInfo.ApiLogAopInfo.RequestTime}\r\n" +
|
||||
$"【当前操作用户】:{ apiLogAopExInfo.ApiLogAopInfo.OpUserName} \r\n" +
|
||||
$"【当前执行方法】:{ apiLogAopExInfo.ApiLogAopInfo.RequestMethodName} \r\n" +
|
||||
$"【携带的参数有】: {apiLogAopExInfo.ApiLogAopInfo.RequestParamsName} \r\n" +
|
||||
$"【携带的参数JSON】: {apiLogAopExInfo.ApiLogAopInfo.RequestParamsData} \r\n" +
|
||||
$"【响应时间】:{apiLogAopExInfo.ApiLogAopInfo.ResponseIntervalTime}\r\n" +
|
||||
$"【执行完成时间】:{apiLogAopExInfo.ApiLogAopInfo.ResponseTime}\r\n" +
|
||||
$"【执行完成结果】:{apiLogAopExInfo.ApiLogAopInfo.ResponseJsonData}\r\n" +
|
||||
$"【执行完成异常信息】:方法中出现异常:{apiLogAopExInfo.ExMessage}\r\n" +
|
||||
$"【执行完成异常】:方法中出现异常:{apiLogAopExInfo.InnerException}\r\n";
|
||||
$"【操作时间】:{apiLogAopExInfo.ApiLogAopInfo.RequestTime}\r\n" +
|
||||
$"【当前操作用户】:{apiLogAopExInfo.ApiLogAopInfo.OpUserName} \r\n" +
|
||||
$"【当前执行方法】:{apiLogAopExInfo.ApiLogAopInfo.RequestMethodName} \r\n" +
|
||||
$"【携带的参数有】: {apiLogAopExInfo.ApiLogAopInfo.RequestParamsName} \r\n" +
|
||||
$"【携带的参数JSON】: {apiLogAopExInfo.ApiLogAopInfo.RequestParamsData} \r\n" +
|
||||
$"【响应时间】:{apiLogAopExInfo.ApiLogAopInfo.ResponseIntervalTime}\r\n" +
|
||||
$"【执行完成时间】:{apiLogAopExInfo.ApiLogAopInfo.ResponseTime}\r\n" +
|
||||
$"【执行完成结果】:{apiLogAopExInfo.ApiLogAopInfo.ResponseJsonData}\r\n" +
|
||||
$"【执行完成异常信息】:方法中出现异常:{apiLogAopExInfo.ExMessage}\r\n" +
|
||||
$"【执行完成异常】:方法中出现异常:{apiLogAopExInfo.InnerException}\r\n";
|
||||
dataParas = new string[] { dataInterceptEx };
|
||||
break;
|
||||
}
|
||||
|
||||
var now = DateTime.Now;
|
||||
string logContent = String.Join("\r\n", dataParas);
|
||||
if (IsHeader)
|
||||
{
|
||||
logContent = (
|
||||
"--------------------------------\r\n" +
|
||||
DateTime.Now + "|\r\n" +
|
||||
String.Join("\r\n", dataParas) + "\r\n"
|
||||
);
|
||||
"--------------------------------\r\n" +
|
||||
DateTime.Now + "|\r\n" +
|
||||
String.Join("\r\n", dataParas) + "\r\n"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
logContent = (
|
||||
dataParas[1] + ",\r\n"
|
||||
);
|
||||
dataParas[1] + ",\r\n"
|
||||
);
|
||||
}
|
||||
|
||||
//if (logContent.IsNotEmptyOrNull() && logContent.Length > 500)
|
||||
|
@ -148,12 +151,12 @@ namespace Blog.Core.Common.LogHelper
|
|||
if (isWrt)
|
||||
{
|
||||
File.WriteAllText(logFilePath, logContent);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
File.AppendAllText(logFilePath, logContent);
|
||||
}
|
||||
|
||||
WritedCount++;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -170,14 +173,15 @@ namespace Blog.Core.Common.LogHelper
|
|||
LogWriteLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public static void OutSql2LogToDB(string prefix, string traceId, string[] dataParas, bool IsHeader = true)
|
||||
{
|
||||
log4net.LogicalThreadContext.Properties["LogType"] = prefix;
|
||||
log4net.LogicalThreadContext.Properties["TraceId"] = traceId;
|
||||
if (dataParas.Length >= 2)
|
||||
{
|
||||
log4net.LogicalThreadContext.Properties["DataType"] = dataParas[0];
|
||||
}
|
||||
//log4net.LogicalThreadContext.Properties["LogType"] = prefix;
|
||||
//log4net.LogicalThreadContext.Properties["TraceId"] = traceId;
|
||||
//if (dataParas.Length >= 2)
|
||||
//{
|
||||
// log4net.LogicalThreadContext.Properties["DataType"] = dataParas[0];
|
||||
//}
|
||||
|
||||
dataParas = dataParas.Skip(1).ToArray();
|
||||
|
||||
|
@ -186,32 +190,37 @@ namespace Blog.Core.Common.LogHelper
|
|||
{
|
||||
logContent = (String.Join("", dataParas));
|
||||
}
|
||||
|
||||
switch (prefix)
|
||||
{
|
||||
//DEBUG | INFO | WARN | ERROR | FATAL
|
||||
case "AOPLog":
|
||||
log.Info(logContent);
|
||||
//TODO 是否需要输出?
|
||||
//Log.Information(logContent);
|
||||
break;
|
||||
case "AOPLogEx":
|
||||
log.Error(logContent);
|
||||
Log.Error(logContent);
|
||||
break;
|
||||
case "RequestIpInfoLog":
|
||||
log.Debug(logContent);
|
||||
//TODO 是否需要Debug输出?
|
||||
//Log.Debug(logContent);
|
||||
break;
|
||||
case "RecordAccessLogs":
|
||||
log.Debug(logContent);
|
||||
//TODO 是否需要Debug输出?
|
||||
//Log.Debug(logContent);
|
||||
break;
|
||||
case "SqlLog":
|
||||
log.Info(logContent);
|
||||
Log.Information(logContent);
|
||||
break;
|
||||
case "RequestResponseLog":
|
||||
log.Debug(logContent);
|
||||
//TODO 是否需要Debug输出?
|
||||
//Log.Debug(logContent);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取文件内容
|
||||
/// </summary>
|
||||
|
@ -287,6 +296,7 @@ namespace Blog.Core.Common.LogHelper
|
|||
{
|
||||
LogWriteLock.ExitReadLock();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -315,7 +325,6 @@ namespace Blog.Core.Common.LogHelper
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return requestInfos;
|
||||
|
@ -336,16 +345,18 @@ namespace Blog.Core.Common.LogHelper
|
|||
if (!string.IsNullOrEmpty(aoplogContent))
|
||||
{
|
||||
aopLogs = aoplogContent.Split("--------------------------------")
|
||||
.Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n")
|
||||
.Select(d => new LogInfo
|
||||
{
|
||||
Datetime = d.Split("|")[0].ObjToDate(),
|
||||
Content = d.Split("|")[1]?.Replace("\r\n", "<br>"),
|
||||
LogColor = "AOP",
|
||||
}).ToList();
|
||||
.Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n")
|
||||
.Select(d => new LogInfo
|
||||
{
|
||||
Datetime = d.Split("|")[0].ObjToDate(),
|
||||
Content = d.Split("|")[1]?.Replace("\r\n", "<br>"),
|
||||
LogColor = "AOP",
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -354,17 +365,19 @@ namespace Blog.Core.Common.LogHelper
|
|||
if (!string.IsNullOrEmpty(exclogContent))
|
||||
{
|
||||
excLogs = exclogContent.Split("--------------------------------")
|
||||
.Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n")
|
||||
.Select(d => new LogInfo
|
||||
{
|
||||
Datetime = (d.Split("|")[0]).Split(',')[0].ObjToDate(),
|
||||
Content = d.Split("|")[1]?.Replace("\r\n", "<br>"),
|
||||
LogColor = "EXC",
|
||||
Import = 9,
|
||||
}).ToList();
|
||||
.Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n")
|
||||
.Select(d => new LogInfo
|
||||
{
|
||||
Datetime = (d.Split("|")[0]).Split(',')[0].ObjToDate(),
|
||||
Content = d.Split("|")[1]?.Replace("\r\n", "<br>"),
|
||||
LogColor = "EXC",
|
||||
Import = 9,
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
|
@ -374,16 +387,18 @@ namespace Blog.Core.Common.LogHelper
|
|||
if (!string.IsNullOrEmpty(sqllogContent))
|
||||
{
|
||||
sqlLogs = sqllogContent.Split("--------------------------------")
|
||||
.Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n")
|
||||
.Select(d => new LogInfo
|
||||
{
|
||||
Datetime = d.Split("|")[0].ObjToDate(),
|
||||
Content = d.Split("|")[1]?.Replace("\r\n", "<br>"),
|
||||
LogColor = "SQL",
|
||||
}).ToList();
|
||||
.Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n")
|
||||
.Select(d => new LogInfo
|
||||
{
|
||||
Datetime = d.Split("|")[0].ObjToDate(),
|
||||
Content = d.Split("|")[1]?.Replace("\r\n", "<br>"),
|
||||
LogColor = "SQL",
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
//try
|
||||
//{
|
||||
|
@ -422,14 +437,17 @@ namespace Blog.Core.Common.LogHelper
|
|||
{
|
||||
aopLogs.AddRange(excLogs);
|
||||
}
|
||||
|
||||
if (sqlLogs != null)
|
||||
{
|
||||
aopLogs.AddRange(sqlLogs);
|
||||
}
|
||||
|
||||
if (reqresLogs != null)
|
||||
{
|
||||
aopLogs.AddRange(reqresLogs);
|
||||
}
|
||||
|
||||
aopLogs = aopLogs.OrderByDescending(d => d.Import).ThenByDescending(d => d.Datetime).Take(100).ToList();
|
||||
|
||||
return aopLogs;
|
||||
|
@ -450,7 +468,8 @@ namespace Blog.Core.Common.LogHelper
|
|||
Logs = GetRequestInfo(ReadType.Prefix);
|
||||
|
||||
apiWeeks = (from n in Logs
|
||||
group n by new { n.Week, n.Url } into g
|
||||
group n by new { n.Week, n.Url }
|
||||
into g
|
||||
select new ApiWeek
|
||||
{
|
||||
week = g.Key.Week,
|
||||
|
@ -459,7 +478,6 @@ namespace Blog.Core.Common.LogHelper
|
|||
}).ToList();
|
||||
|
||||
//apiWeeks = apiWeeks.OrderByDescending(d => d.count).Take(8).ToList();
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -489,10 +507,12 @@ namespace Blog.Core.Common.LogHelper
|
|||
jsonBuilder.Append(item.count);
|
||||
jsonBuilder.Append("\",");
|
||||
}
|
||||
|
||||
if (apiweeksCurrentWeek.Count > 0)
|
||||
{
|
||||
jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
|
||||
}
|
||||
|
||||
jsonBuilder.Append("},");
|
||||
}
|
||||
|
||||
|
@ -500,6 +520,7 @@ namespace Blog.Core.Common.LogHelper
|
|||
{
|
||||
jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
|
||||
}
|
||||
|
||||
jsonBuilder.Append("]");
|
||||
|
||||
//columns.AddRange(apiWeeks.OrderByDescending(d => d.count).Take(8).Select(d => d.url).ToList());
|
||||
|
@ -521,7 +542,8 @@ namespace Blog.Core.Common.LogHelper
|
|||
Logs = GetRequestInfo(ReadType.Prefix);
|
||||
|
||||
apiDates = (from n in Logs
|
||||
group n by new { n.Date } into g
|
||||
group n by new { n.Date }
|
||||
into g
|
||||
select new ApiDate
|
||||
{
|
||||
date = g.Key.Date,
|
||||
|
@ -529,7 +551,6 @@ namespace Blog.Core.Common.LogHelper
|
|||
}).ToList();
|
||||
|
||||
apiDates = apiDates.OrderByDescending(d => d.date).Take(7).ToList();
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -552,7 +573,8 @@ namespace Blog.Core.Common.LogHelper
|
|||
|
||||
apiDates = (from n in Logs
|
||||
where n.Datetime.ObjToDate() >= DateTime.Today
|
||||
group n by new { hour = n.Datetime.ObjToDate().Hour } into g
|
||||
group n by new { hour = n.Datetime.ObjToDate().Hour }
|
||||
into g
|
||||
select new ApiDate
|
||||
{
|
||||
date = g.Key.hour.ToString("00"),
|
||||
|
@ -560,7 +582,6 @@ namespace Blog.Core.Common.LogHelper
|
|||
}).ToList();
|
||||
|
||||
apiDates = apiDates.OrderBy(d => d.date).Take(24).ToList();
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -580,14 +601,15 @@ namespace Blog.Core.Common.LogHelper
|
|||
/// 精确查找一个
|
||||
/// </summary>
|
||||
Accurate,
|
||||
|
||||
/// <summary>
|
||||
/// 指定前缀,模糊查找全部
|
||||
/// </summary>
|
||||
Prefix,
|
||||
|
||||
/// <summary>
|
||||
/// 指定前缀,最新一个文件
|
||||
/// </summary>
|
||||
PrefixLatest
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -18,10 +18,10 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="6.1.0" />
|
||||
<PackageReference Include="MiniProfiler.AspNetCore.Mvc" Version="4.2.22" />
|
||||
<PackageReference Include="NetDevPack.Security.JwtExtensions" Version="6.0.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.5" />
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Blog.Core.EventBus\Blog.Core.EventBus.csproj" />
|
||||
<ProjectReference Include="..\Blog.Core.Serilog\Blog.Core.Serilog.csproj" />
|
||||
<ProjectReference Include="..\Blog.Core.Services\Blog.Core.Services.csproj" />
|
||||
<ProjectReference Include="..\Blog.Core.Tasks\Blog.Core.Tasks.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -4,14 +4,13 @@ using System.Threading.Tasks;
|
|||
using Blog.Core.Model;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
|
||||
namespace Blog.Core.Extensions.Middlewares
|
||||
{
|
||||
public class ExceptionHandlerMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private static readonly log4net.ILog Log =
|
||||
log4net.LogManager.GetLogger(typeof(ExceptionHandlerMiddleware));
|
||||
|
||||
public ExceptionHandlerMiddleware(RequestDelegate next)
|
||||
{
|
||||
|
@ -48,7 +47,9 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
|
||||
context.Response.ContentType = "application/json";
|
||||
|
||||
await context.Response.WriteAsync(JsonConvert.SerializeObject((new ApiResponse(StatusCode.CODE500, e.Message)).MessageModel)).ConfigureAwait(false);
|
||||
await context.Response
|
||||
.WriteAsync(JsonConvert.SerializeObject(new ApiResponse(StatusCode.CODE500, e.Message).MessageModel))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
using System;
|
||||
using AspNetCoreRateLimit;
|
||||
using AspNetCoreRateLimit;
|
||||
using Blog.Core.Common;
|
||||
using log4net;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using System;
|
||||
using Serilog;
|
||||
|
||||
namespace Blog.Core.Extensions.Middlewares
|
||||
{
|
||||
|
@ -11,7 +11,6 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
/// </summary>
|
||||
public static class IpLimitMiddleware
|
||||
{
|
||||
private static readonly ILog Log = LogManager.GetLogger(typeof(IpLimitMiddleware));
|
||||
public static void UseIpLimitMiddle(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Blog.Core.Common;
|
||||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.LogHelper;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Blog.Core.Extensions.Middlewares
|
||||
{
|
||||
|
@ -19,7 +19,6 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
/// </summary>
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(IpLogMiddleware));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using Blog.Core.Common;
|
||||
using log4net;
|
||||
using Blog.Core.Common;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using System;
|
||||
using Serilog;
|
||||
|
||||
namespace Blog.Core.Extensions.Middlewares
|
||||
{
|
||||
|
@ -10,7 +10,6 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
/// </summary>
|
||||
public static class MiniProfilerMiddleware
|
||||
{
|
||||
private static readonly ILog Log = LogManager.GetLogger(typeof(MiniProfilerMiddleware));
|
||||
public static void UseMiniProfilerMiddleware(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
{
|
||||
if (AppSettings.app("Middleware", "SignalR", "Enabled").ObjToBool())
|
||||
{
|
||||
//TODO 主动发送错误消息
|
||||
await _hubContext.Clients.All.SendAsync("ReceiveUpdate", LogLock.GetLogData());
|
||||
}
|
||||
await _next(context);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Blog.Core.Common;
|
||||
using log4net;
|
||||
using Blog.Core.Common;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Serilog;
|
||||
using static Blog.Core.Extensions.CustomApiVersion;
|
||||
|
||||
namespace Blog.Core.Extensions.Middlewares
|
||||
|
@ -14,7 +14,6 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
/// </summary>
|
||||
public static class SwaggerMiddleware
|
||||
{
|
||||
private static readonly ILog Log = LogManager.GetLogger(typeof(SwaggerMiddleware));
|
||||
public static void UseSwaggerMiddle(this IApplicationBuilder app, Func<Stream> streamHtml)
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
|
@ -24,10 +23,7 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
{
|
||||
//根据版本名称倒序 遍历展示
|
||||
var apiName = AppSettings.app(new string[] { "Startup", "ApiName" });
|
||||
typeof(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version =>
|
||||
{
|
||||
c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{apiName} {version}");
|
||||
});
|
||||
typeof(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version => { c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{apiName} {version}"); });
|
||||
|
||||
c.SwaggerEndpoint($"https://petstore.swagger.io/v2/swagger.json", $"{apiName} pet");
|
||||
|
||||
|
@ -38,12 +34,13 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
Log.Error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
c.IndexStream = streamHtml;
|
||||
c.DocExpansion(DocExpansion.None); //->修改界面打开时自动折叠
|
||||
|
||||
if (Permissions.IsUseIds4)
|
||||
{
|
||||
c.OAuthClientId("blogadminjs");
|
||||
c.OAuthClientId("blogadminjs");
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,4 +49,4 @@ namespace Blog.Core.Extensions.Middlewares
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,10 +76,10 @@ namespace Blog.Core.Extensions
|
|||
var ipLogOpen = AppSettings.app(new string[] { "Middleware", "IPLog", "Enabled" }).ObjToBool();
|
||||
var recordAccessLogsOpen = AppSettings.app(new string[] { "Middleware", "RecordAccessLogs", "Enabled" }).ObjToBool();
|
||||
ConsoleHelper.WriteSuccessLine($"OPEN Log: " +
|
||||
(requestResponseLogOpen ? "RequestResponseLog √," : "") +
|
||||
(ipLogOpen ? "IPLog √," : "") +
|
||||
(recordAccessLogsOpen ? "RecordAccessLogs √," : "")
|
||||
);
|
||||
(requestResponseLogOpen ? "RequestResponseLog √," : "") +
|
||||
(ipLogOpen ? "IPLog √," : "") +
|
||||
(recordAccessLogsOpen ? "RecordAccessLogs √," : "")
|
||||
);
|
||||
|
||||
// 事务AOP
|
||||
if (!AppSettings.app(new string[] { "AppSettings", "TranAOP", "Enabled" }).ObjToBool())
|
||||
|
@ -213,7 +213,6 @@ namespace Blog.Core.Extensions
|
|||
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void AddAppTableConfigSetup(this IServiceCollection services, IHostEnvironment env)
|
||||
|
@ -222,7 +221,6 @@ namespace Blog.Core.Extensions
|
|||
|
||||
if (AppSettings.app(new string[] { "Startup", "AppConfigAlert", "Enabled" }).ObjToBool())
|
||||
{
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
|
@ -230,6 +228,7 @@ namespace Blog.Core.Extensions
|
|||
}
|
||||
|
||||
#region 程序配置
|
||||
|
||||
List<string[]> configInfos = new()
|
||||
{
|
||||
new string[] { "当前环境", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") },
|
||||
|
@ -238,7 +237,7 @@ namespace Blog.Core.Extensions
|
|||
new string[] { "RabbitMQ消息列队", AppSettings.app("RabbitMQ", "Enabled") },
|
||||
new string[] { "事件总线(必须开启消息列队)", AppSettings.app("EventBus", "Enabled") },
|
||||
new string[] { "redis消息队列", AppSettings.app("Startup", "RedisMq", "Enabled") },
|
||||
new string[] { "是否多库", AppSettings.app("MutiDBEnabled" ) },
|
||||
new string[] { "是否多库", AppSettings.app("MutiDBEnabled") },
|
||||
new string[] { "读写分离", AppSettings.app("CQRSEnabled") },
|
||||
};
|
||||
|
||||
|
@ -253,17 +252,19 @@ namespace Blog.Core.Extensions
|
|||
TableStyle = TableStyle.Alternative
|
||||
}.Writer(ConsoleColor.Blue);
|
||||
Console.WriteLine();
|
||||
|
||||
#endregion 程序配置
|
||||
|
||||
#region AOP
|
||||
|
||||
List<string[]> aopInfos = new()
|
||||
{
|
||||
{
|
||||
new string[] { "Redis缓存AOP", AppSettings.app("AppSettings", "RedisCachingAOP", "Enabled") },
|
||||
new string[] { "内存缓存AOP", AppSettings.app("AppSettings", "MemoryCachingAOP", "Enabled") },
|
||||
new string[] { "服务日志AOP", AppSettings.app("AppSettings", "LogAOP", "Enabled" ) },
|
||||
new string[] { "事务AOP", AppSettings.app("AppSettings", "TranAOP", "Enabled" ) },
|
||||
new string[] { "Sql执行AOP", AppSettings.app("AppSettings", "SqlAOP", "OutToLogFile", "Enabled" ) },
|
||||
new string[] { "Sql执行AOP控制台输出", AppSettings.app("AppSettings", "SqlAOP", "OutToConsole", "Enabled" ) },
|
||||
new string[] { "服务日志AOP", AppSettings.app("AppSettings", "LogAOP", "Enabled") },
|
||||
new string[] { "事务AOP", AppSettings.app("AppSettings", "TranAOP", "Enabled") },
|
||||
new string[] { "Sql执行AOP", AppSettings.app("AppSettings", "SqlAOP", "Enabled") },
|
||||
new string[] { "Sql执行AOP控制台输出", AppSettings.app("AppSettings", "SqlAOP", "LogToConsole", "Enabled") },
|
||||
};
|
||||
|
||||
new ConsoleTable
|
||||
|
@ -277,15 +278,17 @@ namespace Blog.Core.Extensions
|
|||
TableStyle = TableStyle.Alternative
|
||||
}.Writer(ConsoleColor.Blue);
|
||||
Console.WriteLine();
|
||||
|
||||
#endregion AOP
|
||||
|
||||
#region 中间件
|
||||
|
||||
List<string[]> MiddlewareInfos = new()
|
||||
{
|
||||
new string[] { "请求纪录中间件", AppSettings.app("Middleware", "RecordAccessLogs", "Enabled") },
|
||||
new string[] { "IP记录中间件", AppSettings.app("Middleware", "IPLog", "Enabled" ) },
|
||||
new string[] { "请求响应日志中间件", AppSettings.app("Middleware", "RequestResponseLog", "Enabled" ) },
|
||||
new string[] { "SingnalR实时发送请求数据中间件", AppSettings.app("Middleware", "SignalR", "Enabled" ) },
|
||||
new string[] { "IP记录中间件", AppSettings.app("Middleware", "IPLog", "Enabled") },
|
||||
new string[] { "请求响应日志中间件", AppSettings.app("Middleware", "RequestResponseLog", "Enabled") },
|
||||
new string[] { "SingnalR实时发送请求数据中间件", AppSettings.app("Middleware", "SignalR", "Enabled") },
|
||||
new string[] { "IP限流中间件", AppSettings.app("Middleware", "IpRateLimit", "Enabled") },
|
||||
new string[] { "性能分析中间件", AppSettings.app("Startup", "MiniProfiler", "Enabled") },
|
||||
new string[] { "Consul注册服务", AppSettings.app("Middleware", "Consul", "Enabled") },
|
||||
|
@ -302,10 +305,9 @@ namespace Blog.Core.Extensions
|
|||
TableStyle = TableStyle.Alternative
|
||||
}.Writer(ConsoleColor.Blue);
|
||||
Console.WriteLine();
|
||||
|
||||
#endregion 中间件
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,20 +6,18 @@ using Blog.Core.IRepository.Base;
|
|||
using Blog.Core.IServices.BASE;
|
||||
using Blog.Core.Model;
|
||||
using Blog.Core.Repository.Base;
|
||||
using Blog.Core.Repository.UnitOfWorks;
|
||||
using Blog.Core.Services.BASE;
|
||||
using log4net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Blog.Core.Repository.UnitOfWorks;
|
||||
using Serilog;
|
||||
|
||||
namespace Blog.Core.Extensions
|
||||
{
|
||||
public class AutofacModuleRegister : Autofac.Module
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(AutofacModuleRegister));
|
||||
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
var basePath = AppContext.BaseDirectory;
|
||||
|
@ -34,39 +32,39 @@ namespace Blog.Core.Extensions
|
|||
if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile)))
|
||||
{
|
||||
var msg = "Repository.dll和service.dll 丢失,因为项目解耦了,所以需要先F6编译,再F5运行,请检查 bin 文件夹,并拷贝。";
|
||||
log.Error(msg);
|
||||
Log.Error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
|
||||
// AOP 开关,如果想要打开指定的功能,只需要在 appsettigns.json 对应对应 true 就行。
|
||||
var cacheType = new List<Type>();
|
||||
if (AppSettings.app(new string[] {"AppSettings", "RedisCachingAOP", "Enabled"}).ObjToBool())
|
||||
if (AppSettings.app(new string[] { "AppSettings", "RedisCachingAOP", "Enabled" }).ObjToBool())
|
||||
{
|
||||
builder.RegisterType<BlogRedisCacheAOP>();
|
||||
cacheType.Add(typeof(BlogRedisCacheAOP));
|
||||
}
|
||||
|
||||
if (AppSettings.app(new string[] {"AppSettings", "MemoryCachingAOP", "Enabled"}).ObjToBool())
|
||||
if (AppSettings.app(new string[] { "AppSettings", "MemoryCachingAOP", "Enabled" }).ObjToBool())
|
||||
{
|
||||
builder.RegisterType<BlogCacheAOP>();
|
||||
cacheType.Add(typeof(BlogCacheAOP));
|
||||
}
|
||||
|
||||
if (AppSettings.app(new string[] {"AppSettings", "TranAOP", "Enabled"}).ObjToBool())
|
||||
if (AppSettings.app(new string[] { "AppSettings", "TranAOP", "Enabled" }).ObjToBool())
|
||||
{
|
||||
builder.RegisterType<BlogTranAOP>();
|
||||
cacheType.Add(typeof(BlogTranAOP));
|
||||
}
|
||||
|
||||
if (AppSettings.app(new string[] {"AppSettings", "LogAOP", "Enabled"}).ObjToBool())
|
||||
if (AppSettings.app(new string[] { "AppSettings", "LogAOP", "Enabled" }).ObjToBool())
|
||||
{
|
||||
builder.RegisterType<BlogLogAOP>();
|
||||
cacheType.Add(typeof(BlogLogAOP));
|
||||
}
|
||||
|
||||
builder.RegisterGeneric(typeof(BaseRepository<>)).As(typeof(IBaseRepository<>)).InstancePerDependency();//注册仓储
|
||||
builder.RegisterGeneric(typeof(BaseServices<>)).As(typeof(IBaseServices<>)).InstancePerDependency();//注册服务
|
||||
builder.RegisterGeneric(typeof(BaseRepository<>)).As(typeof(IBaseRepository<>)).InstancePerDependency(); //注册仓储
|
||||
builder.RegisterGeneric(typeof(BaseServices<>)).As(typeof(IBaseServices<>)).InstancePerDependency(); //注册服务
|
||||
|
||||
// 获取 Service.dll 程序集服务,并注册
|
||||
var assemblysServices = Assembly.LoadFrom(servicesDllFile);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using Blog.Core.Common.HttpPolly;
|
||||
using Blog.Core.Common.Https.HttpPolly;
|
||||
using Blog.Core.Model;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Polly;
|
||||
|
|
37
Blog.Core.Extensions/ServiceExtensions/SerilogSetup.cs
Normal file
37
Blog.Core.Extensions/ServiceExtensions/SerilogSetup.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.LogHelper;
|
||||
using Blog.Core.Serilog.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Serilog;
|
||||
using Serilog.Debugging;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Blog.Core.Extensions.ServiceExtensions;
|
||||
|
||||
public static class SerilogSetup
|
||||
{
|
||||
public static IHostBuilder AddSerilogSetup(this IHostBuilder host)
|
||||
{
|
||||
if (host == null) throw new ArgumentNullException(nameof(host));
|
||||
|
||||
var loggerConfiguration = new LoggerConfiguration()
|
||||
.ReadFrom.Configuration(AppSettings.Configuration)
|
||||
.Enrich.FromLogContext()
|
||||
//输出到控制台
|
||||
.WriteToConsole()
|
||||
//将日志保存到文件中
|
||||
.WriteToFile();
|
||||
//配置日志库
|
||||
//.WriteToLogBatching();
|
||||
|
||||
Log.Logger = loggerConfiguration.CreateLogger();
|
||||
|
||||
//Serilog 内部日志
|
||||
var file = File.CreateText(LogContextStatic.Combine($"SerilogDebug{DateTime.Now:yyyyMMdd}.txt"));
|
||||
SelfLog.Enable(TextWriter.Synchronized(file));
|
||||
|
||||
host.UseSerilog();
|
||||
return host;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.Const;
|
||||
using Blog.Core.Common.DB;
|
||||
using Blog.Core.Common.Helper;
|
||||
using Blog.Core.Common.DB.Aop;
|
||||
using Blog.Core.Common.LogHelper;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
@ -9,7 +10,6 @@ using StackExchange.Profiling;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Blog.Core.Common.DB.Aop;
|
||||
|
||||
namespace Blog.Core.Extensions
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ namespace Blog.Core.Extensions
|
|||
|
||||
BaseDBConfig.MutiConnectionString.allDbs.ForEach(m =>
|
||||
{
|
||||
listConfig.Add(new ConnectionConfig()
|
||||
var config = new ConnectionConfig()
|
||||
{
|
||||
ConfigId = m.ConnId.ObjToString().ToLower(),
|
||||
ConnectionString = m.Connection,
|
||||
|
@ -56,29 +56,6 @@ namespace Blog.Core.Extensions
|
|||
IsAutoCloseConnection = true,
|
||||
// Check out more information: https://github.com/anjoy8/Blog.Core/issues/122
|
||||
//IsShardSameThread = false,
|
||||
AopEvents = new AopEvents
|
||||
{
|
||||
OnLogExecuting = (sql, p) =>
|
||||
{
|
||||
if (AppSettings.app(new string[] { "AppSettings", "SqlAOP", "Enabled" }).ObjToBool())
|
||||
{
|
||||
if (AppSettings.app(new string[] { "AppSettings", "SqlAOP", "LogToFile", "Enabled" }).ObjToBool())
|
||||
{
|
||||
Parallel.For(0, 1, e =>
|
||||
{
|
||||
MiniProfiler.Current.CustomTiming("SQL:", GetParas(p) + "【SQL语句】:" + sql);
|
||||
//LogLock.OutSql2Log("SqlLog", new string[] { GetParas(p), "【SQL语句】:" + sql });
|
||||
LogLock.OutLogAOP("SqlLog", "", new string[] { sql.GetType().ToString(), GetParas(p), "【SQL语句】:" + sql });
|
||||
|
||||
});
|
||||
}
|
||||
if (AppSettings.app(new string[] { "AppSettings", "SqlAOP", "LogToConsole", "Enabled" }).ObjToBool())
|
||||
{
|
||||
ConsoleHelper.WriteColorLine(string.Join("\r\n", new string[] { "--------", $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} :" + GetWholeSql(p, sql) }), ConsoleColor.DarkCyan);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
MoreSettings = new ConnMoreSettings()
|
||||
{
|
||||
//IsWithNoLockQuery = true,
|
||||
|
@ -99,15 +76,29 @@ namespace Blog.Core.Extensions
|
|||
}
|
||||
},
|
||||
InitKeyType = InitKeyType.Attribute
|
||||
};
|
||||
if (SqlSugarConst.LogConfigId.Equals(m.ConnId))
|
||||
{
|
||||
BaseDBConfig.LogConfig = config;
|
||||
}
|
||||
);
|
||||
|
||||
listConfig.Add(config);
|
||||
});
|
||||
|
||||
if (BaseDBConfig.LogConfig is null)
|
||||
{
|
||||
throw new ApplicationException("未配置Log库连接");
|
||||
}
|
||||
|
||||
return new SqlSugarScope(listConfig, db =>
|
||||
{
|
||||
listConfig.ForEach(config =>
|
||||
{
|
||||
var dbProvider = db.GetConnectionScope((string)config.ConfigId);
|
||||
|
||||
// 打印SQL语句
|
||||
dbProvider.Aop.OnLogExecuting = (s, parameters) => SqlSugarAop.OnLogExecuting(dbProvider,s, parameters, config);
|
||||
|
||||
// 数据审计
|
||||
dbProvider.Aop.DataExecuting = SqlSugarAop.DataExecuting;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using Blog.Core.Common;
|
||||
using log4net;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Serilog;
|
||||
using Swashbuckle.AspNetCore.Filters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -17,10 +17,6 @@ namespace Blog.Core.Extensions
|
|||
/// </summary>
|
||||
public static class SwaggerSetup
|
||||
{
|
||||
|
||||
private static readonly ILog log =
|
||||
LogManager.GetLogger(typeof(SwaggerSetup));
|
||||
|
||||
public static void AddSwaggerSetup(this IServiceCollection services)
|
||||
{
|
||||
if (services == null) throw new ArgumentNullException(nameof(services));
|
||||
|
@ -59,7 +55,7 @@ namespace Blog.Core.Extensions
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error("Blog.Core.xml和Blog.Core.Model.xml 丢失,请检查并拷贝。\n" + ex.Message);
|
||||
Log.Error("Blog.Core.xml和Blog.Core.Model.xml 丢失,请检查并拷贝。\n" + ex.Message);
|
||||
}
|
||||
|
||||
// 开启加权小锁
|
||||
|
@ -82,12 +78,13 @@ namespace Blog.Core.Extensions
|
|||
Implicit = new OpenApiOAuthFlow
|
||||
{
|
||||
AuthorizationUrl = new Uri($"{AppSettings.app(new string[] { "Startup", "IdentityServer4", "AuthorizationUrl" })}/connect/authorize"),
|
||||
Scopes = new Dictionary<string, string> {
|
||||
Scopes = new Dictionary<string, string>
|
||||
{
|
||||
"blog.core.api","ApiResource id"
|
||||
{
|
||||
"blog.core.api", "ApiResource id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -97,14 +94,11 @@ namespace Blog.Core.Extensions
|
|||
c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
|
||||
Name = "Authorization",//jwt默认的参数名称
|
||||
In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
|
||||
Name = "Authorization", //jwt默认的参数名称
|
||||
In = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中)
|
||||
Type = SecuritySchemeType.ApiKey
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
services.AddSwaggerGenNewtonsoftSupport();
|
||||
}
|
||||
|
@ -124,11 +118,11 @@ namespace Blog.Core.Extensions
|
|||
/// V1 版本
|
||||
/// </summary>
|
||||
V1 = 1,
|
||||
|
||||
/// <summary>
|
||||
/// V2 版本
|
||||
/// </summary>
|
||||
V2 = 2,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog" Version="2.11.0" />
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
13
Blog.Core.Serilog/Blog.Core.Serilog.csproj
Normal file
13
Blog.Core.Serilog/Blog.Core.Serilog.csproj
Normal file
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Blog.Core.Common\Blog.Core.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
121
Blog.Core.Serilog/Extensions/LoggerConfigurationExtensions.cs
Normal file
121
Blog.Core.Serilog/Extensions/LoggerConfigurationExtensions.cs
Normal file
|
@ -0,0 +1,121 @@
|
|||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.LogHelper;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Filters;
|
||||
using SqlSugar;
|
||||
|
||||
namespace Blog.Core.Serilog.Extensions;
|
||||
|
||||
public static class LoggerConfigurationExtensions
|
||||
{
|
||||
public static LoggerConfiguration WriteToSqlServer(this LoggerConfiguration loggerConfiguration)
|
||||
{
|
||||
var logConnectionStrings = AppSettings.app("LogConnectionStrings");
|
||||
if (logConnectionStrings.IsNullOrEmpty()) return loggerConfiguration;
|
||||
|
||||
//输出SQL
|
||||
//loggerConfiguration = loggerConfiguration.WriteTo.Logger(lg =>
|
||||
// lg.FilterSqlLog().WriteTo.MSSqlServer(logConnectionStrings, new MSSqlServerSinkOptions()
|
||||
// {
|
||||
// TableName = "SqlLog",
|
||||
// AutoCreateSqlTable = true
|
||||
// }));
|
||||
|
||||
//输出普通日志
|
||||
//loggerConfiguration = loggerConfiguration.WriteTo.Logger(lg =>
|
||||
// lg.FilterRemoveSqlLog().Filter.ByIncludingOnly(p => p.Level >= LogEventLevel.Error)
|
||||
// .WriteTo.MSSqlServer(logConnectionStrings, new MSSqlServerSinkOptions()
|
||||
// {
|
||||
// TableName = "ErrorLog",
|
||||
// AutoCreateSqlTable = true
|
||||
// }));
|
||||
//loggerConfiguration = loggerConfiguration.WriteTo.Logger(lg =>
|
||||
// lg.FilterRemoveSqlLog().Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Warning)
|
||||
// .WriteTo.MSSqlServer(logConnectionStrings, new MSSqlServerSinkOptions()
|
||||
// {
|
||||
// TableName = "WarningLog",
|
||||
// AutoCreateSqlTable = true
|
||||
// }));
|
||||
//loggerConfiguration = loggerConfiguration.WriteTo.Logger(lg =>
|
||||
// lg.FilterRemoveSqlLog().Filter.ByIncludingOnly(p => p.Level <= LogEventLevel.Information)
|
||||
// .WriteTo.MSSqlServer(logConnectionStrings, new MSSqlServerSinkOptions()
|
||||
// {
|
||||
// TableName = "InformationLog",
|
||||
// AutoCreateSqlTable = true
|
||||
// }));
|
||||
|
||||
return loggerConfiguration;
|
||||
}
|
||||
|
||||
public static LoggerConfiguration WriteToConsole(this LoggerConfiguration loggerConfiguration)
|
||||
{
|
||||
//输出普通日志
|
||||
loggerConfiguration = loggerConfiguration.WriteTo.Logger(lg =>
|
||||
lg.FilterRemoveSqlLog().WriteTo.Console());
|
||||
|
||||
//输出SQL
|
||||
loggerConfiguration = loggerConfiguration.WriteTo.Logger(lg =>
|
||||
lg.FilterSqlLog().Filter.ByIncludingOnly(Matching.WithProperty<bool>(LogContextStatic.SqlOutToConsole, s => s))
|
||||
.WriteTo.Console());
|
||||
|
||||
return loggerConfiguration;
|
||||
}
|
||||
|
||||
public static LoggerConfiguration WriteToFile(this LoggerConfiguration loggerConfiguration)
|
||||
{
|
||||
//输出SQL
|
||||
loggerConfiguration = loggerConfiguration.WriteTo.Logger(lg =>
|
||||
lg.FilterSqlLog().Filter.ByIncludingOnly(Matching.WithProperty<bool>(LogContextStatic.SqlOutToFile, s => s))
|
||||
.WriteTo.Async(s => s.File(LogContextStatic.Combine(LogContextStatic.AopSql, @"AopSql.txt"), rollingInterval: RollingInterval.Day,
|
||||
outputTemplate: LogContextStatic.FileMessageTemplate, retainedFileCountLimit: 31)));
|
||||
//输出普通日志
|
||||
loggerConfiguration = loggerConfiguration.WriteTo.Logger(lg =>
|
||||
lg.FilterRemoveSqlLog().WriteTo.Async(s => s.File(LogContextStatic.Combine(LogContextStatic.BasePathLogs, @"Log.txt"), rollingInterval: RollingInterval.Day,
|
||||
outputTemplate: LogContextStatic.FileMessageTemplate, retainedFileCountLimit: 31)));
|
||||
return loggerConfiguration;
|
||||
}
|
||||
|
||||
public static LoggerConfiguration FilterSqlLog(this LoggerConfiguration lc)
|
||||
{
|
||||
lc = lc.Filter.ByIncludingOnly(Matching.WithProperty<string>(LogContextStatic.LogSource, s => LogContextStatic.AopSql.Equals(s)));
|
||||
return lc;
|
||||
}
|
||||
|
||||
public static IEnumerable<LogEvent> FilterSqlLog(this IEnumerable<LogEvent> batch)
|
||||
{
|
||||
return batch.Where(s => s.WithProperty<string>(LogContextStatic.LogSource, q => LogContextStatic.AopSql.Equals(q)))
|
||||
.Where(s => s.WithProperty<SugarActionType>(LogContextStatic.SugarActionType,
|
||||
q => !new[] { SugarActionType.UnKnown, SugarActionType.Query }.Contains(q)));
|
||||
}
|
||||
|
||||
public static LoggerConfiguration FilterRemoveSqlLog(this LoggerConfiguration lc)
|
||||
{
|
||||
lc = lc.Filter.ByIncludingOnly(WithProperty<string>(LogContextStatic.LogSource, s => !LogContextStatic.AopSql.Equals(s)));
|
||||
return lc;
|
||||
}
|
||||
|
||||
public static IEnumerable<LogEvent> FilterRemoveOtherLog(this IEnumerable<LogEvent> batch)
|
||||
{
|
||||
return batch.Where(s => WithProperty<string>(LogContextStatic.LogSource,
|
||||
q => !LogContextStatic.AopSql.Equals(q))(s));
|
||||
}
|
||||
|
||||
public static Func<LogEvent, bool> WithProperty<T>(string propertyName, Func<T, bool> predicate)
|
||||
{
|
||||
//如果不包含属性 也认为是true
|
||||
return e =>
|
||||
{
|
||||
if (!e.Properties.TryGetValue(propertyName, out var propertyValue)) return true;
|
||||
|
||||
return propertyValue is ScalarValue { Value: T value } && predicate(value);
|
||||
};
|
||||
}
|
||||
|
||||
public static bool WithProperty<T>(this LogEvent e, string key, Func<T, bool> predicate)
|
||||
{
|
||||
if (!e.Properties.TryGetValue(key, out var propertyValue)) return false;
|
||||
|
||||
return propertyValue is ScalarValue { Value: T value } && predicate(value);
|
||||
}
|
||||
}
|
34
Blog.Core.Serilog/Utility/SerilogRequestUtility.cs
Normal file
34
Blog.Core.Serilog/Utility/SerilogRequestUtility.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Blog.Core.Serilog.Utility;
|
||||
|
||||
public class SerilogRequestUtility
|
||||
{
|
||||
private static readonly List<string> _ignoreUrl = new()
|
||||
{
|
||||
"/job",
|
||||
};
|
||||
|
||||
private static LogEventLevel DefaultGetLevel(
|
||||
HttpContext ctx,
|
||||
double _,
|
||||
Exception? ex)
|
||||
{
|
||||
return ex is null && ctx.Response.StatusCode <= 499 ? LogEventLevel.Information : LogEventLevel.Error;
|
||||
}
|
||||
|
||||
public static LogEventLevel GetRequestLevel(HttpContext ctx, double _, Exception? ex) =>
|
||||
ex is null && ctx.Response.StatusCode <= 499 ? IgnoreRequest(ctx) : LogEventLevel.Error;
|
||||
|
||||
private static LogEventLevel IgnoreRequest(HttpContext ctx)
|
||||
{
|
||||
var path = ctx.Request.Path.Value;
|
||||
if (path.IsNullOrEmpty())
|
||||
{
|
||||
return LogEventLevel.Information;
|
||||
}
|
||||
|
||||
return _ignoreUrl.Any(s => path.StartsWith(s)) ? LogEventLevel.Verbose : LogEventLevel.Information;
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@ namespace Blog.Core.Tasks
|
|||
}
|
||||
public async Task Run(IJobExecutionContext context)
|
||||
{
|
||||
|
||||
|
||||
// 可以直接获取 JobDetail 的值
|
||||
var jobKey = context.JobDetail.Key;
|
||||
var jobId = jobKey.Name;
|
||||
|
@ -94,7 +94,7 @@ namespace Blog.Core.Tasks
|
|||
|
||||
Parallel.For(0, 1, e =>
|
||||
{
|
||||
LogLock.OutLogAOP("ACCESSTRENDLOG","",new string[] { activeUserVMs.GetType().ToString(), JsonConvert.SerializeObject(activeUserVMs) }, false);
|
||||
LogLock.OutLogAOP("ACCESSTRENDLOG", "", new string[] { activeUserVMs.GetType().ToString(), JsonConvert.SerializeObject(activeUserVMs) }, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -17,19 +17,21 @@ namespace Blog.Core.Tasks
|
|||
{
|
||||
public class Job_OperateLog_Quartz : JobBase, IJob
|
||||
{
|
||||
private readonly IOperateLogServices _operateLogServices;
|
||||
private readonly IOperateLogServices _operateLogServices;
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
|
||||
public Job_OperateLog_Quartz(IOperateLogServices operateLogServices,IWebHostEnvironment environment, ITasksQzServices tasksQzServices,ITasksLogServices tasksLogServices)
|
||||
:base(tasksQzServices, tasksLogServices)
|
||||
public Job_OperateLog_Quartz(IOperateLogServices operateLogServices, IWebHostEnvironment environment, ITasksQzServices tasksQzServices, ITasksLogServices tasksLogServices)
|
||||
: base(tasksQzServices, tasksLogServices)
|
||||
{
|
||||
_operateLogServices = operateLogServices;
|
||||
_environment = environment;
|
||||
_operateLogServices = operateLogServices;
|
||||
_environment = environment;
|
||||
}
|
||||
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
var executeLog = await ExecuteJob(context, async () => await Run(context));
|
||||
}
|
||||
|
||||
public async Task Run(IJobExecutionContext context)
|
||||
{
|
||||
|
||||
|
@ -78,7 +80,4 @@ namespace Blog.Core.Tasks
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -59,7 +59,6 @@ namespace Blog.Core.Tests
|
|||
services.AddAutoMapper(typeof(Startup));
|
||||
|
||||
services.AddSingleton(new AppSettings(basePath));
|
||||
services.AddSingleton(new LogLock(basePath));
|
||||
services.AddScoped<DBSeed>();
|
||||
services.AddScoped<MyContext>();
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.Serilog.Es", "Blo
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ocelot.Provider.Nacos", "Ocelot.Provider.Nacos\Ocelot.Provider.Nacos.csproj", "{6463FB13-5F01-4A1D-8B62-A454FB3812EB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blog.Core.Serilog", "Blog.Core.Serilog\Blog.Core.Serilog.csproj", "{7F9057F0-ED8D-4694-B590-7D75C012DF00}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -119,6 +121,10 @@ Global
|
|||
{6463FB13-5F01-4A1D-8B62-A454FB3812EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6463FB13-5F01-4A1D-8B62-A454FB3812EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6463FB13-5F01-4A1D-8B62-A454FB3812EB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7F9057F0-ED8D-4694-B590-7D75C012DF00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7F9057F0-ED8D-4694-B590-7D75C012DF00}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7F9057F0-ED8D-4694-B590-7D75C012DF00}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7F9057F0-ED8D-4694-B590-7D75C012DF00}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in New Issue
Block a user