diff --git a/docker-compose.simple.yml b/docker-compose.simple.yml index 999b16c..8b6248b 100644 --- a/docker-compose.simple.yml +++ b/docker-compose.simple.yml @@ -3,9 +3,9 @@ version: '3.8' services: antsk: container_name: antsk - image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.3.1 + image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.3.6 # 如果需要pytorch环境需要使用下面这个镜像,镜像比较大 - # image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.3.1 + # image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.3.6 ports: - 5000:5000 networks: @@ -15,5 +15,7 @@ services: - ASPNETCORE_URLS=http://*:5000 volumes: - ./appsettings.json:/app/appsettings.json # 本地配置文件 需要放在同级目录 + - /AntSK/model:/app/model + - /AntSK/model:/root/.cache/modelscope/hub/AI-ModelScope # LLamaFactory模型文件 networks: antsk: diff --git a/docker-compose.yml b/docker-compose.yml index d0d9c2b..5d73980 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,20 @@ # 非 host 版本, 不使用本机代理 version: '3.8' services: + aspire-dashboard: + container_name: aspire-dashboard + image: mcr.microsoft.com/dotnet/aspire-dashboard:8.0 + networks: + - antsk + environment: + - DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS=true + - ASPIRE_ALLOW_UNSECURED_TRANSPORT=true + - DASHBOARD_OTLP_AUTHMODE=ApiKey + - DASHBOARD_OTLP_PRIMARYAPIKEY=antsk + ports: + - 18888:18888 + - 18889:18889 + restart: unless-stopped antskpg: image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/pg:v0.5.0 container_name: antskpg @@ -18,9 +32,9 @@ services: - ./pg/data:/var/lib/postgresql/data antsk: container_name: antsk - image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.3.1 + image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.3.6 # 如果需要pytorch环境需要使用下面这个镜像,镜像比较大 - # image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.3.1 + # image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.3.6 ports: - 5000:5000 networks: @@ -30,7 +44,15 @@ services: restart: always environment: - ASPNETCORE_URLS=http://*:5000 + - ASPNETCORE_FORWARDEDHEADERS_ENABLED=true + - OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES=true + - OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES= true + - OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY=in_memory + - OTEL_EXPORTER_OTLP_ENDPOINT=http://aspire-dashboard:18889 + - OTEL_SERVICE_NAME=antsk volumes: - ./appsettings.json:/app/appsettings.json # 本地配置文件 需要放在同级目录 + - /AntSK/model:/app/model + - /AntSK/model:/root/.cache/modelscope/hub/AI-ModelScope # LLamaFactory模型文件 networks: antsk: diff --git a/src/AntSK.AppHost/AntSK.AppHost.csproj b/src/AntSK.AppHost/AntSK.AppHost.csproj new file mode 100644 index 0000000..0c428d8 --- /dev/null +++ b/src/AntSK.AppHost/AntSK.AppHost.csproj @@ -0,0 +1,20 @@ + + + + Exe + net8.0 + enable + enable + true + 32ac67c8-178a-4eeb-871d-879023582e06 + + + + + + + + + + + diff --git a/src/AntSK.AppHost/Program.cs b/src/AntSK.AppHost/Program.cs new file mode 100644 index 0000000..0b13ec1 --- /dev/null +++ b/src/AntSK.AppHost/Program.cs @@ -0,0 +1,5 @@ +var builder = DistributedApplication.CreateBuilder(args); + +builder.AddProject("antsk"); + +builder.Build().Run(); diff --git a/src/AntSK.AppHost/appsettings.Development.json b/src/AntSK.AppHost/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/AntSK.AppHost/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/AntSK.AppHost/appsettings.json b/src/AntSK.AppHost/appsettings.json new file mode 100644 index 0000000..31c092a --- /dev/null +++ b/src/AntSK.AppHost/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Aspire.Hosting.Dcp": "Warning" + } + } +} diff --git a/src/AntSK.AppHost/aspirate-output/docker-compose.yaml b/src/AntSK.AppHost/aspirate-output/docker-compose.yaml new file mode 100644 index 0000000..a520a50 --- /dev/null +++ b/src/AntSK.AppHost/aspirate-output/docker-compose.yaml @@ -0,0 +1,26 @@ +services: + aspire-dashboard: + container_name: "aspire-dashboard" + image: "mcr.microsoft.com/dotnet/aspire-dashboard:8.0" + environment: + DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS: "true" + ports: + - target: 18888 + published: 18888 + restart: unless-stopped + antsk: + container_name: "antsk" + image: "antsk:latest" + environment: + OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES: "true" + OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES: "true" + OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY: "in_memory" + ASPNETCORE_FORWARDEDHEADERS_ENABLED: "true" + OTEL_EXPORTER_OTLP_ENDPOINT: "http://aspire-dashboard:18889" + OTEL_SERVICE_NAME: "antsk" + ports: + - target: 8080 + published: 10000 + - target: 8443 + published: 10001 + restart: unless-stopped diff --git a/src/AntSK.AppHost/aspirate-state.json b/src/AntSK.AppHost/aspirate-state.json new file mode 100644 index 0000000..2e8d0ed --- /dev/null +++ b/src/AntSK.AppHost/aspirate-state.json @@ -0,0 +1,17 @@ +{ + "projectPath": ".", + "outputPath": "aspirate-output", + "containerImageTags": [ + "latest" + ], + "containerBuilder": "docker", + "outputFormat": "compose", + "privateRegistryEmail": "aspir8@aka.ms", + "includeDashboard": true, + "secrets": { + "salt": "fjamZa3pQbM1UyY4", + "hash": "QR\u002BSEr3p2SwD/w2oPE21vrWh/EerhNyVyTkr0atIREw=", + "secrets": {} + }, + "processAllComponents": true +} \ No newline at end of file diff --git a/src/AntSK.AppHost/manifest.json b/src/AntSK.AppHost/manifest.json new file mode 100644 index 0000000..5aa0ab1 --- /dev/null +++ b/src/AntSK.AppHost/manifest.json @@ -0,0 +1,26 @@ +{ + "resources": { + "antsk": { + "type": "project.v0", + "path": "../AntSK/AntSK.csproj", + "env": { + "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true", + "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true", + "OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY": "in_memory", + "ASPNETCORE_FORWARDEDHEADERS_ENABLED": "true" + }, + "bindings": { + "http": { + "scheme": "http", + "protocol": "tcp", + "transport": "http" + }, + "https": { + "scheme": "https", + "protocol": "tcp", + "transport": "http" + } + } + } + } +} \ No newline at end of file diff --git a/src/AntSK.Domain/AntSK.Domain.csproj b/src/AntSK.Domain/AntSK.Domain.csproj index 8cc3a77..8f8dd37 100644 --- a/src/AntSK.Domain/AntSK.Domain.csproj +++ b/src/AntSK.Domain/AntSK.Domain.csproj @@ -14,7 +14,7 @@ - + @@ -40,8 +40,14 @@ - - + + + + + + + + diff --git a/src/AntSK.Domain/Common/DependencyInjection/InitExtensions.cs b/src/AntSK.Domain/Common/DependencyInjection/InitExtensions.cs index 82f0a79..4a49eec 100644 --- a/src/AntSK.Domain/Common/DependencyInjection/InitExtensions.cs +++ b/src/AntSK.Domain/Common/DependencyInjection/InitExtensions.cs @@ -5,6 +5,7 @@ using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using SqlSugar; using Swashbuckle.AspNetCore.SwaggerGen; @@ -19,6 +20,12 @@ namespace AntSK.Domain.Common.DependencyInjection { public static class InitExtensions { + private static ILogger _logger; + + public static void InitLog(ILogger logger) + { + _logger = logger; + } /// /// 使用codefirst创建数据库表 /// @@ -52,6 +59,8 @@ namespace AntSK.Domain.Common.DependencyInjection } //安装向量插件 _repository.GetDB().Ado.ExecuteCommandAsync($"CREATE EXTENSION IF NOT EXISTS vector;"); + + _logger.LogInformation("初始化表结构完成"); } return app; } @@ -72,7 +81,7 @@ namespace AntSK.Domain.Common.DependencyInjection llamafactoryStart.Value = "false"; _dic_Repository.Insert(llamafactoryStart); } - + _logger.LogInformation("初始化数据库初始数据完成"); } return app; } @@ -99,7 +108,7 @@ namespace AntSK.Domain.Common.DependencyInjection } catch (Exception ex) { - Console.WriteLine(ex.Message + " ---- " + ex.StackTrace); + _logger.LogError(ex.Message + " ---- " + ex.StackTrace); } return app; } diff --git a/src/AntSK.Domain/Common/LLamaFactory/ProcessWrapper.cs b/src/AntSK.Domain/Common/LLamaFactory/ProcessWrapper.cs index f1109e3..26a5aae 100644 --- a/src/AntSK.Domain/Common/LLamaFactory/ProcessWrapper.cs +++ b/src/AntSK.Domain/Common/LLamaFactory/ProcessWrapper.cs @@ -1,4 +1,6 @@ -using System; +using Amazon.Runtime.Internal.Util; +using Microsoft.Extensions.Logging; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -7,7 +9,7 @@ using System.Threading.Tasks; namespace AntSK.Domain.Common.LLamaFactory { - public class ProcessWrapper + public class ProcessWrapper(ILogger _logger) { private Process process; @@ -41,7 +43,7 @@ namespace AntSK.Domain.Common.LLamaFactory isProcessComplete = true; } } - Console.WriteLine(result); + _logger.LogInformation(result); } start.WaitForExit(); } diff --git a/src/AntSK.Domain/Domain/Other/BackGroundTaskHandler.cs b/src/AntSK.Domain/Domain/Other/BackGroundTaskHandler.cs index 4a46e59..89e102d 100644 --- a/src/AntSK.Domain/Domain/Other/BackGroundTaskHandler.cs +++ b/src/AntSK.Domain/Domain/Other/BackGroundTaskHandler.cs @@ -1,27 +1,31 @@ -using AntSK.BackgroundTask; +using Amazon.Runtime.Internal.Util; +using AntSK.BackgroundTask; using AntSK.Domain.Domain.Interface; using AntSK.Domain.Domain.Model; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; namespace AntSK.Domain.Domain.Other { public class BackGroundTaskHandler : IBackgroundTaskHandler { private readonly IServiceScopeFactory _scopeFactory; + private readonly ILogger _logger; - public BackGroundTaskHandler(IServiceScopeFactory scopeFactory) + public BackGroundTaskHandler(IServiceScopeFactory scopeFactory, ILogger logger) { _scopeFactory = scopeFactory; + _logger = logger; } public async Task ExecuteAsync(ImportKMSTaskReq item) { using (var scope = _scopeFactory.CreateScope()) { - Console.WriteLine("ExecuteAsync.开始执行后台任务"); + _logger.LogInformation("ExecuteAsync.开始执行后台任务"); var importKMSService = scope.ServiceProvider.GetRequiredService(); //不能使用异步 importKMSService.ImportKMSTask(item); - Console.WriteLine("ExecuteAsync.后台任务执行完成"); + _logger.LogInformation("ExecuteAsync.后台任务执行完成"); } } diff --git a/src/AntSK.Domain/Domain/Other/Bge/BgeEmbeddingConfig.cs b/src/AntSK.Domain/Domain/Other/Bge/BgeEmbeddingConfig.cs index 1711418..f345553 100644 --- a/src/AntSK.Domain/Domain/Other/Bge/BgeEmbeddingConfig.cs +++ b/src/AntSK.Domain/Domain/Other/Bge/BgeEmbeddingConfig.cs @@ -1,6 +1,7 @@ using Microsoft.KernelMemory.AI.OpenAI; using Microsoft.KernelMemory.AI.OpenAI.GPT3; using Python.Runtime; +using Serilog; using System; using System.Collections.Generic; using System.Linq; @@ -92,7 +93,7 @@ namespace AntSK.Domain.Domain.Other.Bge public static void Dispose() { - Console.WriteLine("python dispose"); + Log.Information("python dispose"); } } } diff --git a/src/AntSK.Domain/Domain/Service/FunctionService.cs b/src/AntSK.Domain/Domain/Service/FunctionService.cs index 8a1ce04..1c57bec 100644 --- a/src/AntSK.Domain/Domain/Service/FunctionService.cs +++ b/src/AntSK.Domain/Domain/Service/FunctionService.cs @@ -8,6 +8,7 @@ using System.Text.RegularExpressions; using Microsoft.SemanticKernel; using HtmlAgilityPack; using System.Collections.Generic; +using Serilog; namespace AntSK.Domain.Domain.Service { @@ -115,7 +116,7 @@ namespace AntSK.Domain.Domain.Service } catch (Exception ex) { - Console.WriteLine(ex.Message + " ---- " + ex.StackTrace); + Log.Error(ex.Message + " ---- " + ex.StackTrace); } } } diff --git a/src/AntSK.Domain/Domain/Service/ImportKMSService.cs b/src/AntSK.Domain/Domain/Service/ImportKMSService.cs index b03d7c6..97ef7a3 100644 --- a/src/AntSK.Domain/Domain/Service/ImportKMSService.cs +++ b/src/AntSK.Domain/Domain/Service/ImportKMSService.cs @@ -5,6 +5,7 @@ using AntSK.Domain.Domain.Model.Constant; using AntSK.Domain.Domain.Model.Excel; using AntSK.Domain.Domain.Other; using AntSK.Domain.Repositories; +using Microsoft.Extensions.Logging; using Microsoft.KernelMemory; using Microsoft.KernelMemory.Handlers; using System.Text; @@ -15,7 +16,8 @@ namespace AntSK.Domain.Domain.Service public class ImportKMSService( IKMService _kMService, IKmsDetails_Repositories _kmsDetails_Repositories, - IKmss_Repositories _kmss_Repositories + IKmss_Repositories _kmss_Repositories, + ILogger _logger ) : IImportKMSService { @@ -140,13 +142,13 @@ namespace AntSK.Domain.Domain.Service req.KmsDetail.Status = Model.Enum.ImportKmsStatus.Success; _kmsDetails_Repositories.Update(req.KmsDetail); //_kmsDetails_Repositories.GetList(p => p.KmsId == req.KmsId); - Console.WriteLine("后台导入任务成功:" + req.KmsDetail.DataCount); + _logger.LogInformation("后台导入任务成功:" + req.KmsDetail.DataCount); } catch (Exception ex) { req.KmsDetail.Status = Model.Enum.ImportKmsStatus.Fail; _kmsDetails_Repositories.Update(req.KmsDetail); - Console.WriteLine("后台导入任务异常:" + ex.Message); + _logger.LogError("后台导入任务异常:" + ex.Message); } } } diff --git a/src/AntSK.Domain/Domain/Service/KernelService.cs b/src/AntSK.Domain/Domain/Service/KernelService.cs index e072a1b..aacd07a 100644 --- a/src/AntSK.Domain/Domain/Service/KernelService.cs +++ b/src/AntSK.Domain/Domain/Service/KernelService.cs @@ -22,6 +22,8 @@ using Microsoft.KernelMemory; using OpenCvSharp.ML; using LLamaSharp.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.ChatCompletion; +using Amazon.Runtime.Internal.Util; +using Microsoft.Extensions.Logging; namespace AntSK.Domain.Domain.Service { @@ -33,17 +35,20 @@ namespace AntSK.Domain.Domain.Service private readonly FunctionService _functionService; private readonly IServiceProvider _serviceProvider; private Kernel _kernel; + private readonly ILogger _logger; public KernelService( IApis_Repositories apis_Repositories, IAIModels_Repositories aIModels_Repositories, FunctionService functionService, - IServiceProvider serviceProvider) + IServiceProvider serviceProvider, + ILogger logger) { _apis_Repositories = apis_Repositories; _aIModels_Repositories = aIModels_Repositories; _functionService = functionService; _serviceProvider = serviceProvider; + _logger = logger; } /// @@ -224,7 +229,7 @@ namespace AntSK.Domain.Domain.Service { try { - Console.WriteLine(jsonBody); + _logger.LogInformation(jsonBody); RestClient client = new RestClient(); RestRequest request = new RestRequest(api.Url, Method.Post); foreach (var header in api.Header.ConvertToString().Split("\n")) diff --git a/src/AntSK.Domain/Domain/Service/LLamaFactoryService.cs b/src/AntSK.Domain/Domain/Service/LLamaFactoryService.cs index d7379e3..b215ba1 100644 --- a/src/AntSK.Domain/Domain/Service/LLamaFactoryService.cs +++ b/src/AntSK.Domain/Domain/Service/LLamaFactoryService.cs @@ -1,9 +1,11 @@ -using AntSK.Domain.Common.DependencyInjection; +using Amazon.Runtime.Internal.Util; +using AntSK.Domain.Common.DependencyInjection; using AntSK.Domain.Domain.Interface; using AntSK.Domain.Domain.Model.Dto; using AntSK.Domain.Options; using AntSK.LLamaFactory.Model; using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -17,7 +19,7 @@ using System.Threading.Tasks; namespace AntSK.Domain.Domain.Service { [ServiceDescription(typeof(ILLamaFactoryService), ServiceLifetime.Singleton)] - public class LLamaFactoryService : ILLamaFactoryService + public class LLamaFactoryService(ILogger _logger) : ILLamaFactoryService { private Process process; @@ -26,7 +28,7 @@ namespace AntSK.Domain.Domain.Service private readonly object _syncLock = new object(); private List modelList = new List(); - public LLamaFactoryService() { } + public delegate Task LogMessageHandler(string message); public event LogMessageHandler LogMessageReceived; protected virtual async Task OnLogMessageReceived(string message) @@ -56,12 +58,12 @@ namespace AntSK.Domain.Domain.Service }; process.OutputDataReceived += (sender, eventArgs) => { - Console.WriteLine($"{eventArgs.Data}"); + _logger.LogInformation($"{eventArgs.Data}"); OnLogMessageReceived(eventArgs.Data); }; process.ErrorDataReceived += (sender, eventArgs) => { - Console.WriteLine($"{eventArgs.Data}"); + _logger.LogInformation($"{eventArgs.Data}"); OnLogMessageReceived(eventArgs.Data); }; process.Start(); @@ -97,12 +99,12 @@ namespace AntSK.Domain.Domain.Service process.StartInfo.EnvironmentVariables["USE_MODELSCOPE_HUB"] = Environment.GetEnvironmentVariable("USE_MODELSCOPE_HUB") ?? "1"; process.OutputDataReceived += (sender, eventArgs) => { - Console.WriteLine($"{eventArgs.Data}"); + _logger.LogInformation($"{eventArgs.Data}"); OnLogMessageReceived(eventArgs.Data); }; process.ErrorDataReceived += (sender, eventArgs) => { - Console.WriteLine($"{eventArgs.Data}"); + _logger.LogInformation($"{eventArgs.Data}"); OnLogMessageReceived(eventArgs.Data); }; process.Start(); @@ -137,7 +139,7 @@ namespace AntSK.Domain.Domain.Service if (process1.ProcessName.ToLower() == "python") { process1.Kill(); - System.Console.WriteLine("kill python"); + _logger.LogInformation("kill python"); } } } diff --git a/src/AntSK.Domain/Options/FileDirOption.cs b/src/AntSK.Domain/Options/FileDirOption.cs new file mode 100644 index 0000000..e23cc23 --- /dev/null +++ b/src/AntSK.Domain/Options/FileDirOption.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AntSK.Domain.Options +{ + public class FileDirOption + { + public static string DirectoryPath { get; set; } = Directory.GetCurrentDirectory(); + } +} diff --git a/src/AntSK.Domain/Options/LLamaSharpOption.cs b/src/AntSK.Domain/Options/LLamaSharpOption.cs index 0e93939..caa43c0 100644 --- a/src/AntSK.Domain/Options/LLamaSharpOption.cs +++ b/src/AntSK.Domain/Options/LLamaSharpOption.cs @@ -3,6 +3,5 @@ public class LLamaSharpOption { public static string RunType { get; set; } - public static string FileDirectory { get; set; } = Directory.GetCurrentDirectory(); } } diff --git a/src/AntSK.Domain/Utils/OpenAIHttpClientHandler.cs b/src/AntSK.Domain/Utils/OpenAIHttpClientHandler.cs index f64b63f..c99839d 100644 --- a/src/AntSK.Domain/Utils/OpenAIHttpClientHandler.cs +++ b/src/AntSK.Domain/Utils/OpenAIHttpClientHandler.cs @@ -1,4 +1,6 @@ -using System.Text.RegularExpressions; + +using Serilog; +using System.Text.RegularExpressions; namespace AntSK.Domain.Utils { @@ -19,7 +21,7 @@ namespace AntSK.Domain.Utils { string requestBody = await request.Content.ReadAsStringAsync(); //便于调试查看请求prompt - Console.WriteLine(requestBody); + Log.Information(requestBody); } if (match.Success) { diff --git a/src/AntSK.ServiceDefaults/AntSK.ServiceDefaults.csproj b/src/AntSK.ServiceDefaults/AntSK.ServiceDefaults.csproj new file mode 100644 index 0000000..589e391 --- /dev/null +++ b/src/AntSK.ServiceDefaults/AntSK.ServiceDefaults.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + enable + enable + true + + + + + + + + + + + + + + + diff --git a/src/AntSK.ServiceDefaults/Extensions.cs b/src/AntSK.ServiceDefaults/Extensions.cs new file mode 100644 index 0000000..2a3f4e0 --- /dev/null +++ b/src/AntSK.ServiceDefaults/Extensions.cs @@ -0,0 +1,118 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.ServiceDiscovery; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.Hosting; + +// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. +// This project should be referenced by each service project in your solution. +// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults +public static class Extensions +{ + public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder) + { + builder.ConfigureOpenTelemetry(); + + builder.AddDefaultHealthChecks(); + + builder.Services.AddServiceDiscovery(); + + builder.Services.ConfigureHttpClientDefaults(http => + { + // Turn on resilience by default + http.AddStandardResilienceHandler(); + + // Turn on service discovery by default + http.AddServiceDiscovery(); + }); + + // Uncomment the following to restrict the allowed schemes for service discovery. + // builder.Services.Configure(options => + // { + // options.AllowedSchemes = ["https"]; + // }); + + return builder; + } + + public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder) + { + builder.Logging.AddOpenTelemetry(logging => + { + logging.IncludeFormattedMessage = true; + logging.IncludeScopes = true; + }); + + builder.Services.AddOpenTelemetry() + .WithMetrics(metrics => + { + metrics.AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddRuntimeInstrumentation(); + }) + .WithTracing(tracing => + { + tracing.AddAspNetCoreInstrumentation() + // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) + //.AddGrpcClientInstrumentation() + .AddHttpClientInstrumentation(); + }); + + builder.AddOpenTelemetryExporters(); + + return builder; + } + + private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder) + { + var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); + + if (useOtlpExporter) + { + builder.Services.AddOpenTelemetry().UseOtlpExporter(); + } + + // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package) + //if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"])) + //{ + // builder.Services.AddOpenTelemetry() + // .UseAzureMonitor(); + //} + + return builder; + } + + public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicationBuilder builder) + { + builder.Services.AddHealthChecks() + // Add a default liveness check to ensure app is responsive + .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]); + + return builder; + } + + public static WebApplication MapDefaultEndpoints(this WebApplication app) + { + // Adding health checks endpoints to applications in non-development environments has security implications. + // See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments. + if (app.Environment.IsDevelopment()) + { + // All health checks must pass for app to be considered ready to accept traffic after starting + app.MapHealthChecks("/health"); + + // Only health checks tagged with the "live" tag must pass for app to be considered alive + app.MapHealthChecks("/alive", new HealthCheckOptions + { + Predicate = r => r.Tags.Contains("live") + }); + } + + return app; + } +} diff --git a/src/AntSK.sln b/src/AntSK.sln index c26d2fd..79f126a 100644 --- a/src/AntSK.sln +++ b/src/AntSK.sln @@ -27,6 +27,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.LLamaFactory", "AntSK EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.OCR", "AntSK.OCR\AntSK.OCR.csproj", "{6195F7AA-18C2-4372-85CA-11FC4B522686}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aspire", "Aspire", "{8578F0F2-5DE5-45EF-AE54-C37A07B62248}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AntSKWeb", "AntSKWeb", "{F341BA6B-E329-42F7-8005-1E366C8A7B1F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.AppHost", "AntSK.AppHost\AntSK.AppHost.csproj", "{3EEC5A22-2C4D-4D6F-9039-C4AF3FEA3418}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.ServiceDefaults", "AntSK.ServiceDefaults\AntSK.ServiceDefaults.csproj", "{21AC6184-336E-475F-8975-80A39D59B0CC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -61,12 +69,28 @@ Global {6195F7AA-18C2-4372-85CA-11FC4B522686}.Debug|Any CPU.Build.0 = Debug|Any CPU {6195F7AA-18C2-4372-85CA-11FC4B522686}.Release|Any CPU.ActiveCfg = Release|Any CPU {6195F7AA-18C2-4372-85CA-11FC4B522686}.Release|Any CPU.Build.0 = Release|Any CPU + {3EEC5A22-2C4D-4D6F-9039-C4AF3FEA3418}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3EEC5A22-2C4D-4D6F-9039-C4AF3FEA3418}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3EEC5A22-2C4D-4D6F-9039-C4AF3FEA3418}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3EEC5A22-2C4D-4D6F-9039-C4AF3FEA3418}.Release|Any CPU.Build.0 = Release|Any CPU + {21AC6184-336E-475F-8975-80A39D59B0CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {21AC6184-336E-475F-8975-80A39D59B0CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {21AC6184-336E-475F-8975-80A39D59B0CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {21AC6184-336E-475F-8975-80A39D59B0CC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {9AA5A735-8FB1-4CC5-AB3E-D02B3A3B6682} = {F341BA6B-E329-42F7-8005-1E366C8A7B1F} + {64F17C9A-97C2-46FA-9345-86C5289288AD} = {F341BA6B-E329-42F7-8005-1E366C8A7B1F} {DF87E829-99C5-44A7-9718-B3E67DC801F6} = {40DDB1DC-571B-4A95-9F34-47F52981C511} + {19529BFA-152F-4A8C-8254-F2D4896AB739} = {F341BA6B-E329-42F7-8005-1E366C8A7B1F} + {6AD71410-127F-4C83-95A8-F699C39B44FF} = {F341BA6B-E329-42F7-8005-1E366C8A7B1F} + {664DFA1F-68B7-49C7-B889-FA14D1756D3D} = {F341BA6B-E329-42F7-8005-1E366C8A7B1F} + {6195F7AA-18C2-4372-85CA-11FC4B522686} = {F341BA6B-E329-42F7-8005-1E366C8A7B1F} + {3EEC5A22-2C4D-4D6F-9039-C4AF3FEA3418} = {8578F0F2-5DE5-45EF-AE54-C37A07B62248} + {21AC6184-336E-475F-8975-80A39D59B0CC} = {8578F0F2-5DE5-45EF-AE54-C37A07B62248} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2076B7C9-2E5B-4580-9712-03F0D56BC1AF} diff --git a/src/AntSK/AntSK.csproj b/src/AntSK/AntSK.csproj index 447af36..8754ead 100644 --- a/src/AntSK/AntSK.csproj +++ b/src/AntSK/AntSK.csproj @@ -29,6 +29,7 @@ + diff --git a/src/AntSK/Controllers/FileController.cs b/src/AntSK/Controllers/FileController.cs index fc13934..267c792 100644 --- a/src/AntSK/Controllers/FileController.cs +++ b/src/AntSK/Controllers/FileController.cs @@ -23,7 +23,7 @@ namespace AntSK.Controllers } // 创建文件存储的路径 - var uploadsFolderPath = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), LLamaSharpOption.FileDirectory), "files");// 给定的文件夹名称 + var uploadsFolderPath = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), FileDirOption.DirectoryPath), "files");// 给定的文件夹名称 // 如果路径不存在,则创建一个新的目录 if (!Directory.Exists(uploadsFolderPath)) diff --git a/src/AntSK/Pages/ChatPage/Components/ChatView.razor.cs b/src/AntSK/Pages/ChatPage/Components/ChatView.razor.cs index 43aa8ff..aa5bbc8 100644 --- a/src/AntSK/Pages/ChatPage/Components/ChatView.razor.cs +++ b/src/AntSK/Pages/ChatPage/Components/ChatView.razor.cs @@ -7,6 +7,7 @@ using AntSK.Domain.Repositories; using AntSK.Domain.Utils; using AntSK.LLM.StableDiffusion; using AntSK.Models; +using AntSK.Pages.KmsPage; using Blazored.LocalStorage; using DocumentFormat.OpenXml.InkML; using Markdig; @@ -43,6 +44,8 @@ namespace AntSK.Pages.ChatPage.Components [Inject] IChats_Repositories _chats_Repositories { get; set; } [Inject] ProtectedSessionStorage _protectedSessionStore { get; set; } + [Inject] protected ILogger _logger { get; set; } + protected List MessageList = []; protected string? _messageInput; protected string _json = ""; @@ -201,7 +204,7 @@ namespace AntSK.Pages.ChatPage.Components catch (System.Exception ex) { Sendding = false; - Console.WriteLine("异常:" + ex.Message); + _logger.LogError("异常:" + ex.Message); _ = Message.Error("异常:" + ex.Message, 2); } diff --git a/src/AntSK/Pages/KmsPage/KmsDetail.razor.cs b/src/AntSK/Pages/KmsPage/KmsDetail.razor.cs index 94cb652..ac08bdc 100644 --- a/src/AntSK/Pages/KmsPage/KmsDetail.razor.cs +++ b/src/AntSK/Pages/KmsPage/KmsDetail.razor.cs @@ -41,6 +41,8 @@ namespace AntSK.Pages.KmsPage [Inject] protected IHttpService _httpService { get; set; } + [Inject] + protected ILogger _logger { get; set; } private Kmss km; @@ -127,7 +129,7 @@ namespace AntSK.Pages.KmsPage } catch (System.Exception ex) { - Console.WriteLine(ex.Message + " ---- " + ex.StackTrace); + _logger.LogError(ex.Message + " ---- " + ex.StackTrace); } } @@ -169,7 +171,7 @@ namespace AntSK.Pages.KmsPage } catch (System.Exception ex) { - Console.WriteLine(ex.Message + " ---- " + ex.StackTrace); + _logger.LogError(ex.Message + " ---- " + ex.StackTrace); } } @@ -210,7 +212,7 @@ namespace AntSK.Pages.KmsPage } catch (System.Exception ex) { - Console.WriteLine(ex.Message + " ---- " + ex.StackTrace); + _logger.LogError(ex.Message + " ---- " + ex.StackTrace); } } @@ -250,7 +252,7 @@ namespace AntSK.Pages.KmsPage } catch (System.Exception ex) { - Console.WriteLine(ex.Message + " ---- " + ex.StackTrace); + _logger.LogError(ex.Message + " ---- " + ex.StackTrace); } } @@ -289,7 +291,7 @@ namespace AntSK.Pages.KmsPage } catch (System.Exception ex) { - Console.WriteLine(ex.Message + " ---- " + ex.StackTrace); + _logger.LogError(ex.Message + " ---- " + ex.StackTrace); } finally { diff --git a/src/AntSK/Pages/Plugin/FunPage/FunList.razor.cs b/src/AntSK/Pages/Plugin/FunPage/FunList.razor.cs index 6d2c177..34bc2c1 100644 --- a/src/AntSK/Pages/Plugin/FunPage/FunList.razor.cs +++ b/src/AntSK/Pages/Plugin/FunPage/FunList.razor.cs @@ -4,6 +4,7 @@ using AntSK.Domain.Domain.Model.Fun; using AntSK.Domain.Domain.Service; using AntSK.Domain.Repositories; using AntSK.Models; +using AntSK.Pages.KmsPage; using DocumentFormat.OpenXml.Office2010.Excel; using HtmlAgilityPack; using Microsoft.AspNetCore.Components; @@ -27,7 +28,7 @@ namespace AntSK.Pages.FunPage [Inject] protected MessageService? _message { get; set; } - + [Inject] protected ILogger _logger { get; set; } bool _fileVisible = false; bool _fileConfirmLoading = false; @@ -102,7 +103,7 @@ namespace AntSK.Pages.FunPage } catch (System.Exception ex) { - Console.WriteLine(ex.Message + " ---- " + ex.StackTrace); + _logger.LogError(ex.Message + " ---- " + ex.StackTrace); } } private void FileHandleCancel(MouseEventArgs e) diff --git a/src/AntSK/Pages/Setting/AIModel/AddModel.razor.cs b/src/AntSK/Pages/Setting/AIModel/AddModel.razor.cs index e368683..42705f7 100644 --- a/src/AntSK/Pages/Setting/AIModel/AddModel.razor.cs +++ b/src/AntSK/Pages/Setting/AIModel/AddModel.razor.cs @@ -88,7 +88,7 @@ namespace AntSK.Pages.Setting.AIModel //目前只支持gguf的 所以筛选一下 - _modelFiles = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), LLamaSharpOption.FileDirectory)).Where(p=> p.Contains(".gguf")||p.Contains(".ckpt")|| p.Contains(".safetensors")).ToArray(); + _modelFiles = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), FileDirOption.DirectoryPath)).Where(p=> p.Contains(".gguf")||p.Contains(".ckpt")|| p.Contains(".safetensors")).ToArray(); if (!string.IsNullOrEmpty(ModelPath)) { string extension = Path.GetExtension(ModelPath); @@ -167,7 +167,7 @@ namespace AntSK.Pages.Setting.AIModel _download = DownloadBuilder.New() .WithUrl(_downloadUrl) - .WithDirectory(Path.Combine(Directory.GetCurrentDirectory(), LLamaSharpOption.FileDirectory)) + .WithDirectory(Path.Combine(Directory.GetCurrentDirectory(), FileDirOption.DirectoryPath)) .WithConfiguration(new DownloadConfiguration() { ParallelCount = 5, @@ -195,7 +195,7 @@ namespace AntSK.Pages.Setting.AIModel _aiModel.ModelName = _download.Package.FileName; _downloadModalVisible = false; _downloadStarted = false; - _modelFiles = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), LLamaSharpOption.FileDirectory)); + _modelFiles = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), FileDirOption.DirectoryPath)); InvokeAsync(StateHasChanged); } diff --git a/src/AntSK/Program.cs b/src/AntSK/Program.cs index 163e6dd..b3804cc 100644 --- a/src/AntSK/Program.cs +++ b/src/AntSK/Program.cs @@ -15,6 +15,8 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.OpenApi.Models; +using OpenTelemetry.Exporter; +using Serilog; using Swashbuckle.AspNetCore.SwaggerGen; using System.Reflection; using System.Text.Encodings.Web; @@ -30,6 +32,26 @@ builder.Services.AddControllers().AddJsonOptions(config => config.JsonSerializerOptions.Converters.Add(new DateTimeConverter()); config.JsonSerializerOptions.Converters.Add(new DateTimeNullableConvert()); }); + +builder.Configuration.GetSection("DBConnection").Get(); +builder.Configuration.GetSection("Login").Get(); +builder.Configuration.GetSection("LLamaSharp").Get(); +builder.Configuration.GetSection("KernelMemory").Get(); +builder.Configuration.GetSection("FileDir").Get(); + +builder.Services.Configure( + o => o.Headers = $"x-otlp-api-key=antsk"); + +Log.Logger = new LoggerConfiguration() +.ReadFrom.Configuration(builder.Configuration) +.CreateLogger(); + +var loggerFactory = LoggerFactory.Create(builder => { + builder.ClearProviders(); + builder.AddSerilog(); +}); +ILogger logger = loggerFactory.CreateLogger(); +InitExtensions.InitLog(logger); // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); @@ -56,18 +78,14 @@ builder.Services.AddMapper(); //后台队列任务 builder.Services.AddBackgroundTaskBroker().AddHandler("ImportKMSTask"); // 读取连接字符串配置 -{ - builder.Configuration.GetSection("DBConnection").Get(); - builder.Configuration.GetSection("Login").Get(); - builder.Configuration.GetSection("LLamaSharp").Get(); - builder.Configuration.GetSection("KernelMemory").Get(); + if (LLamaSharpOption.RunType.ToUpper() == "CPU") { NativeLibraryConfig .Instance .WithCuda(false) .WithLogCallback((level, message) => { - Console.WriteLine($"[llama {level}]: {message.TrimEnd('\n')}"); + logger.LogInformation($"[llama {level}]: {message.TrimEnd('\n')}"); }); } else if (LLamaSharpOption.RunType.ToUpper() == "GPU") @@ -76,11 +94,11 @@ builder.Services.AddBackgroundTaskBroker().AddHandler { - Console.WriteLine($"[llama {level}]: {message.TrimEnd('\n')}"); + logger.LogInformation($"[llama {level}]: {message.TrimEnd('\n')}"); }) .WithAvx(NativeLibraryConfig.AvxLevel.Avx); } -} + //增加API允许跨域调用 builder.Services.AddCors(options => options.AddPolicy("Any", diff --git a/src/AntSK/Services/OpenApi/OpenApiService.cs b/src/AntSK/Services/OpenApi/OpenApiService.cs index baa9e2f..f27e521 100644 --- a/src/AntSK/Services/OpenApi/OpenApiService.cs +++ b/src/AntSK/Services/OpenApi/OpenApiService.cs @@ -52,9 +52,6 @@ namespace AntSK.Services.OpenApi result1.choices = new List() { new StreamChoicesModel() { delta = new OpenAIMessage() { role = "assistant" } } }; await SendChatStream(HttpContext, result1, app,history); - HttpContext.Response.ContentType = "application/json"; - await HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(result1)); - await HttpContext.Response.CompleteAsync(); return; } else @@ -79,9 +76,6 @@ namespace AntSK.Services.OpenApi result3.choices = new List() { new StreamChoicesModel() { delta = new OpenAIMessage() { role = "assistant" } } }; await SendKmsStream(HttpContext, result3, app, questions,history); - HttpContext.Response.ContentType = "application/json"; - await HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(result3)); - await HttpContext.Response.CompleteAsync(); } else { diff --git a/src/AntSK/appsettings.json b/src/AntSK/appsettings.json index 5a8579d..dd8ab79 100644 --- a/src/AntSK/appsettings.json +++ b/src/AntSK/appsettings.json @@ -7,7 +7,7 @@ "Microsoft.Hosting.Lifetime": "Information" } }, - "urls":"http://*:5000", + "urls": "http://*:5000", "ProSettings": { "NavTheme": "light", "Layout": "side", @@ -25,17 +25,19 @@ "HeaderHeight": 48 }, "DBConnection": { - "DbType": "Sqlite", + "DbType": "Sqlite", "ConnectionStrings": "Data Source=AntSK.db;" }, "KernelMemory": { - "VectorDb": "Disk", + "VectorDb": "Disk", "ConnectionString": "Host=;Port=;Database=antsk;Username=;Password=", "TableNamePrefix": "km-" }, "LLamaSharp": { - "RunType": "GPU", - "FileDirectory": "D:\\git\\AntBlazor\\model" + "RunType": "GPU" + }, + "FileDir": { + "DirectoryPath": "D:\\model" }, "Login": { "User": "admin", @@ -43,7 +45,29 @@ }, "BackgroundTaskBroker": { "ImportKMSTask": { - "WorkerCount": 1 + "WorkerCount": 1 } + }, + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.Seq", "Serilog.Sinks.File" ], + "MinimumLevel": "Debug", + "WriteTo": [ + { "Name": "Console" }, + { + "Name": "OpenTelemetry", + "Args": { + "Endpoint": "http://aspire-dashboard:18889" + } + }, + { + "Name": "File", + "Args": { + "path": "D:\\model\\logs\\log-.txt", + "rollingInterval": "Day", + "fileSizeLimitBytes": 10485760 + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] } }