23 changed files with 54 additions and 5325 deletions
@ -0,0 +1,46 @@ |
|||||
|
<Solution> |
||||
|
<Folder Name="/framework/" /> |
||||
|
<Folder Name="/framework/auditing/"> |
||||
|
<Project Path="../../../aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN.Abp.AuditLogging.Elasticsearch.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN.Abp.AuditLogging.csproj" /> |
||||
|
</Folder> |
||||
|
<Folder Name="/framework/common/"> |
||||
|
<Project Path="../../../aspnet-core/framework/common/LINGYUN.Abp.AspNetCore.Wrapper/LINGYUN.Abp.AspNetCore.Wrapper.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/common/LINGYUN.Abp.IdGenerator/LINGYUN.Abp.IdGenerator.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN.Abp.IP2Region.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/common/LINGYUN.Abp.Wrapper/LINGYUN.Abp.Wrapper.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN.Abp.AspNetCore.Mvc.Wrapper.csproj" /> |
||||
|
</Folder> |
||||
|
<Folder Name="/framework/elasticsearch/"> |
||||
|
<Project Path="../../../aspnet-core/framework/elasticsearch/LINGYUN.Abp.Elasticsearch/LINGYUN.Abp.Elasticsearch.csproj" /> |
||||
|
</Folder> |
||||
|
<Folder Name="/framework/identity/"> |
||||
|
<Project Path="../../../aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session.AspNetCore/LINGYUN.Abp.Identity.Session.AspNetCore.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN.Abp.Identity.Session.csproj" /> |
||||
|
</Folder> |
||||
|
<Folder Name="/framework/localization/"> |
||||
|
<Project Path="../../../aspnet-core/framework/localization/LINGYUN.Abp.Localization.CultureMap/LINGYUN.Abp.Localization.CultureMap.csproj" /> |
||||
|
</Folder> |
||||
|
<Folder Name="/framework/logging/"> |
||||
|
<Project Path="../../../aspnet-core/framework/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN.Abp.Logging.Serilog.Elasticsearch.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/logging/LINGYUN.Abp.Logging/LINGYUN.Abp.Logging.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/logging/LINGYUN.Abp.Serilog.Enrichers.Application/LINGYUN.Abp.Serilog.Enrichers.Application.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/logging/LINGYUN.Abp.Serilog.Enrichers.UniqueId/LINGYUN.Abp.Serilog.Enrichers.UniqueId.csproj" /> |
||||
|
</Folder> |
||||
|
<Folder Name="/framework/open-api/"> |
||||
|
<Project Path="../../../aspnet-core/framework/open-api/LINGYUN.Abp.OpenApi.Authorization/LINGYUN.Abp.OpenApi.Authorization.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/open-api/LINGYUN.Abp.OpenApi/LINGYUN.Abp.OpenApi.csproj" /> |
||||
|
<Project Path="../../../aspnet-core/framework/open-api/OpenApi.Sdk/OpenApi.Sdk.csproj" /> |
||||
|
</Folder> |
||||
|
<Folder Name="/Solution Items/"> |
||||
|
<File Path="../../../common.props" /> |
||||
|
<File Path="../../../common.secrets.props" /> |
||||
|
<File Path="../../../configureawait.props" /> |
||||
|
<File Path="../../../Directory.Build.props" /> |
||||
|
<File Path="../../../Directory.Packages.props" /> |
||||
|
</Folder> |
||||
|
<Folder Name="/src/"> |
||||
|
<Project Path="src/LINGYUN.MicroService.Internal.Gateway/LINGYUN.MicroService.Internal.Gateway.csproj" /> |
||||
|
<Project Path="src/LINGYUN.MicroService.OpenApi.Gateway/LINGYUN.MicroService.OpenApi.Gateway.csproj" /> |
||||
|
</Folder> |
||||
|
</Solution> |
||||
@ -1,12 +0,0 @@ |
|||||
{ |
|
||||
"version": 1, |
|
||||
"isRoot": true, |
|
||||
"tools": { |
|
||||
"dotnet-ef": { |
|
||||
"version": "7.0.12", |
|
||||
"commands": [ |
|
||||
"dotnet-ef" |
|
||||
] |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,48 +0,0 @@ |
|||||
using LINGYUN.MicroService.Internal.ApiGateway.Utils; |
|
||||
using Microsoft.AspNetCore.Mvc; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Ocelot.Multiplexer; |
|
||||
using System; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Application.Dtos; |
|
||||
|
|
||||
namespace LINGYUN.MicroService.Internal.ApiGateway.Controllers |
|
||||
{ |
|
||||
[Area("ApiGateway")] |
|
||||
[Route("api/ApiGateway/Basic")] |
|
||||
public class ApiGatewayController : Controller |
|
||||
{ |
|
||||
protected IServiceProvider ServiceProvider { get; } |
|
||||
protected ILoadBalancerFinder LoadBalancerFinder { get; } |
|
||||
public ApiGatewayController( |
|
||||
IServiceProvider serviceProvider, |
|
||||
ILoadBalancerFinder loadBalancerFinder) |
|
||||
{ |
|
||||
ServiceProvider = serviceProvider; |
|
||||
LoadBalancerFinder = loadBalancerFinder; |
|
||||
} |
|
||||
|
|
||||
[HttpGet] |
|
||||
[Route("Aggregators")] |
|
||||
public Task<JsonResult> GetAggregatorsAsync() |
|
||||
{ |
|
||||
var aggregators = ServiceProvider.GetServices<IDefinedAggregator>(); |
|
||||
|
|
||||
var aggregatorDtos = new ListResultDto<string>(aggregators.Select(agg => agg.GetType().Name).ToList()); |
|
||||
|
|
||||
return Task.FromResult(Json(aggregatorDtos)); |
|
||||
} |
|
||||
|
|
||||
[HttpGet] |
|
||||
[Route("LoadBalancers")] |
|
||||
public async Task<JsonResult> GetLoadBalancersAsync() |
|
||||
{ |
|
||||
var loadBalancers = await LoadBalancerFinder.GetLoadBalancersAsync(); |
|
||||
|
|
||||
var loadBalancerDtos = new ListResultDto<LoadBalancerDescriptor>(loadBalancers); |
|
||||
|
|
||||
return Json(loadBalancerDtos); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,11 +0,0 @@ |
|||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 |
|
||||
LABEL maintainer="colin.in@foxmail.com" |
|
||||
WORKDIR /app |
|
||||
|
|
||||
COPY . /app |
|
||||
|
|
||||
EXPOSE 80/tcp |
|
||||
VOLUME [ "./app/Logs" ] |
|
||||
VOLUME [ "./app/Modules" ] |
|
||||
|
|
||||
ENTRYPOINT ["dotnet", "LINGYUN.MicroService.Internal.ApiGateway.dll"] |
|
||||
@ -1,242 +0,0 @@ |
|||||
using LINGYUN.Abp.Serilog.Enrichers.Application; |
|
||||
using LINGYUN.MicroService.Internal.ApiGateway.Localization; |
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer; |
|
||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.AspNetCore.Cors; |
|
||||
using Microsoft.AspNetCore.DataProtection; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.AspNetCore.Routing; |
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core; |
|
||||
using Microsoft.Extensions.Caching.StackExchangeRedis; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.IdentityModel.Logging; |
|
||||
using Microsoft.OpenApi.Models; |
|
||||
using Ocelot.DependencyInjection; |
|
||||
using Ocelot.Multiplexer; |
|
||||
using Ocelot.Provider.Polly; |
|
||||
using StackExchange.Redis; |
|
||||
using System; |
|
||||
using System.Linq; |
|
||||
using System.Text.Encodings.Web; |
|
||||
using System.Text.Unicode; |
|
||||
using Volo.Abp.Caching; |
|
||||
using Volo.Abp.Json; |
|
||||
using Volo.Abp.Json.SystemTextJson; |
|
||||
using Volo.Abp.Localization; |
|
||||
using Volo.Abp.VirtualFileSystem; |
|
||||
|
|
||||
namespace LINGYUN.MicroService.Internal.ApiGateway |
|
||||
{ |
|
||||
public partial class InternalApiGatewayModule |
|
||||
{ |
|
||||
protected const string DefaultCorsPolicyName = "Default"; |
|
||||
|
|
||||
private void PreConfigureApp(IConfiguration configuration) |
|
||||
{ |
|
||||
AbpSerilogEnrichersConsts.ApplicationName = "Internal-ApiGateWay"; |
|
||||
if (configuration.GetValue<bool>("App:ShowPii")) |
|
||||
{ |
|
||||
IdentityModelEventSource.ShowPII = true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//private void PreForwardedHeaders()
|
|
||||
//{
|
|
||||
// PreConfigure<AbpForwardedHeadersOptions>(options =>
|
|
||||
// {
|
|
||||
// options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
|
||||
// options.KnownNetworks.Clear();
|
|
||||
// options.KnownProxies.Clear();
|
|
||||
// });
|
|
||||
//}
|
|
||||
|
|
||||
private void ConfigureApiGateway(IConfiguration configuration) |
|
||||
{ |
|
||||
Configure<InternalApiGatewayOptions>(configuration.GetSection("ApiGateway")); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
private void ConfigureKestrelServer(IConfiguration configuration, bool isDevelopment = true) |
|
||||
{ |
|
||||
// fix: 不限制请求体大小,解决上传文件问题
|
|
||||
Configure<KestrelServerOptions>(options => |
|
||||
{ |
|
||||
options.Limits.MaxRequestBodySize = null; |
|
||||
options.Limits.MaxRequestBufferSize = null; |
|
||||
}); |
|
||||
|
|
||||
if (!isDevelopment) |
|
||||
{ |
|
||||
// Ssl证书
|
|
||||
var sslOptions = configuration.GetSection("App:SslOptions"); |
|
||||
if (sslOptions.Exists()) |
|
||||
{ |
|
||||
var fileName = sslOptions["FileName"]; |
|
||||
var password = sslOptions["Password"]; |
|
||||
Configure<KestrelServerOptions>(options => |
|
||||
{ |
|
||||
options.ConfigureEndpointDefaults(cfg => |
|
||||
{ |
|
||||
cfg.UseHttps(fileName, password); |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private void ConfigureJsonSerializer() |
|
||||
{ |
|
||||
// 统一时间日期格式
|
|
||||
Configure<AbpJsonOptions>(options => |
|
||||
{ |
|
||||
// options.DefaultDateTimeFormat = "yyyy-MM-dd HH:mm:ss";
|
|
||||
}); |
|
||||
// 中文序列化的编码问题
|
|
||||
Configure<AbpSystemTextJsonSerializerOptions>(options => |
|
||||
{ |
|
||||
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void ConfigureVirtualFileSystem() |
|
||||
{ |
|
||||
Configure<AbpVirtualFileSystemOptions>(options => |
|
||||
{ |
|
||||
options.FileSets.AddEmbedded<InternalApiGatewayModule>("LINGYUN.MicroService.Internal.ApiGateway"); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void ConfigureLocalization() |
|
||||
{ |
|
||||
Configure<AbpLocalizationOptions>(options => |
|
||||
{ |
|
||||
options.Languages.Add(new LanguageInfo("en", "en", "English")); |
|
||||
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); |
|
||||
|
|
||||
options.Resources |
|
||||
.Add<ApiGatewayResource>() |
|
||||
.AddVirtualJson("/Localization/Resources"); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void ConfigureMvc(IServiceCollection services) |
|
||||
{ |
|
||||
var mvcBuilder = services.AddMvc(); |
|
||||
mvcBuilder.AddApplicationPart(typeof(InternalApiGatewayModule).Assembly); |
|
||||
|
|
||||
Configure<AbpEndpointRouterOptions>(options => |
|
||||
{ |
|
||||
options.EndpointConfigureActions.Add(endpointContext => |
|
||||
{ |
|
||||
endpointContext.Endpoints.MapControllerRoute("defaultWithArea", "{area}/{controller=Home}/{action=Index}/{id?}"); |
|
||||
endpointContext.Endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void ConfigureOcelot(IServiceCollection services, IConfiguration configuration) |
|
||||
{ |
|
||||
// 需要合并自定义配置取消注释
|
|
||||
// services.AddSingleton<IFileConfigurationRepository, DiskFileConfigurationAggragatorRepository>();
|
|
||||
services |
|
||||
.AddOcelot(configuration) |
|
||||
.AddPolly() |
|
||||
.AddSingletonDefinedAggregator<AbpResponseMergeAggregator>(); |
|
||||
} |
|
||||
|
|
||||
private void ConfigureCaching(IConfiguration configuration) |
|
||||
{ |
|
||||
Configure<AbpDistributedCacheOptions>(options => |
|
||||
{ |
|
||||
// 最好统一命名,不然某个缓存变动其他应用服务有例外发生
|
|
||||
options.KeyPrefix = "LINGYUN.Abp.Application"; |
|
||||
// 滑动过期30天
|
|
||||
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30d); |
|
||||
// 绝对过期60天
|
|
||||
options.GlobalCacheEntryOptions.AbsoluteExpiration = DateTimeOffset.Now.AddDays(60d); |
|
||||
}); |
|
||||
|
|
||||
Configure<RedisCacheOptions>(options => |
|
||||
{ |
|
||||
var redisConfig = ConfigurationOptions.Parse(options.Configuration); |
|
||||
options.ConfigurationOptions = redisConfig; |
|
||||
options.InstanceName = configuration["Redis:InstanceName"]; |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void ConfigureSwagger(IServiceCollection services) |
|
||||
{ |
|
||||
services.AddSwaggerGen( |
|
||||
options => |
|
||||
{ |
|
||||
options.SwaggerDoc("v1", new OpenApiInfo { Title = "Open API Document", Version = "v1" }); |
|
||||
options.DocInclusionPredicate((docName, description) => true); |
|
||||
options.CustomSchemaIds(type => type.FullName); |
|
||||
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme |
|
||||
{ |
|
||||
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", |
|
||||
Name = "Authorization", |
|
||||
In = ParameterLocation.Header, |
|
||||
Scheme = "bearer", |
|
||||
Type = SecuritySchemeType.Http, |
|
||||
BearerFormat = "JWT" |
|
||||
}); |
|
||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement |
|
||||
{ |
|
||||
{ |
|
||||
new OpenApiSecurityScheme |
|
||||
{ |
|
||||
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } |
|
||||
}, |
|
||||
new string[] { } |
|
||||
} |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void ConfigureCors(IServiceCollection services, IConfiguration configuration) |
|
||||
{ |
|
||||
services.AddCors(options => |
|
||||
{ |
|
||||
options.AddPolicy(DefaultCorsPolicyName, builder => |
|
||||
{ |
|
||||
builder |
|
||||
.WithOrigins( |
|
||||
configuration["App:CorsOrigins"] |
|
||||
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
|
||||
.Select(o => o.RemovePostFix("/")) |
|
||||
.ToArray() |
|
||||
) |
|
||||
.WithAbpExposedHeaders() |
|
||||
// 引用 LINGYUN.Abp.AspNetCore.Mvc.Wrapper 包时可替换为 WithAbpWrapExposedHeaders
|
|
||||
.WithExposedHeaders("_AbpWrapResult", "_AbpDontWrapResult") |
|
||||
.SetIsOriginAllowedToAllowWildcardSubdomains() |
|
||||
.AllowAnyHeader() |
|
||||
.AllowAnyMethod() |
|
||||
.AllowCredentials(); |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) |
|
||||
{ |
|
||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) |
|
||||
.AddJwtBearer(options => |
|
||||
{ |
|
||||
options.Authority = configuration["AuthServer:Authority"]; |
|
||||
options.RequireHttpsMetadata = false; |
|
||||
options.Audience = configuration["AuthServer:ApiName"]; |
|
||||
}); |
|
||||
|
|
||||
if (!isDevelopment) |
|
||||
{ |
|
||||
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); |
|
||||
services |
|
||||
.AddDataProtection() |
|
||||
.SetApplicationName("LINGYUN.Abp.Application") |
|
||||
.PersistKeysToStackExchangeRedis(redis, "LINGYUN.Abp.Application:DataProtection:Protection-Keys"); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,87 +0,0 @@ |
|||||
using LINGYUN.Abp.Serilog.Enrichers.Application; |
|
||||
using LINGYUN.Abp.Serilog.Enrichers.UniqueId; |
|
||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Hosting; |
|
||||
using Microsoft.Extensions.Options; |
|
||||
using Ocelot.Middleware; |
|
||||
using Volo.Abp; |
|
||||
using Volo.Abp.AspNetCore.Serilog; |
|
||||
using Volo.Abp.Autofac; |
|
||||
using Volo.Abp.Caching.StackExchangeRedis; |
|
||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace LINGYUN.MicroService.Internal.ApiGateway |
|
||||
{ |
|
||||
|
|
||||
[DependsOn( |
|
||||
typeof(AbpAutofacModule), |
|
||||
typeof(AbpSerilogEnrichersApplicationModule), |
|
||||
typeof(AbpSerilogEnrichersUniqueIdModule), |
|
||||
typeof(AbpCachingStackExchangeRedisModule), |
|
||||
typeof(AbpAspNetCoreSerilogModule) |
|
||||
)] |
|
||||
public partial class InternalApiGatewayModule : AbpModule |
|
||||
{ |
|
||||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
var configuration = context.Services.GetConfiguration(); |
|
||||
|
|
||||
PreConfigureApp(configuration); |
|
||||
} |
|
||||
|
|
||||
public override void ConfigureServices(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|
||||
var configuration = context.Services.GetConfiguration(); |
|
||||
|
|
||||
ConfigureLocalization(); |
|
||||
ConfigureJsonSerializer(); |
|
||||
ConfigureVirtualFileSystem(); |
|
||||
|
|
||||
ConfigureCaching(configuration); |
|
||||
ConfigureApiGateway(configuration); |
|
||||
|
|
||||
ConfigureKestrelServer(configuration, hostingEnvironment.IsDevelopment()); |
|
||||
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); |
|
||||
|
|
||||
ConfigureMvc(context.Services); |
|
||||
ConfigureSwagger(context.Services); |
|
||||
ConfigureCors(context.Services, configuration); |
|
||||
ConfigureOcelot(context.Services, configuration); |
|
||||
} |
|
||||
|
|
||||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|
||||
{ |
|
||||
var app = context.GetApplicationBuilder(); |
|
||||
app.UseAuditing(); |
|
||||
app.UseStaticFiles(); |
|
||||
app.UseRouting(); |
|
||||
app.UseCors(DefaultCorsPolicyName); |
|
||||
app.UseAuthentication(); |
|
||||
app.UseAbpClaimsMap(); |
|
||||
app.MapWhen( |
|
||||
ctx => ctx.Request.Path.ToString().StartsWith("/api/ApiGateway/Basic/"), |
|
||||
appNext => |
|
||||
{ |
|
||||
// 仅针对属于网关自己的控制器进入MVC管道
|
|
||||
appNext.UseRouting(); |
|
||||
appNext.UseConfiguredEndpoints(); |
|
||||
}); |
|
||||
app.UseSwagger(); |
|
||||
app.UseSwaggerUI(c => |
|
||||
{ |
|
||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Open API Document"); |
|
||||
var options = app.ApplicationServices.GetRequiredService<IOptions<InternalApiGatewayOptions>>().Value; |
|
||||
foreach (var api in options.DownstreamOpenApis) |
|
||||
{ |
|
||||
c.SwaggerEndpoint(api.EndPoint, api.Name); |
|
||||
} |
|
||||
}); |
|
||||
// 启用ws协议
|
|
||||
app.UseWebSockets(); |
|
||||
app.UseAbpSerilogEnrichers(); |
|
||||
app.UseOcelot().Wait(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,18 +0,0 @@ |
|||||
using LINGYUN.MicroService.Internal.ApiGateway.Models; |
|
||||
|
|
||||
namespace LINGYUN.MicroService.Internal.ApiGateway |
|
||||
{ |
|
||||
public class InternalApiGatewayOptions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 聚合异常时是否忽略
|
|
||||
/// </summary>
|
|
||||
public bool AggregationIgnoreError { get; set; } |
|
||||
public DownstreamOpenApi[] DownstreamOpenApis { get; set; } |
|
||||
public InternalApiGatewayOptions() |
|
||||
{ |
|
||||
AggregationIgnoreError = true; |
|
||||
DownstreamOpenApis = new DownstreamOpenApi[0]; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,41 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|
||||
|
|
||||
<Import Project="..\..\..\..\..\common.props" /> |
|
||||
<Import Project="..\..\..\..\..\common.secrets.props" /> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<OutputType>Exe</OutputType> |
|
||||
<TargetFramework>net10.0</TargetFramework> |
|
||||
<RootNamespace>LINGYUN.MicroService.Internal.ApiGateway</RootNamespace> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Ocelot.Provider.Polly" /> |
|
||||
<PackageReference Include="AgileConfig.Client" /> |
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" /> |
|
||||
<PackageReference Include="Serilog.AspNetCore" /> |
|
||||
<PackageReference Include="Serilog.Enrichers.Environment" /> |
|
||||
<PackageReference Include="Serilog.Enrichers.Assembly" /> |
|
||||
<PackageReference Include="Serilog.Enrichers.Process" /> |
|
||||
<PackageReference Include="Serilog.Enrichers.Thread" /> |
|
||||
<PackageReference Include="Serilog.Settings.Configuration" /> |
|
||||
<PackageReference Include="Serilog.Sinks.Elasticsearch" /> |
|
||||
<PackageReference Include="Serilog.Sinks.File" /> |
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" /> |
|
||||
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" /> |
|
||||
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" /> |
|
||||
<PackageReference Include="Volo.Abp.Autofac" /> |
|
||||
<PackageReference Include="Volo.Abp.AspNetCore" /> |
|
||||
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" /> |
|
||||
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\..\..\..\..\aspnet-core\framework\auditing\LINGYUN.Abp.AuditLogging.Elasticsearch\LINGYUN.Abp.AuditLogging.Elasticsearch.csproj" /> |
|
||||
<!--<ProjectReference Include="..\..\..\..\..\aspnet-core\framework\common\LINGYUN.Abp.AspNetCore.HttpOverrides\LINGYUN.Abp.AspNetCore.HttpOverrides.csproj" />--> |
|
||||
<ProjectReference Include="..\..\..\..\..\aspnet-core\framework\localization\LINGYUN.Abp.Localization.CultureMap\LINGYUN.Abp.Localization.CultureMap.csproj" /> |
|
||||
<ProjectReference Include="..\..\..\..\..\aspnet-core\framework\logging\LINGYUN.Abp.Serilog.Enrichers.Application\LINGYUN.Abp.Serilog.Enrichers.Application.csproj" /> |
|
||||
<ProjectReference Include="..\..\..\..\..\aspnet-core\framework\logging\LINGYUN.Abp.Serilog.Enrichers.UniqueId\LINGYUN.Abp.Serilog.Enrichers.UniqueId.csproj" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,9 +0,0 @@ |
|||||
using Volo.Abp.Localization; |
|
||||
|
|
||||
namespace LINGYUN.MicroService.Internal.ApiGateway.Localization |
|
||||
{ |
|
||||
[LocalizationResourceName("InternalApiGateway")] |
|
||||
public class ApiGatewayResource |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,10 +0,0 @@ |
|||||
{ |
|
||||
"culture": "en", |
|
||||
"texts": { |
|
||||
"NoLoadBalancer": "No Load balancer", |
|
||||
"RoundRobin": "Round robin", |
|
||||
"LeastConnection": "Least connection", |
|
||||
"CookieStickySessions": "Cookie sticky sessions", |
|
||||
"CustomLoadBalancer": "Custom load balancer - {0}" |
|
||||
} |
|
||||
} |
|
||||
@ -1,10 +0,0 @@ |
|||||
{ |
|
||||
"culture": "zh-Hans", |
|
||||
"texts": { |
|
||||
"NoLoadBalancer": "无负载均衡", |
|
||||
"RoundRobin": "服务器轮询", |
|
||||
"LeastConnection": "总是空闲服务器", |
|
||||
"CookieStickySessions": "粘性会话类型", |
|
||||
"CustomLoadBalancer": "自定义负载均衡器 - {0}" |
|
||||
} |
|
||||
} |
|
||||
@ -1,8 +0,0 @@ |
|||||
namespace LINGYUN.MicroService.Internal.ApiGateway.Models |
|
||||
{ |
|
||||
public class DownstreamOpenApi |
|
||||
{ |
|
||||
public string Name { get; set; } |
|
||||
public string EndPoint { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,132 +0,0 @@ |
|||||
using LINGYUN.MicroService.Internal.ApiGateway; |
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
using Microsoft.Extensions.Logging.Abstractions; |
|
||||
using Microsoft.Extensions.Options; |
|
||||
using Newtonsoft.Json; |
|
||||
using Newtonsoft.Json.Linq; |
|
||||
using Ocelot.Middleware; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Net; |
|
||||
using System.Net.Http; |
|
||||
using System.Net.Http.Headers; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Http; |
|
||||
|
|
||||
namespace Ocelot.Multiplexer |
|
||||
{ |
|
||||
public class AbpResponseMergeAggregator : IDefinedAggregator |
|
||||
{ |
|
||||
public ILogger<AbpResponseMergeAggregator> Logger { protected get; set; } |
|
||||
protected InternalApiGatewayOptions Options { get; } |
|
||||
|
|
||||
public AbpResponseMergeAggregator( |
|
||||
IOptions<InternalApiGatewayOptions> options) |
|
||||
{ |
|
||||
Options = options.Value; |
|
||||
|
|
||||
Logger = NullLogger<AbpResponseMergeAggregator>.Instance; |
|
||||
} |
|
||||
|
|
||||
public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses) |
|
||||
{ |
|
||||
return await MapAbpApiDefinitionAggregateContentAsync(responses); |
|
||||
} |
|
||||
|
|
||||
protected virtual async Task<DownstreamResponse> MapAbpApiDefinitionAggregateContentAsync(List<HttpContext> responses) |
|
||||
{ |
|
||||
JObject responseObject = null; |
|
||||
JsonMergeSettings mergeSetting = new JsonMergeSettings |
|
||||
{ |
|
||||
MergeArrayHandling = MergeArrayHandling.Union, |
|
||||
PropertyNameComparison = System.StringComparison.CurrentCultureIgnoreCase |
|
||||
}; |
|
||||
foreach (var httpResponse in responses) |
|
||||
{ |
|
||||
var errorItems = httpResponse.Items.Errors(); |
|
||||
var response = httpResponse.Items.DownstreamResponse(); |
|
||||
|
|
||||
if (errorItems.Any()) |
|
||||
{ |
|
||||
if (!Options.AggregationIgnoreError) |
|
||||
{ |
|
||||
var errorItem = errorItems.First(); |
|
||||
string error = errorItems.Select(x => x.Message).JoinAsString(";"); |
|
||||
if (httpResponse.Response.Headers.ContainsKey(AbpHttpConsts.AbpErrorFormat)) |
|
||||
{ |
|
||||
// header 存在abp错误标头, 可以序列化错误信息
|
|
||||
error = await response.Content.ReadAsStringAsync(); |
|
||||
} |
|
||||
var errorContent = new StringContent(error) |
|
||||
{ |
|
||||
Headers = { ContentType = new MediaTypeHeaderValue("application/json") } |
|
||||
}; |
|
||||
if (httpResponse.Response.Headers.ContainsKey(AbpHttpConsts.AbpErrorFormat)) |
|
||||
{ |
|
||||
errorContent.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); |
|
||||
} |
|
||||
|
|
||||
return new DownstreamResponse( |
|
||||
errorContent, |
|
||||
(HttpStatusCode)errorItem.HttpStatusCode, |
|
||||
httpResponse.Response.Headers.Select(x => new Header(x.Key, x.Value)).ToList(), |
|
||||
errorItem.Message); |
|
||||
} |
|
||||
var route = httpResponse.Items.DownstreamRoute(); |
|
||||
var service = route.ServiceName ?? route.LoadBalancerKey ?? route.DownstreamPathTemplate.Value; |
|
||||
Logger.LogWarning($"The downstream service {service} returned an error, which is configured to be ignored"); |
|
||||
continue; |
|
||||
} |
|
||||
var content = await response.Content.ReadAsStringAsync(); |
|
||||
try |
|
||||
{ |
|
||||
var contentObject = JsonConvert.DeserializeObject(content); |
|
||||
if (responseObject == null) |
|
||||
{ |
|
||||
responseObject = JObject.FromObject(contentObject); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
responseObject.Merge(contentObject, mergeSetting); |
|
||||
} |
|
||||
} |
|
||||
catch (System.Exception ex) |
|
||||
{ |
|
||||
Logger.LogError(ex, "An error occurred in the aggregate route request result."); |
|
||||
return new DownstreamResponse( |
|
||||
null, |
|
||||
HttpStatusCode.InternalServerError, |
|
||||
new List<KeyValuePair<string, IEnumerable<string>>>(), |
|
||||
content); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (responseObject == null) |
|
||||
{ |
|
||||
return new DownstreamResponse( |
|
||||
null, |
|
||||
HttpStatusCode.NotFound, |
|
||||
new List<KeyValuePair<string, IEnumerable<string>>>(), |
|
||||
"Not Found"); |
|
||||
} |
|
||||
|
|
||||
var stringContent = new StringContent(responseObject.ToString()) |
|
||||
{ |
|
||||
Headers = { ContentType = new MediaTypeHeaderValue("application/json") } |
|
||||
}; |
|
||||
|
|
||||
//if (responses.Any(response => response.Response.Headers.ContainsKey(AbpHttpConsts.AbpErrorFormat)))
|
|
||||
//{
|
|
||||
// stringContent.Headers.Add("_AbpErrorFormat", "true");
|
|
||||
//}
|
|
||||
|
|
||||
return new DownstreamResponse( |
|
||||
stringContent, |
|
||||
HttpStatusCode.OK, |
|
||||
new List<KeyValuePair<string, IEnumerable<string>>>(), |
|
||||
"OK"); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
@ -1,73 +0,0 @@ |
|||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Hosting; |
|
||||
using Serilog; |
|
||||
using System; |
|
||||
using System.IO; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.IO; |
|
||||
using Volo.Abp.Modularity.PlugIns; |
|
||||
|
|
||||
namespace LINGYUN.MicroService.Internal.ApiGateway; |
|
||||
|
|
||||
public class Program |
|
||||
{ |
|
||||
public async static Task<int> Main(string[] args) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
Log.Information("Starting Internal ApiGateway."); |
|
||||
|
|
||||
var builder = WebApplication.CreateBuilder(args); |
|
||||
|
|
||||
builder.Host.AddAppSettingsSecretsJson() |
|
||||
.UseAutofac() |
|
||||
.ConfigureAppConfiguration((context, config) => |
|
||||
{ |
|
||||
var configuration = config.Build(); |
|
||||
var agileConfigEnabled = configuration["AgileConfig:IsEnabled"]; |
|
||||
if (agileConfigEnabled.IsNullOrEmpty() || bool.Parse(agileConfigEnabled)) |
|
||||
{ |
|
||||
config.AddAgileConfig(new AgileConfig.Client.ConfigClient(configuration)); |
|
||||
} |
|
||||
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: true); |
|
||||
if (!context.HostingEnvironment.EnvironmentName.IsNullOrWhiteSpace()) |
|
||||
{ |
|
||||
config.AddJsonFile($"ocelot.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true); |
|
||||
} |
|
||||
}) |
|
||||
.UseSerilog((context, provider, config) => |
|
||||
{ |
|
||||
config.ReadFrom.Configuration(context.Configuration); |
|
||||
}); |
|
||||
await builder.AddApplicationAsync<InternalApiGatewayModule>(options => |
|
||||
{ |
|
||||
// 搜索 Modules 目录下所有文件作为插件
|
|
||||
// 取消显示引用所有其他项目的模块,改为通过插件的形式引用
|
|
||||
var pluginFolder = Path.Combine( |
|
||||
Directory.GetCurrentDirectory(), "Modules"); |
|
||||
DirectoryHelper.CreateIfNotExists(pluginFolder); |
|
||||
options.PlugInSources.AddFolder( |
|
||||
pluginFolder, |
|
||||
SearchOption.AllDirectories); |
|
||||
}); |
|
||||
var app = builder.Build(); |
|
||||
await app.InitializeApplicationAsync(); |
|
||||
await app.RunAsync(); |
|
||||
return 0; |
|
||||
} |
|
||||
catch (Exception ex) |
|
||||
{ |
|
||||
Log.Fatal(ex, "Host terminated unexpectedly!"); |
|
||||
Console.WriteLine("Host terminated unexpectedly!"); |
|
||||
Console.WriteLine(ex.ToString()); |
|
||||
return 1; |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
Log.CloseAndFlush(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
{ |
|
||||
"iisSettings": { |
|
||||
"windowsAuthentication": false, |
|
||||
"anonymousAuthentication": true, |
|
||||
"iisExpress": { |
|
||||
"applicationUrl": "http://localhost:51466/", |
|
||||
"sslPort": 44332 |
|
||||
} |
|
||||
}, |
|
||||
"profiles": { |
|
||||
"LINGYUN.MicroService.Internal.ApiGateway": { |
|
||||
"commandName": "Project", |
|
||||
"launchBrowser": false, |
|
||||
"environmentVariables": { |
|
||||
"ASPNETCORE_ENVIRONMENT": "Development" |
|
||||
}, |
|
||||
"applicationUrl": "https://127.0.0.1:30443;http://127.0.0.1:30000" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,21 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace LINGYUN.MicroService.Internal.ApiGateway.Utils |
|
||||
{ |
|
||||
public interface ILoadBalancerFinder |
|
||||
{ |
|
||||
Task<List<LoadBalancerDescriptor>> GetLoadBalancersAsync(); |
|
||||
} |
|
||||
|
|
||||
public class LoadBalancerDescriptor |
|
||||
{ |
|
||||
public string Type { get; } |
|
||||
public string DisplayName { get; } |
|
||||
public LoadBalancerDescriptor(string type, string displayName) |
|
||||
{ |
|
||||
Type = type; |
|
||||
DisplayName = displayName; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,58 +0,0 @@ |
|||||
using LINGYUN.MicroService.Internal.ApiGateway.Localization; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Localization; |
|
||||
using Ocelot.LoadBalancer.LoadBalancers; |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
|
|
||||
namespace LINGYUN.MicroService.Internal.ApiGateway.Utils |
|
||||
{ |
|
||||
public class LoadBalancerFinder : ILoadBalancerFinder, ISingletonDependency |
|
||||
{ |
|
||||
private Lazy<List<LoadBalancerDescriptor>> lazyLoadBalancers; |
|
||||
protected List<LoadBalancerDescriptor> LoadBalancers => lazyLoadBalancers.Value; |
|
||||
protected IServiceProvider ServiceProvider { get; } |
|
||||
protected IStringLocalizer Localizer { get; } |
|
||||
public LoadBalancerFinder( |
|
||||
IServiceProvider serviceProvider, |
|
||||
IStringLocalizer<ApiGatewayResource> localizer) |
|
||||
{ |
|
||||
Localizer = localizer; |
|
||||
ServiceProvider = serviceProvider; |
|
||||
|
|
||||
lazyLoadBalancers = new Lazy<List<LoadBalancerDescriptor>>(() => FindLocalLoadBalancers()); |
|
||||
} |
|
||||
|
|
||||
public Task<List<LoadBalancerDescriptor>> GetLoadBalancersAsync() |
|
||||
{ |
|
||||
return Task.FromResult(LoadBalancers); |
|
||||
} |
|
||||
|
|
||||
protected List<LoadBalancerDescriptor> FindLocalLoadBalancers() |
|
||||
{ |
|
||||
List<LoadBalancerDescriptor> loadBalancers = new List<LoadBalancerDescriptor> |
|
||||
{ |
|
||||
new LoadBalancerDescriptor(typeof(NoLoadBalancer).Name, Localizer["NoLoadBalancer"]), |
|
||||
new LoadBalancerDescriptor(typeof(RoundRobin).Name, Localizer["RoundRobin"]), |
|
||||
new LoadBalancerDescriptor(typeof(LeastConnection).Name, Localizer["LeastConnection"]), |
|
||||
new LoadBalancerDescriptor(typeof(CookieStickySessions).Name, Localizer["CookieStickySessions"]) |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
var loadBalancerCreators = ServiceProvider.GetServices<ILoadBalancerCreator>(); |
|
||||
loadBalancerCreators = loadBalancerCreators |
|
||||
.Where(lbc => !loadBalancers.Any(l => l.Type.Equals(lbc.Type))) |
|
||||
.ToArray(); |
|
||||
|
|
||||
foreach(var defintedLoadBalancerCreator in loadBalancerCreators) |
|
||||
{ |
|
||||
loadBalancers.Add(new LoadBalancerDescriptor(defintedLoadBalancerCreator.Type, Localizer["CustomLoadBalancer", defintedLoadBalancerCreator.Type])); |
|
||||
} |
|
||||
|
|
||||
return loadBalancers; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,87 +0,0 @@ |
|||||
{ |
|
||||
"AgileConfig": { |
|
||||
"IsEnabled": false, |
|
||||
"env": "DEV", |
|
||||
"appId": "LINGYUN.Internal.ApiGateway", |
|
||||
"secret": "1q2w3E*", |
|
||||
"nodes": "http://127.0.0.1:5000", |
|
||||
"name": "ApiGateway", |
|
||||
"tag": "ApiGateway" |
|
||||
}, |
|
||||
"App": { |
|
||||
"CorsOrigins": "http://127.0.0.1:3100", |
|
||||
"ShowPii": true |
|
||||
}, |
|
||||
"ApiGateway": { |
|
||||
"AppId": "TEST-APP", |
|
||||
"DownstreamOpenApis": [ |
|
||||
{ |
|
||||
"Name": "ApiGateway Admin API", |
|
||||
"EndPoint": "/apigateway-admin/v1/swagger.json" |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "Backend Admin API", |
|
||||
"EndPoint": "/admin/v1/swagger.json" |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "Platform API", |
|
||||
"EndPoint": "/platform/v1/swagger.json" |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "Localization API", |
|
||||
"EndPoint": "/localization/v1/swagger.json" |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "Messages API", |
|
||||
"EndPoint": "/messages/v1/swagger.json" |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "IdentityServer Admin API", |
|
||||
"EndPoint": "/ids-admin/v1/swagger.json" |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "Webhooks API", |
|
||||
"EndPoint": "/webhooks/v1/swagger.json" |
|
||||
} |
|
||||
] |
|
||||
}, |
|
||||
"Redis": { |
|
||||
"Configuration": "127.0.0.1,defaultDatabase=10", |
|
||||
"InstanceName": "LINGYUN.Abp.Application" |
|
||||
}, |
|
||||
"AuthServer": { |
|
||||
"Authority": "http://host.docker.internal:44385/", |
|
||||
"ApiName": "lingyun-abp-application", |
|
||||
"SwaggerClientId": "ApigatewayHostClient", |
|
||||
"SwaggerClientSecret": "1q2w3e*", |
|
||||
"ApiSocpes": "lingyun-abp-application" |
|
||||
}, |
|
||||
"Serilog": { |
|
||||
"MinimumLevel": { |
|
||||
"Default": "Debug", |
|
||||
"Override": { |
|
||||
"System": "Warning", |
|
||||
"Microsoft": "Warning", |
|
||||
"DotNetCore": "Debug" |
|
||||
} |
|
||||
}, |
|
||||
"WriteTo": [ |
|
||||
{ |
|
||||
"Name": "Console", |
|
||||
"Args": { |
|
||||
"restrictedToMinimumLevel": "Debug", |
|
||||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "Elasticsearch", |
|
||||
"Args": { |
|
||||
"nodeUris": "http://127.0.0.1:9200", |
|
||||
"indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}", |
|
||||
"autoRegisterTemplate": true, |
|
||||
"autoRegisterTemplateVersion": "ESv7" |
|
||||
} |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
} |
|
||||
@ -1,80 +0,0 @@ |
|||||
{ |
|
||||
"AuthServer": { |
|
||||
"Authority": "http://127.0.0.1:44385/", |
|
||||
"ApiName": "lingyun-abp-application", |
|
||||
"SwaggerClientId": "ApigatewayHostClient", |
|
||||
"SwaggerClientSecret": "1q2w3e*", |
|
||||
"ApiSocpes": "lingyun-abp-application" |
|
||||
}, |
|
||||
"StringEncryption": { |
|
||||
"DefaultPassPhrase": "s46c5q55nxpeS8Ra", |
|
||||
"InitVectorBytes": "s83ng0abvd02js84", |
|
||||
"DefaultSalt": "sf&5)s3#" |
|
||||
}, |
|
||||
"Serilog": { |
|
||||
"MinimumLevel": { |
|
||||
"Default": "Debug", |
|
||||
"Override": { |
|
||||
"System": "Warning", |
|
||||
"Microsoft": "Warning" |
|
||||
} |
|
||||
}, |
|
||||
"Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], |
|
||||
"WriteTo": [ |
|
||||
{ |
|
||||
"Name": "Console", |
|
||||
"Args": { |
|
||||
"initialMinimumLevel": "Information", |
|
||||
"standardErrorFromLevel": "Information", |
|
||||
"restrictedToMinimumLevel": "Information", |
|
||||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "File", |
|
||||
"Args": { |
|
||||
"path": "Logs/Debug-.log", |
|
||||
"restrictedToMinimumLevel": "Debug", |
|
||||
"rollingInterval": "Day", |
|
||||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "File", |
|
||||
"Args": { |
|
||||
"path": "Logs/Info-.log", |
|
||||
"restrictedToMinimumLevel": "Information", |
|
||||
"rollingInterval": "Day", |
|
||||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "File", |
|
||||
"Args": { |
|
||||
"path": "Logs/Warn-.log", |
|
||||
"restrictedToMinimumLevel": "Warning", |
|
||||
"rollingInterval": "Day", |
|
||||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "File", |
|
||||
"Args": { |
|
||||
"path": "Logs/Error-.log", |
|
||||
"restrictedToMinimumLevel": "Error", |
|
||||
"rollingInterval": "Day", |
|
||||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|
||||
} |
|
||||
}, |
|
||||
{ |
|
||||
"Name": "File", |
|
||||
"Args": { |
|
||||
"path": "Logs/Fatal-.log", |
|
||||
"restrictedToMinimumLevel": "Fatal", |
|
||||
"rollingInterval": "Day", |
|
||||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|
||||
} |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
} |
|
||||
@ -1 +0,0 @@ |
|||||
{} |
|
||||
File diff suppressed because it is too large
Loading…
Reference in new issue