├── .editorconfig ├── .github └── workflows │ ├── publish-beta.yml │ ├── publish.yml │ └── test.yml ├── .gitignore ├── ClientTest ├── AgentInfoTests.cs ├── AppInfoTests.cs ├── AppServiceTests.cs ├── ClientTest.csproj ├── ConfigTests.cs ├── DiagnosticTests.cs ├── LocalStarClientTests.cs ├── StarClientTests.cs ├── StarFactoryTests.cs ├── TokenModelTests.cs └── appsettings.json ├── DeployAgent ├── Commands │ ├── DeployCommand.cs │ ├── ICommand.cs │ └── PackCommand.cs ├── DeployAgent.csproj ├── DeploySetting.cs ├── DeployWorker.cs ├── Program.cs └── Properties │ ├── PublishProfiles │ └── win-x64.pubxml │ └── launchSettings.json ├── Doc ├── ProcessStart.md ├── StarInstall.bat ├── ab_http.png ├── clear.bat ├── leaf.png ├── newlife.snk ├── staragent.sh ├── web.config ├── 关系图.png ├── 应用监控.png ├── 星尘分布式.emmx ├── 星尘分布式.png ├── 星尘分布式.svg ├── 星尘发布.emmx ├── 星尘发布.png ├── 服务注册.emmx ├── 本地通信.emmx └── 调用链.png ├── Installer ├── Command.cs ├── Installer.csproj ├── Program.cs └── app.manifest ├── LICENSE ├── Plugins ├── MySqlAgent │ ├── BinlogClear.cs │ ├── MySqlAgent.csproj │ └── MySqlPlugin.cs └── NetworkDetect │ ├── NetDetect.cs │ ├── NetworkDetect.csproj │ ├── NetworkDetectSetting.cs │ ├── ServiceItem.cs │ └── Worker.cs ├── Readme.MD ├── Samples ├── TestA │ ├── Program.cs │ ├── Properties │ │ └── PublishProfiles │ │ │ └── FolderProfile.pubxml │ └── TestA.csproj ├── TestB │ ├── Program.cs │ ├── Properties │ │ └── PublishProfiles │ │ │ └── FolderProfile.pubxml │ └── TestB.csproj └── TestC │ ├── Program.cs │ ├── Properties │ └── PublishProfiles │ │ └── FolderProfile.pubxml │ └── TestC.csproj ├── StarAgent ├── CommandHandler │ ├── ShowMachineInfo.cs │ ├── UseMicroService.cs │ └── UseStarServer.cs ├── MyStarClient.cs ├── Program.cs ├── Properties │ └── PublishProfiles │ │ ├── FolderProfile.pubxml │ │ ├── linux-arm.pubxml │ │ ├── linux-x64.pubxml │ │ └── win-x64.pubxml ├── Setting.cs ├── StarAgent.csproj ├── StarService.cs ├── StarService2.cs └── app.manifest ├── StarAgentTool └── StarAgentTool.csproj ├── StarGateway ├── Host.cs ├── InitService.cs ├── MyService.cs ├── Program.cs ├── Properties │ └── PublishProfiles │ │ └── FolderProfile.pubxml ├── Proxy │ ├── HttpReverseProxy.cs │ ├── NATProxy.cs │ ├── ProxyServer.cs │ └── ProxySession.cs ├── Setting.cs └── StarGateway.csproj ├── Stardust.Data ├── Configs │ ├── Model.xml │ ├── Stardust.htm │ ├── 应用依赖.Biz.cs │ ├── 应用依赖.cs │ ├── 应用规则.Biz.cs │ ├── 应用规则.cs │ ├── 应用配置.Biz.cs │ ├── 应用配置.cs │ ├── 配置历史.Biz.cs │ ├── 配置历史.cs │ ├── 配置在线.Biz.cs │ ├── 配置在线.cs │ ├── 配置数据.Biz.cs │ └── 配置数据.cs ├── Deployment │ ├── Model.xml │ ├── Stardust.htm │ ├── 应用节点.Biz.cs │ ├── 应用节点.cs │ ├── 应用部署.Biz.cs │ ├── 应用部署.cs │ ├── 部署历史.Biz.cs │ ├── 部署历史.cs │ ├── 部署版本.Biz.cs │ ├── 部署版本.cs │ ├── 附件.Biz.cs │ └── 附件.cs ├── Entity │ ├── Model.xml │ ├── Stardust.htm │ ├── 应用历史.Biz.cs │ ├── 应用历史.cs │ ├── 应用命令.Biz.cs │ ├── 应用命令.cs │ ├── 应用在线.Biz.cs │ ├── 应用在线.cs │ ├── 应用性能.Biz.cs │ ├── 应用性能.cs │ ├── 应用日志.Biz.cs │ ├── 应用日志.cs │ ├── 应用服务.Biz.cs │ ├── 应用服务.cs │ ├── 应用消费.Biz.cs │ ├── 应用消费.cs │ ├── 应用系统.Biz.cs │ ├── 应用系统.cs │ ├── 服务信息.Biz.cs │ └── 服务信息.cs ├── Models │ └── RedisDbEntry.cs ├── Monitors │ ├── Model.xml │ ├── Stardust.htm │ ├── TraceStatModel.cs │ ├── 告警历史.Biz.cs │ ├── 告警历史.cs │ ├── 告警组.Biz.cs │ ├── 告警组.cs │ ├── 应用分钟统计.Biz.cs │ ├── 应用分钟统计.cs │ ├── 应用每日统计.Biz.cs │ ├── 应用每日统计.cs │ ├── 应用跟踪器.Biz.cs │ ├── 应用跟踪器.cs │ ├── 跟踪分钟统计.Biz.cs │ ├── 跟踪分钟统计.cs │ ├── 跟踪小时统计.Biz.cs │ ├── 跟踪小时统计.cs │ ├── 跟踪数据.Biz.cs │ ├── 跟踪数据.cs │ ├── 跟踪每日统计.Biz.cs │ ├── 跟踪每日统计.cs │ ├── 跟踪规则.Biz.cs │ ├── 跟踪规则.cs │ ├── 跟踪项.Biz.cs │ ├── 跟踪项.cs │ ├── 采样数据.Biz.cs │ ├── 采样数据.cs │ ├── 采样数据2.Biz.cs │ └── 采样数据2.cs ├── NodeResolver.cs ├── Nodes │ ├── Model.xml │ ├── Stardust.htm │ ├── 节点.Biz.cs │ ├── 节点.cs │ ├── 节点历史.Biz.cs │ ├── 节点历史.cs │ ├── 节点命令.Biz.cs │ ├── 节点命令.cs │ ├── 节点在线.Biz.cs │ ├── 节点在线.cs │ ├── 节点定位.Biz.cs │ ├── 节点定位.cs │ ├── 节点数据.Biz.cs │ ├── 节点数据.cs │ ├── 节点版本.Biz.cs │ ├── 节点版本.cs │ ├── 节点统计.Biz.cs │ ├── 节点统计.cs │ ├── 节点规则.Biz.cs │ └── 节点规则.cs ├── Platform │ ├── Model.xml │ ├── Stardust.htm │ ├── 星系项目.Biz.cs │ ├── 星系项目.cs │ ├── 项目用户关系.Biz.cs │ └── 项目用户关系.cs ├── RedisNodes │ ├── Model.xml │ ├── Redis数据.Biz.cs │ ├── Redis数据.cs │ ├── Redis消息队列.Biz.cs │ ├── Redis消息队列.cs │ ├── Redis节点.Biz.cs │ └── Redis节点.cs ├── RobotHelper.cs ├── Stardust.Data.csproj ├── xcodetool.bat └── xcodetool.exe ├── Stardust.Extensions ├── Caches │ ├── CacheDirectoryContents.cs │ ├── CacheFileProvider.cs │ ├── FileCacheExtensions.cs │ └── FileInfoModel.cs ├── IpFilterMiddleware.cs ├── RegistryMiddleware.cs ├── StarFactoryExtensions.cs ├── StarService.cs ├── Stardust.Extensions.csproj ├── TracerMiddleware.cs └── WebHelper.cs ├── Stardust.Server ├── .config │ └── dotnet-tools.json ├── Common │ ├── ApiFilterAttribute.cs │ ├── DateTimeConverter.cs │ ├── JsonConverter.cs │ ├── JsonConverterForBuilder.cs │ ├── TokenFilter.cs │ ├── TokenSession.cs │ ├── WebHelper.cs │ └── XLogger.cs ├── Controllers │ ├── ApiController.cs │ ├── AppController.cs │ ├── BaseController.cs │ ├── ConfigController.cs │ ├── CubeController.cs │ ├── DeployController.cs │ ├── DustController.cs │ ├── LogController.cs │ ├── NodeController.cs │ ├── OAuthController.cs │ └── TraceController.cs ├── DiscoverService.cs ├── Models │ ├── CommandInModel.cs │ ├── ConfigInModel.cs │ ├── SetConfigModel.cs │ └── TokenInModel.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Services │ ├── AlarmService.cs │ ├── ApolloService.cs │ ├── AppDayStatService.cs │ ├── AppOnlineService.cs │ ├── AppQueueService.cs │ ├── AppSessionManager.cs │ ├── CacheFileProvider.cs │ ├── ConfigService.cs │ ├── DataRetentionService.cs │ ├── DeployService.cs │ ├── MonitorService.cs │ ├── NodeOnlineService.cs │ ├── NodeService.cs │ ├── NodeSessionManager.cs │ ├── NodeStatService.cs │ ├── OnlineService.cs │ ├── RedisService.cs │ ├── RegistryService.cs │ ├── ShardTableService.cs │ ├── TokenService.cs │ ├── TraceItemStatService.cs │ ├── TraceStatService.cs │ └── UplinkService.cs ├── Setting.cs ├── StarService.cs ├── Stardust.Server.csproj ├── Startup.cs └── appsettings.json ├── Stardust.ServerTests ├── AppRuleTests.cs ├── Apps │ └── AppTests.cs ├── Controllers │ ├── ApiTests.cs │ ├── OAuthControllerTests.cs │ └── WebSocketTests.cs ├── NodeTests.cs ├── Nodes │ ├── NodeLevelTests.cs │ ├── NodeStatTests.cs │ └── NodeVersionTests.cs ├── Services │ ├── AppServiceTests.cs │ └── MonitorServiceTests.cs ├── Stardust.ServerTests.csproj ├── TraceRuleTests.cs └── appsettings.json ├── Stardust.Web.Vue ├── index.html ├── lib │ ├── CubeUI.js │ ├── CubeUI.js.map │ ├── favicon.ico │ └── style.css ├── package.json ├── public │ └── leaf.png ├── src │ ├── App.vue │ ├── CubeUI │ │ └── index.js │ ├── main.ts │ └── views │ │ ├── Admin │ │ └── Role │ │ │ └── config.tsx │ │ ├── Deployment │ │ └── AppDeploy │ │ │ └── config.tsx │ │ ├── Nodes │ │ └── Node │ │ │ └── config.tsx │ │ └── School │ │ └── Student │ │ └── list.vue ├── tsconfig.json ├── tslint.json ├── vite.config.ts └── yarn.lock ├── Stardust.Web ├── .config │ └── dotnet-tools.json ├── Areas │ ├── Configs │ │ ├── ConfigsArea.cs │ │ ├── Controllers │ │ │ ├── AppConfigController.cs │ │ │ ├── AppQuoteController.cs │ │ │ ├── AppRuleController.cs │ │ │ ├── ConfigDataController.cs │ │ │ ├── ConfigHistoryController.cs │ │ │ └── ConfigOnlineController.cs │ │ └── Views │ │ │ ├── AppConfig │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Custom.cshtml │ │ │ ├── ConfigData │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Batch.cshtml │ │ │ ├── ConfigHistory │ │ │ └── _List_Search.cshtml │ │ │ └── _ViewImports.cshtml │ ├── Deployment │ │ ├── Controllers │ │ │ ├── AppDeployController.cs │ │ │ ├── AppDeployHistoryController.cs │ │ │ ├── AppDeployNodeController.cs │ │ │ ├── AppDeployOnlineController.cs │ │ │ ├── AppDeployVersionController.cs │ │ │ └── AttachmentController.cs │ │ ├── DeploymentArea.cs │ │ └── Views │ │ │ ├── AppDeploy │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Custom.cshtml │ │ │ ├── AppDeployNode │ │ │ ├── _Form_Body.cshtml │ │ │ ├── _Form_SelectNode.cshtml │ │ │ ├── _List_Data.cshtml │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Batch.cshtml │ │ │ ├── AppDeployVersion │ │ │ └── _Form_File.cshtml │ │ │ └── _ViewImports.cshtml │ ├── Monitors │ │ ├── Controllers │ │ │ ├── AlarmGroupController.cs │ │ │ ├── AlarmHistoryController.cs │ │ │ ├── AppDayStatController.cs │ │ │ ├── AppMinuteStatController.cs │ │ │ ├── AppTracerController.cs │ │ │ ├── SampleData2Controller.cs │ │ │ ├── SampleDataController.cs │ │ │ ├── TraceController.cs │ │ │ ├── TraceDataController.cs │ │ │ ├── TraceDayStatController.cs │ │ │ ├── TraceHourStatController.cs │ │ │ ├── TraceItemController.cs │ │ │ ├── TraceMinuteStatController.cs │ │ │ └── TraceRuleController.cs │ │ ├── MonitorsArea.cs │ │ └── Views │ │ │ ├── AppDayStat │ │ │ ├── _List_Data.cshtml │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Batch.cshtml │ │ │ ├── AppMinuteStat │ │ │ ├── _List_Data.cshtml │ │ │ └── _List_Search.cshtml │ │ │ ├── AppTracer │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Batch.cshtml │ │ │ ├── Trace │ │ │ └── Index.cshtml │ │ │ ├── TraceData │ │ │ ├── _List_Data.cshtml │ │ │ └── _List_Search.cshtml │ │ │ ├── TraceDayStat │ │ │ ├── _List_Data.cshtml │ │ │ └── _List_Search.cshtml │ │ │ ├── TraceHourStat │ │ │ ├── _List_Data.cshtml │ │ │ └── _List_Search.cshtml │ │ │ ├── TraceItem │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Batch.cshtml │ │ │ ├── TraceMinuteStat │ │ │ ├── _List_Data.cshtml │ │ │ └── _List_Search.cshtml │ │ │ └── _ViewImports.cshtml │ ├── Nodes │ │ ├── Controllers │ │ │ ├── NodeCommandController.cs │ │ │ ├── NodeController.cs │ │ │ ├── NodeDataController.cs │ │ │ ├── NodeFrameworkController.cs │ │ │ ├── NodeHistoryController.cs │ │ │ ├── NodeLocationController.cs │ │ │ ├── NodeOnlineController.cs │ │ │ ├── NodeRuleController.cs │ │ │ ├── NodeStatController.cs │ │ │ └── NodeVersionController.cs │ │ ├── NodesArea.cs │ │ └── Views │ │ │ ├── Node │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Batch.cshtml │ │ │ ├── NodeCommand │ │ │ └── _List_Search.cshtml │ │ │ ├── NodeData │ │ │ └── _List_Search.cshtml │ │ │ ├── NodeFramework │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Batch.cshtml │ │ │ ├── NodeHistory │ │ │ └── _List_Search.cshtml │ │ │ ├── NodeOnline │ │ │ ├── _List_Search.cshtml │ │ │ └── _List_Toolbar_Batch.cshtml │ │ │ ├── NodeStat │ │ │ └── _List_Search.cshtml │ │ │ ├── NodeVersion │ │ │ └── _List_Search.cshtml │ │ │ ├── Shared │ │ │ └── _SelectNode.cshtml │ │ │ └── _ViewImports.cshtml │ ├── Platform │ │ ├── Controllers │ │ │ ├── GalaxyProjectController.cs │ │ │ ├── ProjectUserController.cs │ │ │ └── StarServerController.cs │ │ └── PlatformArea.cs │ ├── Redis │ │ ├── Controllers │ │ │ ├── RedisDataController.cs │ │ │ ├── RedisMessageQueueController.cs │ │ │ └── RedisNodeController.cs │ │ ├── RedisArea.cs │ │ └── Views │ │ │ ├── RedisData │ │ │ └── _List_Search.cshtml │ │ │ ├── RedisMessageQueue │ │ │ └── _List_Search.cshtml │ │ │ ├── RedisNode │ │ │ └── _List_Search.cshtml │ │ │ ├── Shared │ │ │ └── _SelectRedis.cshtml │ │ │ └── _ViewImports.cshtml │ └── Registry │ │ ├── Controllers │ │ ├── AppClientLogController.cs │ │ ├── AppCommandController.cs │ │ ├── AppConsumeController.cs │ │ ├── AppController.cs │ │ ├── AppHistoryController.cs │ │ ├── AppLogController.cs │ │ ├── AppMeterController.cs │ │ ├── AppOnlineController.cs │ │ ├── AppServiceController.cs │ │ └── ServiceController.cs │ │ ├── RegistryArea.cs │ │ └── Views │ │ ├── App │ │ ├── _List_Search.cshtml │ │ └── _List_Toolbar_Batch.cshtml │ │ ├── AppHistory │ │ └── _List_Search.cshtml │ │ ├── AppLog │ │ └── _List_Search.cshtml │ │ ├── AppMeter │ │ └── _List_Search.cshtml │ │ ├── AppOnline │ │ ├── _List_Search.cshtml │ │ └── _List_Toolbar_Batch.cshtml │ │ └── _ViewImports.cshtml ├── Controllers │ ├── ConfigController.cs │ └── TraceController.cs ├── Models │ ├── GraphViewModel.cs │ ├── SelectAppModel.cs │ ├── SelectNodeModel.cs │ └── TraceViewModel.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Services │ ├── DeployService.cs │ └── FixDataHostedService.cs ├── Stardust.Web.csproj ├── Startup.cs ├── Views │ ├── Shared │ │ ├── _App_Nav.cshtml │ │ ├── _Node_Nav.cshtml │ │ ├── _Project_Nav.cshtml │ │ ├── _SelectApp.cshtml │ │ └── _SelectNode.cshtml │ ├── Trace │ │ ├── Detail.cshtml │ │ ├── Graph.cshtml │ │ ├── Index.cshtml │ │ ├── _AppChain.cshtml │ │ ├── _CallChain.cshtml │ │ └── _Nav.cshtml │ └── _ViewImports.cshtml ├── appsettings.json ├── web.config └── wwwroot │ └── icons │ ├── app.svg │ ├── db.svg │ ├── http.svg │ ├── modbus.svg │ ├── mq.svg │ ├── mqtt.svg │ └── redis.svg ├── Stardust ├── AppClient.cs ├── Configs │ └── StarHttpConfigProvider.cs ├── Deployment │ ├── CopyModes.cs │ └── ZipDeploy.cs ├── DingTalk │ └── DingTalkClient.cs ├── LocalStarClient.cs ├── Managers │ ├── FrameworkManager.cs │ ├── MachineInfoProvider.cs │ ├── NetRuntime.cs │ ├── ProcessInfo.cs │ ├── ServiceController.cs │ ├── ServiceManager.cs │ └── VerInfo.cs ├── Models │ ├── AgentInfo.cs │ ├── AppInfo.cs │ ├── AppModel.cs │ ├── CommandEventArgs.cs │ ├── CommandInModel.cs │ ├── CommandModel.cs │ ├── CommandReplyModel.cs │ ├── CommandStatus.cs │ ├── CompileCommand.cs │ ├── ConfigInfo.cs │ ├── ConsumeServiceInfo.cs │ ├── DeployInfo.cs │ ├── DeployModes.cs │ ├── EventModel.cs │ ├── FrameworkModel.cs │ ├── LocalPingInfo.cs │ ├── LoginInfo.cs │ ├── MigrationEventArgs.cs │ ├── NodeInfo.cs │ ├── OSKindHelper.cs │ ├── OSKinds.cs │ ├── PingInfo.cs │ ├── ProjectKinds.cs │ ├── PublishServiceInfo.cs │ ├── RuntimeIdentifier.cs │ ├── ServiceInfo.cs │ ├── ServiceModel.cs │ ├── ServiceModes.cs │ ├── TokenModel.cs │ └── UpgradeInfo.cs ├── Monitors │ ├── AspNetCoreDiagnosticListener.cs │ ├── DiagnosticListenerObserver.cs │ ├── DnsEventListener.cs │ ├── EfCoreDiagnosticListener.cs │ ├── EventListenerBase.cs │ ├── GrpcDiagnosticListener.cs │ ├── HttpDiagnosticListener.cs │ ├── MongoDbDiagnosticListener.cs │ ├── MyBuilder.cs │ ├── MySpan.cs │ ├── MyTraceModel.cs │ ├── SocketEventListener.cs │ ├── SqlClientDiagnosticListener.cs │ ├── StarTracer.cs │ ├── StarTracerResolver.cs │ └── TraceModel.cs ├── Plugins │ └── IAgentPlugin.cs ├── Properties │ └── PublishProfiles │ │ └── FolderProfile.pubxml ├── Registry │ ├── IRegistry.cs │ └── RegistryClient.cs ├── Services │ ├── CacheService.cs │ ├── ICommandClient.cs │ ├── IEventProvider.cs │ ├── QueueService.cs │ ├── StarTimeProvider.cs │ └── TraceService.cs ├── StarClient.cs ├── StarFactory.cs ├── StarHelper.cs ├── StarSetting.cs ├── Stardust.csproj ├── Web │ ├── TracerModule.cs │ └── Upgrade.cs ├── WeiXin │ ├── Article.cs │ └── WeiXinClient.cs ├── Windows │ ├── NativeMethods.cs │ └── NativeWifi.cs └── res │ └── md5.txt ├── Test ├── Program.cs ├── Properties │ └── PublishProfiles │ │ └── FolderProfile.pubxml ├── Test.csproj └── appsettings.json ├── Tools ├── Resources │ ├── Plugins │ │ ├── SQLite.Interop.dll │ │ └── System.Data.SQLite.dll │ ├── backup │ │ └── StarAgent.config │ ├── linux-service.sh │ ├── run.bat │ └── windows-service.bat ├── Scripts │ ├── net.sh │ ├── net6.sh │ ├── net8.sh │ ├── net9.sh │ ├── star.sh │ └── star8.sh ├── build.bat ├── clover.exe ├── clover40.exe ├── clover80.exe ├── pack-agent.bat ├── pack.bat └── 通用或专用平台.txt └── 星尘.sln /.github/workflows/publish-beta.yml: -------------------------------------------------------------------------------- 1 | name: publish-beta 2 | 3 | on: 4 | push: 5 | branches: [ master,dev ] 6 | paths: 7 | - 'Stardust/**' 8 | - 'Stardust.Extensions/**' 9 | - 'DeployAgent/**' 10 | workflow_dispatch: 11 | 12 | jobs: 13 | build-publish: 14 | runs-on: windows-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Setup dotNET 19 | uses: actions/setup-dotnet@v4 20 | with: 21 | dotnet-version: | 22 | 6.x 23 | 7.x 24 | 8.x 25 | 9.x 26 | - name: Get Version 27 | run: echo "VERSION=$(date '+%Y.%m%d-beta%H%M')" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 28 | - name: Build 29 | run: | 30 | dotnet pack --version-suffix ${{ env.VERSION }} -c Release -o out Stardust\Stardust.csproj 31 | dotnet pack --version-suffix ${{ env.VERSION }} -c Release -o out Stardust.Extensions\Stardust.Extensions.csproj 32 | dotnet pack --version-suffix ${{ env.VERSION }} -c Release -o out DeployAgent\DeployAgent.csproj 33 | 34 | - name: Publish 35 | run: | 36 | dotnet nuget push .\out\*.nupkg --skip-duplicate --source https://nuget.pkg.github.com/NewLifeX/index.json --api-key ${{ github.token }} 37 | dotnet nuget push .\out\*.nupkg --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.nugetKey }} 38 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: publish 2 | 3 | on: 4 | push: 5 | tags: [ v* ] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build-publish: 10 | runs-on: windows-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | - name: Setup dotNET 15 | uses: actions/setup-dotnet@v4 16 | with: 17 | dotnet-version: | 18 | 6.x 19 | 7.x 20 | 8.x 21 | 9.x 22 | - name: Build 23 | run: | 24 | dotnet build -c Release 25 | - name: Pack 26 | run: | 27 | dotnet pack --no-build -o out Stardust\Stardust.csproj 28 | dotnet pack --no-build -o out Stardust.Extensions\Stardust.Extensions.csproj 29 | dotnet pack --no-build -o out DeployAgent\DeployAgent.csproj 30 | 31 | - name: Publish 32 | run: | 33 | dotnet nuget push .\out\*.nupkg --skip-duplicate --source https://nuget.pkg.github.com/NewLifeX/index.json --api-key ${{ github.token }} 34 | dotnet nuget push .\out\*.nupkg --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.nugetKey }} 35 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | push: 5 | branches: [ '*' ] 6 | pull_request: 7 | branches: [ '*' ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build-publish: 12 | 13 | runs-on: windows-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Setup dotNET 18 | uses: actions/setup-dotnet@v4 19 | with: 20 | dotnet-version: | 21 | 6.x 22 | 7.x 23 | 8.x 24 | 9.x 25 | - name: Build 26 | run: | 27 | dotnet build -c Release 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。 3 | ################################################################################ 4 | 5 | /.vs 6 | [Dd]ebug/ 7 | [Dd]ebugPublic/ 8 | [Rr]elease/ 9 | [Rr]eleases/ 10 | x64/ 11 | x86/ 12 | build/ 13 | bld/ 14 | [Bb]in/ 15 | [Oo]bj/ 16 | /packages 17 | *.user 18 | /Data 19 | /Log 20 | *.log 21 | *.htm 22 | *.nuspec 23 | *.nupkg 24 | /Avatars 25 | /Stardust.WebFx/Config 26 | /Stardust.WebFx/Content 27 | /Stardust.WebFx/Plugins 28 | /Stardust.Data/Config 29 | /BinServer 30 | /BinClient 31 | /BinWeb 32 | /Stardust.Data/Nodes/Config 33 | /Stardust.Server/Properties 34 | /Stardust.Web/Properties 35 | /BinClient2 36 | /Stardust.Data/Monitors/Config 37 | /Stardust.Data/Entity/Config 38 | /Stardust.Data/ConfigCenter/Config 39 | /Stardust.Data/Configs/Config 40 | /Stardust.Data/Deployment/Config 41 | /Stardust.Data/Entity/Data 42 | /Stardust.Data/Nodes/Data 43 | /Stardust.Data/Configs/Data 44 | /Stardust.Extensions/Properties 45 | Stardust.Web.Vue/.vscode 46 | Stardust.Web.Vue/node_modules 47 | Stardust.Web.Vue/dist 48 | 49 | /Stardust.Data/Platform/Config 50 | /Stardust.Data/RedisNodes/Config 51 | -------------------------------------------------------------------------------- /ClientTest/AgentInfoTests.cs: -------------------------------------------------------------------------------- 1 | using Stardust.Models; 2 | using Xunit; 3 | 4 | namespace ClientTest; 5 | 6 | public class AgentInfoTests 7 | { 8 | [Fact] 9 | public void Test1() 10 | { 11 | var inf = AgentInfo.GetLocal(true); 12 | 13 | Assert.NotNull(inf); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ClientTest/AppInfoTests.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using NewLife; 3 | using NewLife.Log; 4 | using NewLife.Serialization; 5 | using Stardust; 6 | using Stardust.Models; 7 | using Xunit; 8 | 9 | namespace ClientTest; 10 | 11 | public class AppInfoTests 12 | { 13 | [Fact] 14 | public void Test() 15 | { 16 | foreach (var p in Process.GetProcesses()) 17 | { 18 | //Console.WriteLine(p); 19 | var pi = new AppInfo(p); 20 | if (pi.ProcessorTime > 0) XTrace.WriteLine(pi.ToJson()); 21 | } 22 | } 23 | 24 | [Fact] 25 | public void GetProcessName() 26 | { 27 | var p = Process.GetCurrentProcess(); 28 | 29 | var name = p.GetProcessName(); 30 | Assert.Equal("testhost", name); 31 | } 32 | 33 | //[Fact] 34 | //public void GetStarAgentName() 35 | //{ 36 | // var flag = false; 37 | // foreach (var p in Process.GetProcesses()) 38 | // { 39 | // if (p.ProcessName == "dotnet") 40 | // { 41 | // var name = AppInfo.GetProcessName(p); 42 | // if (name == "StarAgent") 43 | // { 44 | // flag = true; 45 | // break; 46 | // } 47 | // } 48 | // } 49 | 50 | // Assert.True(flag); 51 | //} 52 | } 53 | -------------------------------------------------------------------------------- /ClientTest/AppServiceTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Xunit; 7 | 8 | namespace ClientTest; 9 | 10 | public class AppServiceTests 11 | { 12 | [Fact] 13 | public void Test1() 14 | { 15 | var str = "http://star.newlifex.com:80/"; 16 | var uri = new Uri(str); 17 | 18 | var str2 = uri.ToString(); 19 | Assert.Equal("http://star.newlifex.com/", str2); 20 | } 21 | 22 | [Fact] 23 | public void Test2() 24 | { 25 | var str = "https://star.newlifex.com:443/"; 26 | var uri = new Uri(str); 27 | 28 | var str2 = uri.ToString(); 29 | Assert.Equal("https://star.newlifex.com/", str2); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ClientTest/ClientTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | ..\Bin\ClientTest 6 | 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | true 18 | PreserveNewest 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | all 29 | runtime; build; native; contentfiles; analyzers; buildtransitive 30 | 31 | 32 | all 33 | runtime; build; native; contentfiles; analyzers; buildtransitive 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ClientTest/ConfigTests.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Caching; 2 | using NewLife.Configuration; 3 | using NewLife.Model; 4 | using Stardust; 5 | using Xunit; 6 | 7 | namespace ClientTest; 8 | 9 | public class ConfigTests 10 | { 11 | [Fact] 12 | public void Http_Test() 13 | { 14 | { 15 | var prv = new HttpConfigProvider 16 | { 17 | Server = "http://127.0.0.1:6600", 18 | AppId = "StarWeb" 19 | }; 20 | 21 | var title = prv["Title"]; 22 | Assert.Equal("NewLife开发团队", title); 23 | 24 | var shop = prv["conn_shop"]; 25 | Assert.Equal("server=10.0.0.1;user=maindb;pass=Pass@word", shop); 26 | } 27 | { 28 | var prv = new HttpConfigProvider 29 | { 30 | Server = "http://127.0.0.1:6600", 31 | AppId = "StarWeb", 32 | Scope = "dev", 33 | }; 34 | 35 | var title = prv["Title"]; 36 | Assert.Equal("NewLife开发团队", title); 37 | 38 | var shop = prv["conn_shop"]; 39 | Assert.Equal("server=192.168.0.1;user=dev;pass=dev1234", shop); 40 | } 41 | } 42 | 43 | [Fact] 44 | public void Redis_ConfigTest() 45 | { 46 | using var star = new StarFactory("http://star.newlifex.com:6600", "Test", null); 47 | 48 | var services = ObjectContainer.Current; 49 | services.AddSingleton(star.Config); 50 | 51 | services.AddSingleton(p => new Redis(p, "redis6")); 52 | 53 | var provider = services.BuildServiceProvider(); 54 | 55 | var rds = provider.GetService(); 56 | Assert.Equal(6, rds.Db); 57 | } 58 | } -------------------------------------------------------------------------------- /ClientTest/LocalStarClientTests.cs: -------------------------------------------------------------------------------- 1 | using Stardust; 2 | using Xunit; 3 | 4 | namespace ClientTest; 5 | 6 | public class LocalStarClientTests 7 | { 8 | [Fact] 9 | public void Info() 10 | { 11 | var client = new LocalStarClient(); 12 | var inf = client.GetInfo(); 13 | 14 | Assert.NotNull(inf); 15 | Assert.NotEmpty(inf.Server); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ClientTest/TokenModelTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using NewLife.Security; 5 | using NewLife.Serialization; 6 | using NewLife.Web; 7 | using Stardust.Models; 8 | using Xunit; 9 | 10 | namespace ClientTest 11 | { 12 | public class TokenModelTests 13 | { 14 | [Fact] 15 | public void Test1() 16 | { 17 | var model = new TokenModel 18 | { 19 | AccessToken = Rand.NextString(32), 20 | TokenType = "token", 21 | ExpireIn = 7200, 22 | RefreshToken = Rand.NextString(32), 23 | }; 24 | 25 | var json = model.ToJson(); 26 | 27 | var rs = "{\"access_token\":\"{access_token}\",\"token_type\":\"token\",\"expire_in\":7200,\"refresh_token\":\"{refresh_token}\"}"; 28 | rs = rs.Replace("{access_token}", model.AccessToken) 29 | .Replace("{refresh_token}", model.RefreshToken); 30 | 31 | Assert.Equal(rs, json); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ClientTest/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "StarServer": "http://127.0.0.1:6600" 10 | } -------------------------------------------------------------------------------- /DeployAgent/Commands/DeployCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DeployAgent.Commands; 8 | 9 | internal class DeployCommand : ICommand 10 | { 11 | public void Process(String[] args) 12 | { 13 | 14 | } 15 | } 16 | 17 | class DeployParameter 18 | { 19 | public String AppId { get; set; } 20 | } -------------------------------------------------------------------------------- /DeployAgent/Commands/ICommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DeployAgent.Commands; 8 | 9 | internal interface ICommand 10 | { 11 | void Process(String[] args); 12 | } 13 | -------------------------------------------------------------------------------- /DeployAgent/DeploySetting.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife.Configuration; 3 | using NewLife.Remoting.Clients; 4 | 5 | namespace DeployAgent; 6 | 7 | /// 配置 8 | [Config("DeployAgent")] 9 | public class DeploySetting : Config, IClientSetting 10 | { 11 | #region 属性 12 | /// 服务端地址 13 | [Description("服务端地址")] 14 | public String Server { get; set; } = "http://localhost:6600"; 15 | 16 | /// 客户端编码 17 | [Description("客户端编码")] 18 | public String Code { get; set; } 19 | 20 | /// 客户端密钥 21 | [Description("客户端密钥")] 22 | public String Secret { get; set; } 23 | #endregion 24 | } -------------------------------------------------------------------------------- /DeployAgent/DeployWorker.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Log; 3 | using NewLife.Model; 4 | using NewLife.Remoting.Clients; 5 | using NewLife.Serialization; 6 | using Stardust; 7 | using Stardust.Models; 8 | 9 | namespace DeployAgent; 10 | 11 | public class DeployWorker(StarFactory factory) : IHostedService 12 | { 13 | private StarClient _client; 14 | 15 | public Task StartAsync(CancellationToken cancellationToken) 16 | { 17 | XTrace.WriteLine("开始Deploy客户端"); 18 | 19 | var set = DeploySetting.Current; 20 | 21 | // 产品编码、产品密钥从IoT管理平台获取,设备编码支持自动注册 22 | var client = new StarClient(factory.Server) 23 | { 24 | Name = "Deploy", 25 | Code = set.Code, 26 | Secret = set.Secret, 27 | ProductCode = factory.AppId, 28 | Setting = set, 29 | 30 | Tracer = factory.Tracer, 31 | Log = XTrace.Log, 32 | }; 33 | 34 | // 禁用客户端特性 35 | client.Features &= ~Features.Upgrade; 36 | 37 | client.Open(); 38 | 39 | Host.RegisterExit(() => client.Logout("ApplicationExit")); 40 | 41 | _client = client; 42 | 43 | client.RegisterCommand("deploy/compile", OnCompile); 44 | 45 | return Task.CompletedTask; 46 | } 47 | 48 | public Task StopAsync(CancellationToken cancellationToken) 49 | { 50 | _client.TryDispose(); 51 | 52 | return Task.CompletedTask; 53 | } 54 | 55 | private String OnCompile(String args) 56 | { 57 | if (args.IsNullOrEmpty()) throw new ArgumentNullException(nameof(args)); 58 | 59 | var cmd = args.ToJsonEntity(); 60 | if (cmd == null || cmd.Repository.IsNullOrEmpty()) throw new ArgumentNullException(nameof(cmd.Repository)); 61 | 62 | //todo 拉取代码编译逻辑 63 | 64 | return "OK"; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /DeployAgent/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Xml; 3 | using DeployAgent; 4 | using DeployAgent.Commands; 5 | using NewLife; 6 | using NewLife.Log; 7 | using NewLife.Model; 8 | using Stardust; 9 | 10 | // 启用控制台日志,拦截所有异常 11 | XTrace.UseConsole(); 12 | 13 | // 初始化对象容器,提供注入能力 14 | var services = ObjectContainer.Current; 15 | //services.AddSingleton(XTrace.Log); 16 | 17 | var asm = Assembly.GetEntryAssembly(); 18 | Console.WriteLine("星尘发布 \e[31;1mstardeploy\e[0m v{0}", asm.GetName().Version); 19 | Console.WriteLine(asm.GetCustomAttribute()?.Description); 20 | Console.WriteLine("\e[34;1m{0}\e[0m", Environment.OSVersion); 21 | Console.WriteLine(); 22 | 23 | var cmds = new Dictionary 24 | { 25 | { "pack", new PackCommand() }, 26 | { "deploy", new DeployCommand() } 27 | }; 28 | Console.WriteLine("可用命令:"); 29 | 30 | foreach (var item in cmds) 31 | { 32 | var type = item.Value.GetType(); 33 | 34 | Console.WriteLine("\t{0,-8}\t{1}", item.Key, type.GetDescription() ?? type.FullName); 35 | } 36 | 37 | var cmd = args?.FirstOrDefault(); 38 | if (args != null && !cmd.IsNullOrEmpty()) 39 | { 40 | if (cmds.TryGetValue(cmd, out var command)) 41 | { 42 | try 43 | { 44 | // 执行命令 45 | command.Process(args.Skip(1).ToArray()); 46 | return; 47 | } 48 | catch (Exception ex) 49 | { 50 | XTrace.WriteException(ex); 51 | Thread.Sleep(15_000); 52 | } 53 | } 54 | } 55 | 56 | // 没有命令时走默认逻辑 57 | if (cmd.IsNullOrEmpty()) 58 | { 59 | // 配置星尘。自动读取配置文件 config/star.config 中的服务器地址 60 | var star = services.AddStardust(); 61 | 62 | services.AddHostedService(); 63 | 64 | var host = services.BuildHost(); 65 | 66 | // 异步阻塞,友好退出 67 | await host.RunAsync(); 68 | } -------------------------------------------------------------------------------- /DeployAgent/Properties/PublishProfiles/win-x64.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Release 6 | Any CPU 7 | ..\Bin\DeployAgent\publish-win\ 8 | FileSystem 9 | <_TargetId>Folder 10 | net8.0 11 | false 12 | win-x64 13 | true 14 | false 15 | 16 | -------------------------------------------------------------------------------- /DeployAgent/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "DeployAgent": { 4 | "commandName": "Project", 5 | "commandLineArgs": "pack -r ../star.zip ../../star/*.exe ../../star/*.dll ../../star/*.runtimeconfig.json ../../../Doc *.dll" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Doc/StarInstall.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal enabledelayedexpansion 3 | 4 | @REM create star folder 5 | mkdir star 6 | 7 | @REM traverse all zip files in the current directory 8 | for %%f in (*.zip) do ( 9 | @REM skip agent.zip 10 | if /I "%%f" NEQ "agent.zip" ( 11 | @REM get filename (without extension) 12 | set "filename=%%~nf" 13 | 14 | @REM filename to lowercase 15 | for %%A in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do ( 16 | call set "filename=!filename:%%A=%%A!" 17 | ) 18 | 19 | @REM remove star characters from filename 20 | set "filename=!filename:star=!" 21 | echo !filename! 22 | 23 | @REM create folder with filename 24 | mkdir "star\!filename!" 2>nul 25 | 26 | @REM move zip file to folder 27 | move /Y "%%f" "star\!filename!\" 28 | ) 29 | ) 30 | 31 | @REM tar agent folder 32 | tar -xf agent.zip 33 | 34 | @REM test agent 35 | call agent\StarAgent.exe 36 | 37 | echo move completed 38 | endlocal 39 | pause 40 | 41 | -------------------------------------------------------------------------------- /Doc/ab_http.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/ab_http.png -------------------------------------------------------------------------------- /Doc/clear.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set root=%cd%\..\ 3 | pushd ..\ 4 | 5 | ::for /r %root% %%i in (*.pdb,*.vshost.*) do (del %%i) 6 | 7 | ::for /r %root% %%i in (obj,bin) do (IF EXIST %%i RD /s /q %%i) 8 | ::for /r %root% %%i in (obj,bin) do (IF EXIST %%i echo %%i %%~ti) 9 | for /f "delims=" %%i in ('dir /ad/b/s .') do ( 10 | if EXIST %%i\bin echo %%i\bin 11 | if EXIST %%i\bin rd /s/q %%i\bin 12 | if EXIST %%i\obj echo %%i\obj 13 | if EXIST %%i\obj rd /s/q %%i\obj 14 | ) 15 | ::for /f "delims=" %%i in ('dir /ad/b .') do (if EXIST %%i\bin echo %%i\bin) 16 | 17 | popd -------------------------------------------------------------------------------- /Doc/leaf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/leaf.png -------------------------------------------------------------------------------- /Doc/newlife.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/newlife.snk -------------------------------------------------------------------------------- /Doc/staragent.sh: -------------------------------------------------------------------------------- 1 | # staragent cube.zip urls=http://*:80 2 | # dotnet startagent.dll cube.zip urls=htts://*:80 3 | # echo $@ # cube.zip urls=http://*:80 4 | # echo $(pwd) # Workspace 5 | # BASEDIR=$(dirname "$0") 6 | # echo "$BASEDIR" 7 | SCRIPT=$(readlink -f "$0") 8 | SCRIPTPATH=$(dirname "$SCRIPT") 9 | # echo $SCRIPTPATH 10 | # echo 11 | STAR_AGENT=$SCRIPTPATH"/staragent.dll" # star agent 的全路径 12 | # echo $STAR_AGENT 13 | ZIP_DIR=$(pwd) 14 | dotnet $STAR_AGENT $ZIP_DIR"/"$@ -------------------------------------------------------------------------------- /Doc/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Doc/关系图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/关系图.png -------------------------------------------------------------------------------- /Doc/应用监控.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/应用监控.png -------------------------------------------------------------------------------- /Doc/星尘分布式.emmx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/星尘分布式.emmx -------------------------------------------------------------------------------- /Doc/星尘分布式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/星尘分布式.png -------------------------------------------------------------------------------- /Doc/星尘发布.emmx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/星尘发布.emmx -------------------------------------------------------------------------------- /Doc/星尘发布.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/星尘发布.png -------------------------------------------------------------------------------- /Doc/服务注册.emmx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/服务注册.emmx -------------------------------------------------------------------------------- /Doc/本地通信.emmx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/本地通信.emmx -------------------------------------------------------------------------------- /Doc/调用链.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Doc/调用链.png -------------------------------------------------------------------------------- /Installer/Command.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Installer; 5 | 6 | /// 命令选项 7 | internal class Command 8 | { 9 | #region 属性 10 | /// 操作名 11 | public String Name { get; set; } 12 | 13 | /// 参数集合 14 | public IList Arguments { get; set; } = new List(); 15 | #endregion 16 | 17 | #region 方法 18 | /// 分析输入参数数组,得到命令选项列表 19 | /// 20 | /// 21 | public static IList Parse(String[] args) 22 | { 23 | var commands = new List(); 24 | if (args == null || args.Length == 0) return commands; 25 | 26 | Command command = null; 27 | for (var i = 0; i < args.Length; i++) 28 | { 29 | // 命令以-开头,其它是参数 30 | var arg = args[i]; 31 | if (arg[0] == '-') 32 | commands.Add(command = new Command { Name = arg }); 33 | else 34 | { 35 | // 如果第一个参数不是-开头,则添加空名称命令 36 | if (command == null) 37 | commands.Add(command = new Command { Name = "" }); 38 | 39 | command.Arguments.Add(arg); 40 | } 41 | } 42 | 43 | return commands; 44 | } 45 | #endregion 46 | } 47 | -------------------------------------------------------------------------------- /Installer/Installer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net40;net45;net5.0;net6.0;net7.0 6 | 安装器 7 | 安装辅助工具 8 | 新生命开发团队 9 | ©2002-2025 NewLife 10 | 1.0 11 | $([System.DateTime]::Now.ToString(`yyyy.MMdd`)) 12 | $(VersionPrefix).$(VersionSuffix) 13 | $(Version) 14 | $(VersionPrefix).* 15 | false 16 | ..\Bin\Agent 17 | 18 | latest 19 | app.manifest 20 | true 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 新生命开发团队 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Plugins/MySqlAgent/MySqlAgent.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net45;netstandard2.0 5 | MySql助手 6 | 监控MySql性能,上报星尘平台 7 | 新生命开发团队 8 | ©2002-2025 NewLife 9 | 1.0 10 | $([System.DateTime]::Now.ToString(`yyyy.MMdd`)) 11 | $(VersionPrefix).$(VersionSuffix) 12 | $(Version) 13 | $(VersionPrefix).* 14 | false 15 | ..\..\Bin\Agent 16 | 17 | enable 18 | latest 19 | False 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Plugins/MySqlAgent/MySqlPlugin.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife.Log; 3 | using NewLife.Model; 4 | using NewLife.Remoting.Clients; 5 | using NewLife.Threading; 6 | using Stardust.Plugins; 7 | 8 | namespace MySqlAgent; 9 | 10 | [DisplayName("MySql助手")] 11 | public class MySqlPlugin : AgentPlugin 12 | { 13 | private TimerX _timer; 14 | private ITracer _tracer; 15 | private BinlogClear _clear; 16 | 17 | /// 开始工作 18 | public override void Start() 19 | { 20 | _tracer = Provider.GetService(); 21 | 22 | _clear = new BinlogClear 23 | { 24 | Event = Provider.GetService(), 25 | }; 26 | _clear.Start(); 27 | } 28 | 29 | /// 停止工作 30 | /// 31 | public override void Stop(String reason) 32 | { 33 | _clear.Stop(); 34 | } 35 | 36 | protected override void Dispose(Boolean disposing) 37 | { 38 | base.Dispose(disposing); 39 | 40 | Stop(disposing ? "Dispose" : "GC"); 41 | } 42 | } -------------------------------------------------------------------------------- /Plugins/NetworkDetect/NetworkDetect.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net45;netstandard2.0 5 | 网络监测 6 | 检测网络,如果长期不可用,则重启系统,主要应用于嵌入式工控机 7 | 新生命开发团队 8 | ©2002-2025 NewLife 9 | 1.0 10 | $([System.DateTime]::Now.ToString(`yyyy.MMdd`)) 11 | $(VersionPrefix).$(VersionSuffix) 12 | $(Version) 13 | $(VersionPrefix).* 14 | false 15 | ..\..\Bin\Agent 16 | 17 | enable 18 | latest 19 | False 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Plugins/NetworkDetect/NetworkDetectSetting.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife.Configuration; 3 | 4 | namespace NetworkDetect; 5 | 6 | /// 网络监测设置 7 | [Config("NetworkDetect")] 8 | public class NetworkDetectSetting : Config 9 | { 10 | #region 属性 11 | /// 调试。默认启用 12 | [Description("调试。默认启用")] 13 | public Boolean Debug { get; set; } = true; 14 | 15 | /// 周期。检测周期,默认5秒 16 | [Description("周期。检测周期,默认5秒")] 17 | public Int32 Period { get; set; } = 5; 18 | 19 | /// 服务集合 20 | [Description("服务集合")] 21 | public ServiceItem[] Services { get; set; } 22 | #endregion 23 | 24 | #region 方法 25 | /// 加载完成后 26 | protected override void OnLoaded() 27 | { 28 | if (Services == null || Services.Length == 0) 29 | { 30 | var si = new ServiceItem 31 | { 32 | Name = "路由心跳", 33 | Address = "192.168.1.1", 34 | }; 35 | var si2 = new ServiceItem 36 | { 37 | Name = "交换机", 38 | Address = "192.168.1.254", 39 | }; 40 | 41 | Services = new[] { si, si2 }; 42 | } 43 | 44 | base.OnLoaded(); 45 | } 46 | #endregion 47 | } -------------------------------------------------------------------------------- /Plugins/NetworkDetect/ServiceItem.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Serialization; 2 | 3 | namespace NetworkDetect; 4 | 5 | /// 服务信息 6 | public class ServiceItem 7 | { 8 | #region 属性 9 | /// 名称 10 | [XmlAttribute] 11 | public String Name { get; set; } 12 | 13 | /// 地址。如 192.168.1.1 14 | [XmlAttribute] 15 | public String Address { get; set; } 16 | 17 | /// 超时时间。默认1000 18 | [XmlAttribute] 19 | public Int32 Timeout { get; set; } = 1000; 20 | 21 | /// 启用 22 | [XmlAttribute] 23 | public Boolean Enable { get; set; } 24 | #endregion 25 | } -------------------------------------------------------------------------------- /Plugins/NetworkDetect/Worker.cs: -------------------------------------------------------------------------------- 1 | using System.Net.NetworkInformation; 2 | using NewLife; 3 | using NewLife.Log; 4 | using NewLife.Threading; 5 | 6 | namespace NetworkDetect; 7 | 8 | internal class Worker 9 | { 10 | public ServiceItem Item { get; set; } 11 | 12 | public Int32 Period { get; set; } 13 | 14 | public ITracer Tracer { get; set; } 15 | 16 | private TimerX _timer; 17 | 18 | public void Start() 19 | { 20 | if (_timer == null) 21 | { 22 | XTrace.WriteLine("网络探测[{0}]:{1}", Item.Name, Item.Address); 23 | 24 | var set = NetworkDetectSetting.Current; 25 | var p = set.Period; 26 | if (p <= 0) p = 5; 27 | _timer = new TimerX(DoWork, null, 1000, p * 1000) { Async = true }; 28 | } 29 | } 30 | 31 | public void Stop() => _timer.TryDispose(); 32 | 33 | private void DoWork(Object state) 34 | { 35 | var ip = Item.Address; 36 | if (ip.IsNullOrEmpty()) return; 37 | 38 | // 埋点记录 39 | using var span = Tracer?.NewSpan($"ping:{Item.Name}", ip); 40 | try 41 | { 42 | var reply = new Ping().Send(ip, Item.Timeout); 43 | 44 | if (reply != null) span?.AppendTag($"{reply.Address} {reply.RoundtripTime}ms"); 45 | 46 | if (reply.Status != IPStatus.Success) 47 | throw new Exception(reply.Status + ""); 48 | } 49 | catch (Exception ex) 50 | { 51 | span?.SetError(ex, null); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Samples/TestA/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using NewLife; 3 | using NewLife.Log; 4 | 5 | XTrace.UseConsole(); 6 | 7 | XTrace.WriteLine("TestA启动,PID={0}", Process.GetCurrentProcess().Id); 8 | XTrace.WriteLine("测试参数:{0}", args.Join(" ")); 9 | 10 | var target = "TestB"; 11 | if (args.Contains("-c")) target = "TestC"; 12 | 13 | var old = Process.GetProcesses().FirstOrDefault(e => e.ProcessName == target); 14 | if (old != null) 15 | { 16 | XTrace.WriteLine("关闭进程 {0} {1}", old.Id, old.ProcessName); 17 | old.Kill(); 18 | } 19 | 20 | var si = new ProcessStartInfo 21 | { 22 | FileName = (Runtime.Windows ? $"../{target}/{target}.exe" : $"../{target}/{target}").GetFullPath(), 23 | Arguments = "-name NewLife", 24 | //WorkingDirectory = "", 25 | //UseShellExecute = false, 26 | }; 27 | 28 | // 必须在si.Environment之前设置,否则丢失。可能si.Environment复制了一份 29 | if (args.Contains("-b")) Environment.SetEnvironmentVariable("BasePath", $"../{target}".GetFullPath()); 30 | if (args.Contains("-s")) si.UseShellExecute = true; 31 | if (args.Contains("-w")) si.WorkingDirectory = Path.GetDirectoryName(si.FileName)?.GetFullPath(); 32 | if (args.Contains("-e")) si.Environment["star"] = "dust"; 33 | 34 | XTrace.WriteLine("UseShellExecute:\t{0}", si.UseShellExecute); 35 | XTrace.WriteLine("WorkingDirectory:\t{0}", si.WorkingDirectory); 36 | 37 | var p = Process.Start(si); 38 | if (p == null || p.WaitForExit(3_000) && p.ExitCode != 0) 39 | { 40 | XTrace.WriteLine("启动失败!ExitCode={0}", p?.ExitCode); 41 | } 42 | else 43 | { 44 | XTrace.WriteLine("启动成功!PID={0}", p.Id); 45 | } 46 | 47 | Console.WriteLine("TestA OK!"); 48 | //Console.ReadKey(); 49 | Thread.Sleep(5_000); -------------------------------------------------------------------------------- /Samples/TestA/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | ..\..\Bin\Samples\TestA\publish\linux-x64\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net8.0 13 | linux-x64 14 | false 15 | false 16 | 17 | -------------------------------------------------------------------------------- /Samples/TestA/TestA.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 新生命开发团队 7 | ©2002-2025 NewLife 8 | 1.0 9 | $([System.DateTime]::Now.ToString(`yyyy.MMdd`)) 10 | $(VersionPrefix).$(VersionSuffix) 11 | $(Version) 12 | $(VersionPrefix).* 13 | false 14 | ..\..\Bin\Samples\TestA 15 | false 16 | enable 17 | enable 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Samples/TestB/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using NewLife; 3 | using NewLife.Log; 4 | 5 | XTrace.UseConsole(); 6 | 7 | XTrace.WriteLine("TestB启动,PID={0}", Process.GetCurrentProcess().Id); 8 | XTrace.WriteLine("测试参数:{0}", args.Join(" ")); 9 | 10 | XTrace.WriteLine("GetFullPath:\t{0}", Path.GetFullPath(".")); 11 | XTrace.WriteLine("CurrentDirectory:\t{0}", Environment.CurrentDirectory); 12 | XTrace.WriteLine("BaseDirectory:\t{0}", AppDomain.CurrentDomain.BaseDirectory); 13 | XTrace.WriteLine("BasePath:\t{0}", PathHelper.BasePath); 14 | XTrace.WriteLine("BaseDirectory:\t{0}", PathHelper.BaseDirectory); 15 | 16 | var envs = new[] { "BasePath", "star" }; 17 | XTrace.WriteLine("环境变量:"); 18 | var dic = Runtime.GetEnvironmentVariables().OrderBy(e => e.Key).ToDictionary(e => e.Key, e => e.Value); 19 | foreach (var item in dic) 20 | { 21 | if (item.Key.EqualIgnoreCase(envs)) 22 | XTrace.WriteLine("{0}:\t{1}", item.Key, item.Value); 23 | } 24 | 25 | Console.WriteLine("TestB OK!"); 26 | //Console.ReadKey(); 27 | Thread.Sleep(15_000); 28 | XTrace.WriteLine("Auto Exist!"); -------------------------------------------------------------------------------- /Samples/TestB/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | ..\..\Bin\Samples\TestB\publish\linux-x64\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net8.0 13 | linux-x64 14 | false 15 | false 16 | 17 | -------------------------------------------------------------------------------- /Samples/TestB/TestB.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 新生命开发团队 7 | ©2002-2025 NewLife 8 | 1.0 9 | $([System.DateTime]::Now.ToString(`yyyy.MMdd`)) 10 | $(VersionPrefix).$(VersionSuffix) 11 | $(Version) 12 | $(VersionPrefix).* 13 | false 14 | ..\..\Bin\Samples\TestB 15 | false 16 | enable 17 | enable 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Samples/TestC/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Diagnostics; 3 | 4 | Console.WriteLine("TestC启动,PID={0}", Process.GetCurrentProcess().Id); 5 | Console.WriteLine("测试参数:{0}", String.Join(',', args)); 6 | 7 | Console.WriteLine("GetFullPath:\t{0}", Path.GetFullPath(".")); 8 | Console.WriteLine("CurrentDirectory:\t{0}", Environment.CurrentDirectory); 9 | Console.WriteLine("BaseDirectory:\t{0}", AppDomain.CurrentDomain.BaseDirectory); 10 | Console.WriteLine("BasePath:\t{0}", Environment.GetEnvironmentVariable("BasePath")); 11 | 12 | var envs = new[] { "BasePath", "star" }; 13 | Console.WriteLine("环境变量:"); 14 | foreach (DictionaryEntry item in Environment.GetEnvironmentVariables()) 15 | { 16 | if (envs.Contains(item.Key)) 17 | Console.WriteLine("{0}:\t{1}", item.Key, item.Value); 18 | } 19 | 20 | Console.WriteLine("TestC OK!"); 21 | //Console.ReadKey(); 22 | Thread.Sleep(15_000); 23 | Console.WriteLine("Auto Exist!"); -------------------------------------------------------------------------------- /Samples/TestC/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | ..\..\Bin\Samples\TestC\publish\linux-x64\ 10 | FileSystem 11 | <_TargetId>Folder 12 | net8.0 13 | linux-x64 14 | false 15 | false 16 | 17 | -------------------------------------------------------------------------------- /Samples/TestC/TestC.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 新生命开发团队 7 | ©2002-2025 NewLife 8 | 1.0 9 | $([System.DateTime]::Now.ToString(`yyyy.MMdd`)) 10 | $(VersionPrefix).$(VersionSuffix) 11 | $(Version) 12 | $(VersionPrefix).* 13 | false 14 | ..\..\Bin\Samples\TestC 15 | false 16 | enable 17 | enable 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /StarAgent/CommandHandler/UseMicroService.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Agent.Command; 2 | using NewLife.Agent; 3 | using NewLife; 4 | using NewLife.Serialization; 5 | 6 | namespace StarAgent.CommandHandler; 7 | 8 | public class UseMicroService : BaseCommandHandler 9 | { 10 | public UseMicroService(ServiceBase service) : base(service) 11 | { 12 | Cmd = "-UseMicroService"; 13 | Description = "测试微服务"; 14 | ShortcutKey = 'w'; 15 | } 16 | 17 | private String _lastService; 18 | 19 | public override void Process(String[] args) 20 | { 21 | var service = (MyService)Service; 22 | if (_lastService.IsNullOrEmpty()) 23 | Console.WriteLine("请输入要测试的微服务名称:"); 24 | else 25 | Console.WriteLine("请输入要测试的微服务名称({0}):", _lastService); 26 | 27 | var serviceName = Console.ReadLine(); 28 | if (serviceName.IsNullOrEmpty()) serviceName = _lastService; 29 | if (serviceName.IsNullOrEmpty()) return; 30 | 31 | _lastService = serviceName; 32 | 33 | service.StartFactory(); 34 | 35 | var models = service._factory.Service.ResolveAsync(serviceName).ConfigureAwait(false).GetAwaiter().GetResult(); 36 | 37 | Console.WriteLine(models.ToJson(true)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /StarAgent/CommandHandler/UseStarServer.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Agent; 2 | using NewLife.Agent.Command; 3 | 4 | namespace StarAgent.CommandHandler 5 | { 6 | public class UseStarServer : BaseCommandHandler 7 | { 8 | public UseStarServer(ServiceBase service) : base(service) 9 | { 10 | Cmd = "-UseStarServer"; 11 | Description = "使用星尘"; 12 | ShortcutKey = 's'; 13 | } 14 | 15 | public override void Process(String[] args) 16 | { 17 | var set = ((MyService)Service).StarSetting; 18 | if (!String.IsNullOrEmpty(set.Server)) Console.WriteLine("服务端:{0}", set.Server); 19 | 20 | Console.WriteLine("请输入新的服务端:"); 21 | 22 | var addr = Console.ReadLine(); 23 | if (String.IsNullOrEmpty(addr)) addr = "http://127.0.0.1:6600"; 24 | 25 | set.Server = addr; 26 | set.Save(); 27 | 28 | Service.WriteLog("服务端修改为:{0}", addr); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /StarAgent/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | Any CPU 10 | net6.0 11 | ..\Bin\Agent_publish\ 12 | linux-x64 13 | false 14 | False 15 | 16 | -------------------------------------------------------------------------------- /StarAgent/Properties/PublishProfiles/linux-arm.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | ..\Bin\Agent\net6.0\publish\linux-arm\ 10 | FileSystem 11 | net6.0 12 | linux-arm 13 | false 14 | False 15 | 16 | -------------------------------------------------------------------------------- /StarAgent/Properties/PublishProfiles/linux-x64.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | ..\Bin\Agent\net6.0\publish\linux-x64\ 10 | FileSystem 11 | net6.0 12 | linux-x64 13 | false 14 | False 15 | 16 | -------------------------------------------------------------------------------- /StarAgent/Properties/PublishProfiles/win-x64.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | ..\Bin\Agent\publish\win-x64\ 10 | FileSystem 11 | net7.0 12 | true 13 | win-x64 14 | false 15 | false 16 | true 17 | 18 | -------------------------------------------------------------------------------- /StarGateway/InitService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using Stardust.Data; 4 | 5 | namespace StarGateway 6 | { 7 | class InitService : IHostedService 8 | { 9 | public Task StartAsync(CancellationToken cancellationToken) 10 | { 11 | //await Task.Yield(); 12 | 13 | Task.Run(() => 14 | { 15 | // 配置 16 | var set = NewLife.Setting.Current; 17 | if (set.IsNew) 18 | { 19 | set.DataPath = "../Data"; 20 | set.Save(); 21 | } 22 | 23 | // 初始化数据库 24 | var n = App.Meta.Count; 25 | //AppStat.Meta.Session.Dal.Db.ShowSQL = false; 26 | }); 27 | 28 | return Task.CompletedTask; 29 | } 30 | 31 | public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; 32 | } 33 | } -------------------------------------------------------------------------------- /StarGateway/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NewLife.Log; 3 | 4 | namespace StarGateway 5 | { 6 | class Program 7 | { 8 | public static void Main(String[] args) 9 | { 10 | XTrace.UseConsole(); 11 | 12 | #if DEBUG 13 | //DefaultTracer.Instance = new DefaultTracer { Log = XTrace.Log }; 14 | #endif 15 | 16 | var host = new Host(); 17 | host.Add(); 18 | host.Add(); 19 | 20 | host.Run(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /StarGateway/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | ..\Bin\Gateway\publish\ 10 | FileSystem 11 | netcoreapp3.1 12 | linux-x64 13 | false 14 | False 15 | 16 | -------------------------------------------------------------------------------- /StarGateway/Proxy/NATProxy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NewLife.Net; 3 | 4 | namespace StarGateway.Proxy 5 | { 6 | /// 通用NAT代理。对固定目标服务器进行数据转发 7 | /// 8 | /// 监听协议可以跟远程协议不同,也即是可以实现Tcp/Udp互相转发 9 | /// 10 | public class NATProxy : ProxyServer 11 | { 12 | #region 属性 13 | /// 远程服务器地址 14 | public NetUri RemoteServer { get; set; } = new NetUri(); 15 | #endregion 16 | 17 | #region 方法 18 | /// 开始 19 | protected override void OnStart() 20 | { 21 | var rs = RemoteServer; 22 | WriteLog("NAT代理 => {0}", rs); 23 | 24 | if (rs.Type == 0) rs.Type = ProtocolType; 25 | 26 | base.OnStart(); 27 | } 28 | 29 | /// 添加会话。子类可以在添加会话前对会话进行一些处理 30 | /// 31 | protected override void AddSession(INetSession session) 32 | { 33 | var rs = RemoteServer; 34 | var ps = session as ProxySession; 35 | ps.RemoteServerUri = rs; 36 | 37 | // 如果不是Tcp/Udp,则使用本地协议 38 | if (!rs.IsTcp && !rs.IsUdp) 39 | ps.RemoteServerUri.Type = Local.Type; 40 | 41 | base.AddSession(session); 42 | } 43 | #endregion 44 | } 45 | } -------------------------------------------------------------------------------- /StarGateway/Proxy/ProxyServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NewLife.Net; 3 | 4 | namespace StarGateway.Proxy 5 | { 6 | /// 代理服务器 7 | /// 8 | /// 负责监听并转发客户端和远程服务器之间的所有数据。 9 | /// 10 | public abstract class ProxyServer : NetServer 11 | { 12 | #region 属性 13 | /// 开始会话时连接远程会话。默认false,将在首次收到数据包时连接远程会话 14 | public Boolean ConnectRemoteOnStart { get; set; } 15 | #endregion 16 | 17 | #region 构造函数 18 | /// 19 | public ProxyServer() { } 20 | #endregion 21 | 22 | #region 业务 23 | ///// 创建会话 24 | ///// 25 | ///// 26 | //protected override INetSession CreateSession(ISocketSession session) => new ProxySession { Host = this }; 27 | #endregion 28 | } 29 | } -------------------------------------------------------------------------------- /StarGateway/Setting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using NewLife.Configuration; 4 | 5 | namespace StarGateway 6 | { 7 | /// 配置 8 | [Config("StarGateway")] 9 | public class StarGatewaySetting : Config 10 | { 11 | #region 属性 12 | /// 调试开关。默认true 13 | [Description("调试开关。默认true")] 14 | public Boolean Debug { get; set; } = true; 15 | 16 | /// 服务端口。默认8800 17 | [Description("服务端口。默认8800")] 18 | public Int32 Port { get; set; } = 8800; 19 | 20 | /// 令牌密钥。用于生成JWT令牌的算法和密钥,如HS256:ABCD1234 21 | [Description("令牌密钥。用于生成JWT令牌的算法和密钥,如HS256:ABCD1234")] 22 | public String TokenSecret { get; set; } 23 | #endregion 24 | } 25 | } -------------------------------------------------------------------------------- /StarGateway/StarGateway.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | 星尘网关 7 | 星尘网关,转发网络请求,实现路由切换。 8 | 新生命开发团队 9 | ©2002-2025 NewLife 10 | 3.0 11 | $([System.DateTime]::Now.ToString(`yyyy.MMdd`)) 12 | $(VersionPrefix).$(VersionSuffix) 13 | $(Version) 14 | $(VersionPrefix).* 15 | false 16 | ..\Bin\Gateway 17 | false 18 | enable 19 | latest 20 | False 21 | 1701;1702;NU5104;NETSDK1138;CS7035 22 | 23 | 24 | 25 | $(DefineConstants);DEBUG 26 | full 27 | false 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Stardust.Data/Models/RedisDbEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Stardust.Data.Models 4 | { 5 | /// Redis库实体 6 | public class RedisDbEntry 7 | { 8 | /// 键个数 9 | public Int32 Keys { get; set; } 10 | 11 | /// 过期数 12 | public Int32 Expires { get; set; } 13 | 14 | /// 平均过期时间。秒 15 | public Int32 AvgTtl { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /Stardust.Data/Monitors/TraceStatModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NewLife; 3 | 4 | namespace Stardust.Data.Monitors; 5 | 6 | /// 跟踪统计模型 7 | public class TraceStatModel 8 | { 9 | /// 时间 10 | public DateTime Time { get; set; } 11 | 12 | /// 应用 13 | public Int32 AppId { get; set; } 14 | 15 | ///// 操作名 16 | //public String Name { get; set; } 17 | 18 | /// 跟踪项 19 | public Int32 ItemId { get; set; } 20 | 21 | /// 用于统计的唯一Key 22 | public String Key => $"{Time.ToFullString()}#{AppId}#{ItemId}"; 23 | 24 | /// 已重载。用于统计的唯一Key 25 | /// 26 | public override String ToString() => $"{Time.ToFullString()}#{AppId}#{ItemId}"; 27 | } -------------------------------------------------------------------------------- /Stardust.Data/xcodetool.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Stardust.Data/xcodetool.bat -------------------------------------------------------------------------------- /Stardust.Data/xcodetool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Stardust.Data/xcodetool.exe -------------------------------------------------------------------------------- /Stardust.Extensions/Caches/FileInfoModel.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System; 3 | using Microsoft.Extensions.FileProviders; 4 | 5 | namespace Stardust.Extensions.Caches; 6 | 7 | class FileInfoModel : IFileInfo 8 | { 9 | public String Name { get; set; } = null!; 10 | 11 | public Boolean Exists { get; set; } 12 | 13 | public Boolean IsDirectory { get; set; } 14 | 15 | public DateTimeOffset LastModified { get; set; } 16 | 17 | public Int64 Length { get; set; } 18 | 19 | public String? PhysicalPath { get; set; } 20 | 21 | public Stream CreateReadStream() => throw new NotImplementedException(); 22 | } 23 | -------------------------------------------------------------------------------- /Stardust.Extensions/StarService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using Microsoft.AspNetCore.Hosting.Server.Features; 4 | using Microsoft.AspNetCore.Http.Features; 5 | using Microsoft.Extensions.Hosting; 6 | using NewLife; 7 | using NewLife.Log; 8 | using NewLife.Reflection; 9 | 10 | namespace Stardust.Extensions 11 | { 12 | internal class StarService : IHostedService 13 | { 14 | private readonly StarFactory _starFactory; 15 | private readonly IFeatureCollection _applicationBuilder; 16 | 17 | public StarService(StarFactory starFactory, IFeatureCollection applicationBuilder) 18 | { 19 | _starFactory = starFactory; 20 | _applicationBuilder = applicationBuilder; 21 | } 22 | 23 | public Task StartAsync(CancellationToken cancellationToken) 24 | { 25 | var feature = _applicationBuilder.Get(); 26 | var addrs = feature?.Addresses.Join(); 27 | if (!addrs.IsNullOrEmpty()) 28 | { 29 | var serviceName = _starFactory.ServiceName; 30 | if (serviceName.IsNullOrEmpty()) serviceName = AssemblyX.Entry.Name; 31 | 32 | // 发布服务到星尘注册中心 33 | XTrace.WriteLine("发布服务[{0}]到星尘注册中心。", serviceName); 34 | _starFactory.Dust.Register(serviceName, addrs); 35 | } 36 | 37 | return Task.CompletedTask; 38 | } 39 | 40 | public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Stardust.Server/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "3.1.8", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Stardust.Server/Common/DateTimeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.Json; 3 | using System.Text.Json.Serialization; 4 | using NewLife; 5 | 6 | namespace Stardust.Server.Common 7 | { 8 | public class DateTimeConverter : JsonConverter 9 | { 10 | public String DateTimeFormat { get; set; } = "yyyy-MM-dd HH:mm:ss"; 11 | 12 | public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 13 | { 14 | var str = reader.GetString(); 15 | var utc = false; 16 | if (str.EndsWith("UTC")) 17 | { 18 | str = str.TrimEnd("UTC").Trim(); 19 | utc = true; 20 | } 21 | if (!DateTime.TryParse(str, out var dt)) return DateTime.MinValue; 22 | 23 | if (utc) dt = dt.ToLocalTime(); 24 | 25 | return dt; 26 | } 27 | 28 | public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString(DateTimeFormat)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Stardust.Server/Common/JsonConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.Json; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace Stardust.Server.Common 6 | { 7 | /// Json反序列化时进行类型绑定 8 | /// 9 | /// 10 | public class JsonConverter : JsonConverter where TImplementation : TService 11 | { 12 | public override TService Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => JsonSerializer.Deserialize(ref reader, options); 13 | 14 | public override void Write(Utf8JsonWriter writer, TService value, JsonSerializerOptions options) => JsonSerializer.Serialize(writer, value, options); 15 | } 16 | } -------------------------------------------------------------------------------- /Stardust.Server/Common/JsonConverterForBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.Json; 3 | using System.Text.Json.Serialization; 4 | using NewLife.Log; 5 | 6 | namespace Stardust.Server.Common 7 | { 8 | internal class JsonConverterForBuilder : JsonConverter 9 | { 10 | public override ISpanBuilder Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => JsonSerializer.Deserialize(ref reader, options); 11 | 12 | public override void Write(Utf8JsonWriter writer, ISpanBuilder value, JsonSerializerOptions options) => JsonSerializer.Serialize(writer, value, options); 13 | } 14 | 15 | internal class JsonConverterForSpan : JsonConverter 16 | { 17 | public override ISpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => JsonSerializer.Deserialize(ref reader, options); 18 | 19 | public override void Write(Utf8JsonWriter writer, ISpan value, JsonSerializerOptions options) => JsonSerializer.Serialize(writer, value, options); 20 | } 21 | } -------------------------------------------------------------------------------- /Stardust.Server/Common/TokenFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Mvc.Filters; 3 | using NewLife; 4 | using NewLife.Remoting; 5 | using Stardust.Server.Controllers; 6 | 7 | namespace Stardust.Server.Common 8 | { 9 | /// 令牌校验 10 | public class TokenFilterAttribute : ActionFilterAttribute 11 | { 12 | public override void OnActionExecuting(ActionExecutingContext context) 13 | { 14 | if (context.Controller is BaseController bc) 15 | { 16 | var session = bc.Session; 17 | if (bc.Token.IsNullOrEmpty()) throw new ApiException(403, "未授权"); 18 | if (session == null) throw new ApiException(402, "令牌无效"); 19 | } 20 | 21 | base.OnActionExecuting(context); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Stardust.Server/DiscoverService.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Net; 2 | using NewLife.Remoting; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Stardust.Server 10 | { 11 | [Api(null)] 12 | class DiscoverService 13 | { 14 | public String Name { get; set; } 15 | 16 | public NetUri Local { get; set; } 17 | 18 | [Api(nameof(Discover))] 19 | public Object Discover(String state) 20 | { 21 | return new 22 | { 23 | Name = Name, 24 | Server = Local + "", 25 | State = state, 26 | }; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Stardust.Server/Models/CommandInModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Stardust.Server.Models; 4 | 5 | public class CommandInModel 6 | { 7 | /// 节点编码 8 | public String Code { get; set; } 9 | 10 | /// 命令 11 | public String Command { get; set; } 12 | 13 | /// 参数 14 | public String Argument { get; set; } 15 | 16 | /// 有效期。多久之后指令过期,单位秒,未指定时表示不限制 17 | public Int32 Expire { get; set; } 18 | } -------------------------------------------------------------------------------- /Stardust.Server/Models/ConfigInModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Server.Models; 2 | 3 | #pragma warning disable CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 4 | /// 配置入参 5 | public class ConfigInModel 6 | { 7 | ///// 令牌 8 | //public String Token { get; set; } 9 | 10 | /// 应用 11 | public String AppId { get; set; } 12 | 13 | /// 密钥 14 | public String? Secret { get; set; } 15 | 16 | /// 客户端标识 17 | public String? ClientId { get; set; } 18 | 19 | /// 作用域 20 | public String? Scope { get; set; } 21 | 22 | /// 版本 23 | public Int32 Version { get; set; } 24 | 25 | /// 已使用的键 26 | public String? UsedKeys { get; set; } 27 | 28 | /// 缺失的键 29 | public String? MissedKeys { get; set; } 30 | } 31 | #pragma warning restore CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 32 | -------------------------------------------------------------------------------- /Stardust.Server/Models/SetConfigModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Server.Models; 2 | 3 | #pragma warning disable CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 4 | /// 配置入参 5 | public class SetConfigModel 6 | { 7 | /// 应用 8 | public String AppId { get; set; } 9 | 10 | /// 密钥 11 | public String? Secret { get; set; } 12 | 13 | /// 客户端标识 14 | public String? ClientId { get; set; } 15 | 16 | /// 配置数据 17 | public IDictionary Configs { get; set; } 18 | } 19 | #pragma warning restore CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 20 | -------------------------------------------------------------------------------- /Stardust.Server/Models/TokenInModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Server.Models; 2 | 3 | #pragma warning disable CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 4 | /// 访问令牌输入参数 5 | public class TokenInModel 6 | { 7 | /// 授权类型 8 | public String? grant_type { get; set; } 9 | 10 | /// 用户名 11 | public String? UserName { get; set; } 12 | 13 | /// 密码 14 | public String? Password { get; set; } 15 | 16 | /// 客户端唯一标识。一般是IP@进程 17 | public String? ClientId { get; set; } 18 | 19 | /// 刷新令牌 20 | public String? refresh_token { get; set; } 21 | } 22 | #pragma warning restore CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 23 | -------------------------------------------------------------------------------- /Stardust.Server/Program.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Log; 2 | 3 | namespace Stardust.Server; 4 | 5 | public class Program 6 | { 7 | public static void Main(String[] args) 8 | { 9 | XTrace.UseConsole(); 10 | 11 | CreateWebHostBuilder(args).Build().Run(); 12 | } 13 | 14 | public static IHostBuilder CreateWebHostBuilder(String[] args) 15 | { 16 | var builder = Host.CreateDefaultBuilder(args); 17 | builder.ConfigureWebHostDefaults(webBuilder => 18 | { 19 | var set = StarServerSetting.Current; 20 | if (set.Port > 0) webBuilder.UseUrls($"http://*:{set.Port}"); 21 | webBuilder.UseStartup(); 22 | }); 23 | 24 | return builder; 25 | } 26 | } -------------------------------------------------------------------------------- /Stardust.Server/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Stardust.Server": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | }, 9 | "applicationUrl": "http://localhost:6600/api" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Stardust.Server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | //"RedisCache": "server=127.0.0.1;password=;db=1", 11 | //"RedisQueue": "server=127.0.0.1;password=;db=3", 12 | "StarServer": "http://127.0.0.1:6600", 13 | "ConnectionStrings": { 14 | "Stardust": "Data Source=..\\Data\\Stardust.db;ShowSql=false;Provider=SQLite", 15 | "StardustData": "Data Source=..\\Data\\StardustData.db;ShowSql=false;Provider=SQLite", 16 | "Membership": "Data Source=..\\Data\\Membership.db;Provider=SQLite", 17 | 18 | // 各种数据库连接字符串模版 19 | //"Stardust": "Server=.;Port=3306;Database=star;Uid=root;Pwd=root;ShowSql=false;Provider=MySql", 20 | //"StardustData": "MapTo=Stardust", 21 | //"Membership": "Server=.;Port=3306;Database=star;Uid=root;Pwd=root;Provider=MySql", 22 | 23 | //"Stardust": "Data Source=.;Initial Catalog=star;user=sa;password=sa;ShowSql=false;Provider=SqlServer", 24 | //"StardustData": "MapTo=Stardust", 25 | //"Membership": "Data Source=.;Initial Catalog=star;user=sa;password=sa;Provider=SqlServer", 26 | 27 | //"Stardust": "Server=.;Database=star;Uid=root;Pwd=root;ShowSql=false;Provider=PostgreSql", 28 | //"StardustData": "MapTo=Stardust", 29 | //"Membership": "Server=.;Database=star;Uid=root;Pwd=root;Provider=PostgreSql", 30 | 31 | //"Stardust": "Data Source=Tcp://127.0.0.1/ORCL;User Id=scott;Password=tiger;ShowSql=false;Provider=Oracle" 32 | //"StardustData": "MapTo=Stardust", 33 | //"Membership": "Data Source=Tcp://127.0.0.1/ORCL;User Id=scott;Password=tiger;Provider=Oracle" 34 | 35 | // 魔方审计日志使用Membership的连接字符串 36 | "Log": "MapTo=Membership", 37 | "Cube": "MapTo=Membership" 38 | } 39 | } -------------------------------------------------------------------------------- /Stardust.ServerTests/AppRuleTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Stardust.Data.Configs; 7 | using Xunit; 8 | 9 | namespace Stardust.ServerTests 10 | { 11 | public class AppRuleTests 12 | { 13 | [Fact] 14 | public void Test1() 15 | { 16 | var entity = AppRule.FindById(2) ?? new AppRule(); 17 | 18 | entity.Rule = "LocalIP=172.*"; 19 | entity.Result = "Scope=pro"; 20 | entity.Enable = true; 21 | entity.Save(); 22 | 23 | var scope = AppRule.CheckScope(1, null, null); 24 | Assert.Null(scope); 25 | 26 | var clientId = "172.21.69.46@3144"; 27 | scope = AppRule.CheckScope(1, null, clientId); 28 | 29 | Assert.Equal("pro", scope); 30 | 31 | clientId = "192.168.0.46@3144"; 32 | scope = AppRule.CheckScope(1, null, clientId); 33 | 34 | Assert.NotEqual("pro", scope); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Stardust.ServerTests/Apps/AppTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Stardust.Data; 3 | using Xunit; 4 | 5 | namespace Stardust.ServerTests.Apps; 6 | 7 | public class AppTests 8 | { 9 | [Theory] 10 | [InlineData("10.*,192.168.1.*", "192.168.0.*", "10.0.0.6", "匹配白名单且未匹配黑名单")] 11 | [InlineData("10.*;192.168.1.*", "", "10.0.0.6", "匹配白名单")] 12 | [InlineData("", "192.168.0.*", "10.0.0.6", "匹配白名单")] 13 | [InlineData("", "", "10.0.0.6", "没有黑白名单")] 14 | [InlineData("10.*,192.168.1.*", "192.168.0.*", "192.168.1.6", "匹配白名单")] 15 | [InlineData("10.*;192.168.1.*", "", "192.168.1.6", "匹配白名单")] 16 | [InlineData("", "192.168.0.*", "192.168.1.6", "匹配白名单")] 17 | [InlineData("", "", "192.168.1.6", "没有黑白名单")] 18 | public void MatchSuccess(String whites, String blacks, String ip, String message) 19 | { 20 | var app = new App 21 | { 22 | WhiteIPs = whites, 23 | BlackIPs = blacks, 24 | }; 25 | 26 | var rs = app.MatchIp(ip); 27 | Assert.True(rs, message); 28 | } 29 | 30 | [Theory] 31 | [InlineData("10.*,192.168.1.*", "192.168.0.*", "192.168.0.6", "匹配黑名单")] 32 | [InlineData("10.*;192.168.1.*", "", "192.168.0.6", "不在白名单里面")] 33 | [InlineData("", "192.168.0.*", "192.168.0.6", "匹配黑名单")] 34 | [InlineData("10.*,192.168.1.*", "192.168.*", "192.168.0.6", "同时匹配黑白名单")] 35 | public void MatchFail(String whites, String blacks, String ip, String message) 36 | { 37 | var app = new App 38 | { 39 | WhiteIPs = whites, 40 | BlackIPs = blacks, 41 | }; 42 | 43 | var rs = app.MatchIp(ip); 44 | Assert.False(rs, message); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Stardust.ServerTests/NodeTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Stardust.Data.Nodes; 7 | using Stardust.Models; 8 | using Xunit; 9 | 10 | namespace Stardust.ServerTests; 11 | 12 | public class NodeTests 13 | { 14 | [Fact] 15 | public void TestDriveSize() 16 | { 17 | var inf = new NodeInfo 18 | { 19 | DriveInfo = "C:\\[NTFS]=8.50G/200.00G,D:\\[NTFS]=80.34G/275.45G", 20 | }; 21 | var node = new Node(); 22 | node.Fill(inf); 23 | 24 | Assert.NotEmpty(node.DriveInfo); 25 | Assert.Equal(486861, node.DriveSize); 26 | Assert.Equal(Math.Round((200 + 275.45) * 1024), node.DriveSize); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Stardust.ServerTests/Nodes/NodeStatTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Xml.Linq; 7 | using Xunit; 8 | 9 | namespace Stardust.ServerTests.Nodes; 10 | 11 | public class NodeStatTests 12 | { 13 | [Fact] 14 | public void Test1() 15 | { 16 | var name = "AMD Ryzen 7 2700 Eight-Core Processor"; 17 | 18 | var p = name.IndexOf("-Core"); 19 | if (p > 0) p = name.LastIndexOf(' ', p); 20 | if (p > 0) name = name[..p].Trim(); 21 | 22 | Assert.Equal("AMD Ryzen 7 2700", name); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Stardust.ServerTests/Services/MonitorServiceTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NewLife.Reflection; 3 | using Stardust.Data.Monitors; 4 | using Xunit; 5 | using static Stardust.Server.Services.MonitorService; 6 | 7 | namespace Stardust.ServerTests.Services; 8 | 9 | public class MonitorServiceTests 10 | { 11 | [Fact] 12 | public void GetClientTest() 13 | { 14 | var actor = new WebHookActor(); 15 | actor.App = new AppTracer { WebHook = "https://newlifex.com/monitor/push?id=1234#token=abcd" }; 16 | 17 | var uri = new Uri(actor.App.WebHook); 18 | Assert.Equal("newlifex.com", uri.Host); 19 | Assert.Equal("/monitor/push", uri.AbsolutePath); 20 | Assert.Equal("?id=1234", uri.Query); 21 | Assert.Equal("/monitor/push?id=1234", uri.PathAndQuery); 22 | 23 | var client = actor.GetClient(); 24 | Assert.NotNull(client); 25 | Assert.Equal("/monitor/push?id=1234", actor.GetValue("_action")); 26 | //Assert.Equal("abcd", client.Token); 27 | Assert.Equal("abcd", client.Services[0].Token); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Stardust.ServerTests/Stardust.ServerTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | ..\Bin\ServerTest 6 | 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | true 18 | PreserveNewest 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | all 29 | runtime; build; native; contentfiles; analyzers; buildtransitive 30 | 31 | 32 | all 33 | runtime; build; native; contentfiles; analyzers; buildtransitive 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Stardust.ServerTests/TraceRuleTests.cs: -------------------------------------------------------------------------------- 1 | using Stardust.Data.Monitors; 2 | using Xunit; 3 | 4 | namespace Stardust.ServerTests; 5 | 6 | public class TraceRuleTests 7 | { 8 | [Fact] 9 | public void GetOrAddItem() 10 | { 11 | var name = "/Admin/Menu/Index"; 12 | var rule = TraceRule.Match(name); 13 | Assert.NotNull(rule); 14 | 15 | var app = AppTracer.FindByName("StarWeb"); 16 | var ti = app.GetOrAddItem(name, rule?.IsWhite); 17 | Assert.NotNull(ti); 18 | Assert.True(ti.Enable); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Stardust.ServerTests/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "StarServer": "http://127.0.0.1:6600", 11 | "ConnectionStrings": { 12 | "Stardust": { 13 | "connectionString": "Data Source=..\\..\\Data\\Stardust.db;ShowSql=false", 14 | "providerName": "SQLite" 15 | }, 16 | "Node": { 17 | "connectionString": "MapTo=Stardust", 18 | "providerName": "SQLite" 19 | }, 20 | "NodeLog": { 21 | "connectionString": "MapTo=Stardust", 22 | "providerName": "SQLite" 23 | }, 24 | "Monitor": { 25 | "connectionString": "MapTo=Stardust", 26 | "providerName": "SQLite" 27 | }, 28 | "MonitorLog": { 29 | "connectionString": "MapTo=Stardust", 30 | "providerName": "SQLite" 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Stardust.Web.Vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 星尘分布式服务平台 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Stardust.Web.Vue/lib/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Stardust.Web.Vue/lib/favicon.ico -------------------------------------------------------------------------------- /Stardust.Web.Vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "newlife-cube-vueui-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "serve": "vite", 8 | "build": "vue-tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@element-plus/icons-vue": "^2.0.10", 13 | "axios": "^1.8.2", 14 | "core-js": "^3.6.5", 15 | "element-plus": "^2.2.32", 16 | "vue": "^3.2.47", 17 | "vue-router": "^4.1.6", 18 | "vuex": "^4.1.0" 19 | }, 20 | "devDependencies": { 21 | "@vitejs/plugin-vue": "^4.0.0", 22 | "sass": "^1.26.2", 23 | "sass-loader": "^8.0.2", 24 | "typescript": "^4.5.2", 25 | "vite": "^4.5.14", 26 | "vue-tsc": "^1.0.24" 27 | } 28 | } -------------------------------------------------------------------------------- /Stardust.Web.Vue/public/leaf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Stardust.Web.Vue/public/leaf.png -------------------------------------------------------------------------------- /Stardust.Web.Vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 24 | -------------------------------------------------------------------------------- /Stardust.Web.Vue/src/CubeUI/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import * as CubeUI from '../../lib/CubeUI.js'; 3 | export default CubeUI; 4 | export * from '../../lib/CubeUI.js'; 5 | -------------------------------------------------------------------------------- /Stardust.Web.Vue/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createCubeUI, fileContext } from "CubeUI"; 2 | import "element-plus/dist/index.css"; 3 | import { createApp } from "vue"; 4 | import "../lib/style.css"; 5 | import App from "./App.vue"; 6 | 7 | const cubeUI = createCubeUI(); 8 | 9 | const app = createApp(App); 10 | app.use(cubeUI); 11 | 12 | const store = app.config.globalProperties.$store; 13 | 14 | // 注册组件 15 | const files = import.meta.glob("@/**/*.(vue|tsx)", { eager: true }); 16 | 17 | store.dispatch("setFiles", files); 18 | 19 | fileContext.addFiles(files); 20 | 21 | // store.dispatch('setUrls', { baseUrl: 'http://localhost:5000' }) 22 | store.dispatch("setUrls", { baseUrl: "http://star.newlifex.com" }); 23 | 24 | app.mount("#app"); 25 | -------------------------------------------------------------------------------- /Stardust.Web.Vue/src/views/Deployment/AppDeploy/config.tsx: -------------------------------------------------------------------------------- 1 | export const tableSearchConfig = [ 2 | { 3 | itemType: "datePicker", 4 | name: "dtStart$dtEnd", 5 | displayName: "时间范围", 6 | showInSearch: true, 7 | options: { type: "daterange", setDefaultValue: false } 8 | }, 9 | { 10 | name: "appId", 11 | displayName: "应用名称", 12 | showInSearch: true, 13 | itemType: "select", 14 | url: "/Registry/App/AppSearch", 15 | options: { 16 | method: "get", 17 | labelField: "displayName", 18 | valueField: "id", 19 | remote: true, 20 | keyField: "key" 21 | } 22 | }, 23 | { 24 | name: "category", 25 | displayName: "类别", 26 | showInSearch: true, 27 | itemType: "select", 28 | url: [ 29 | { 30 | label: "全部", 31 | value: "" 32 | }, 33 | { 34 | label: "物联网", 35 | value: "物联网" 36 | }, 37 | { 38 | label: "基础平台", 39 | value: "基础平台" 40 | }, 41 | { 42 | label: "魔方", 43 | value: "魔方" 44 | }, 45 | { 46 | label: "定位", 47 | value: "定位" 48 | }, 49 | { 50 | label: "Zero脚手架", 51 | value: "Zero脚手架" 52 | }, 53 | { 54 | label: "新生命", 55 | value: "新生命" 56 | } 57 | ] 58 | }, 59 | { 60 | name: "enable", 61 | displayName: "状态", 62 | showInSearch: true, 63 | itemType: "select", 64 | url: [ 65 | { 66 | label: "启用", 67 | value: 1 68 | }, 69 | { 70 | label: "禁用", 71 | value: 0 72 | } 73 | ] 74 | }, 75 | { 76 | name: "Q", 77 | displayName: "", 78 | showInSearch: true, 79 | options: { 80 | placeholder: "请输入关键字" 81 | } 82 | } 83 | ]; 84 | -------------------------------------------------------------------------------- /Stardust.Web.Vue/src/views/Nodes/Node/config.tsx: -------------------------------------------------------------------------------- 1 | export const tableSearchConfig = [ 2 | { 3 | itemType: "datePicker", 4 | name: "dtStart$dtEnd", 5 | displayName: "时间范围", 6 | showInSearch: true, 7 | options: { type: "daterange", setDefaultValue: false }, 8 | }, 9 | { 10 | name: "category", 11 | displayName: "类别", 12 | showInSearch: true, 13 | itemType: "select", 14 | url: [ 15 | { 16 | label: "全部", 17 | value: "", 18 | }, 19 | { 20 | label: "物联网", 21 | value: "物联网", 22 | }, 23 | { 24 | label: "基础平台", 25 | value: "基础平台", 26 | }, 27 | { 28 | label: "魔方", 29 | value: "魔方", 30 | }, 31 | { 32 | label: "定位", 33 | value: "定位", 34 | }, 35 | { 36 | label: "Zero脚手架", 37 | value: "Zero脚手架", 38 | }, 39 | { 40 | label: "新生命", 41 | value: "新生命", 42 | }, 43 | ], 44 | }, 45 | { 46 | name: "appId", 47 | displayName: "应用名称", 48 | showInSearch: true, 49 | itemType: "select", 50 | url: "/Registry/App/AppSearch", 51 | options: { 52 | method: "get", 53 | labelField: "displayName", 54 | valueField: "id", 55 | remote: true, 56 | keyField: "key", 57 | }, 58 | }, 59 | { 60 | name: "enable", 61 | displayName: "状态", 62 | showInSearch: true, 63 | itemType: "select", 64 | url: [ 65 | { 66 | label: "启用", 67 | value: 1, 68 | }, 69 | { 70 | label: "禁用", 71 | value: 0, 72 | }, 73 | ], 74 | }, 75 | { 76 | name: "Q", 77 | displayName: "", 78 | showInSearch: true, 79 | options: { 80 | placeholder: "请输入关键字", 81 | }, 82 | }, 83 | ]; 84 | -------------------------------------------------------------------------------- /Stardust.Web.Vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "moduleResolution": "Node", 7 | "strict": true, 8 | "allowJs": true, 9 | "jsx": "preserve", 10 | "sourceMap": true, 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "esModuleInterop": true, 14 | "lib": [ 15 | "ESNext", 16 | "DOM" 17 | ], 18 | "skipLibCheck": true, 19 | "types": [ 20 | "vite/client" 21 | ], 22 | "paths": { 23 | "@/*": [ 24 | "./src/*" 25 | ] 26 | } 27 | }, 28 | "include": [ 29 | "src/**/*.ts", 30 | "src/**/*.d.ts", 31 | "src/**/*.tsx", 32 | "src/**/*.vue" 33 | ], 34 | "exclude": [ 35 | "node_modules" 36 | ] 37 | } -------------------------------------------------------------------------------- /Stardust.Web.Vue/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "warning", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "linterOptions": { 7 | "exclude": [ 8 | "node_modules/**", 9 | "lib/**" 10 | ] 11 | }, 12 | "rules": { 13 | "indent": [ 14 | true, 15 | "spaces", 16 | 2 17 | ], 18 | "interface-name": false, 19 | "no-consecutive-blank-lines": false, 20 | "object-literal-sort-keys": false, 21 | "ordered-imports": false, 22 | "quotemark": [ 23 | true, 24 | "single" 25 | ], 26 | "semicolon": false, 27 | "trailing-comma": false 28 | } 29 | } -------------------------------------------------------------------------------- /Stardust.Web.Vue/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue'; 2 | import path from 'path'; 3 | import { defineConfig } from 'vite'; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue()], 8 | resolve: { 9 | alias: { 10 | '@': path.resolve(__dirname, './src'), 11 | CubeUI: path.resolve(__dirname, './src/CubeUI'), 12 | }, 13 | extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], // 默认后缀支持vue 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /Stardust.Web/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "3.1.8", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/ConfigsArea.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife; 3 | using NewLife.Cube; 4 | 5 | namespace Stardust.Web.Areas.Configs; 6 | 7 | [DisplayName("配置中心")] 8 | [Menu(666, true, LastUpdate = "20240407")] 9 | public class ConfigsArea : AreaBase 10 | { 11 | public ConfigsArea() : base(nameof(ConfigsArea).TrimEnd("Area")) { } 12 | 13 | static ConfigsArea() => RegisterArea(); 14 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/Controllers/AppQuoteController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NewLife.Cube; 4 | using NewLife.Web; 5 | using Stardust.Data.Configs; 6 | 7 | namespace Stardust.Web.Areas.Configs.Controllers 8 | { 9 | [ConfigsArea] 10 | public class AppQuoteController : EntityController 11 | { 12 | //protected override IEnumerable Search(Pager p) 13 | //{ 14 | // var appId = p["appId"].ToInt(-1); 15 | 16 | // var start = p["dtStart"].ToDateTime(); 17 | // var end = p["dtEnd"].ToDateTime(); 18 | 19 | // return AppRule.Search(appId, start, end, p["Q"], p); 20 | //} 21 | } 22 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/Controllers/AppRuleController.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Cube; 2 | using Stardust.Data.Configs; 3 | 4 | namespace Stardust.Web.Areas.Configs.Controllers; 5 | 6 | [Menu(30)] 7 | [ConfigsArea] 8 | public class AppRuleController : EntityController 9 | { 10 | static AppRuleController() 11 | { 12 | LogOnChange = true; 13 | 14 | { 15 | var df = ListFields.AddListField("Log", "CreateUserID"); 16 | df.DisplayName = "审计日志"; 17 | df.Header = "审计日志"; 18 | df.Url = "/Admin/Log?category=应用规则&linkId={Id}"; 19 | df.Target = "_frame"; 20 | } 21 | } 22 | 23 | //protected override IEnumerable Search(Pager p) 24 | //{ 25 | // var appId = p["appId"].ToInt(-1); 26 | 27 | // var start = p["dtStart"].ToDateTime(); 28 | // var end = p["dtEnd"].ToDateTime(); 29 | 30 | // return AppRule.Search(appId, start, end, p["Q"], p); 31 | //} 32 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/Controllers/ConfigOnlineController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NewLife.Cube; 4 | using NewLife.Web; 5 | using Stardust.Data.Configs; 6 | 7 | namespace Stardust.Web.Areas.Configs.Controllers 8 | { 9 | [ConfigsArea] 10 | public class ConfigOnlineController : ReadOnlyEntityController 11 | { 12 | static ConfigOnlineController() 13 | { 14 | ListFields.RemoveField("Token"); 15 | } 16 | 17 | protected override IEnumerable Search(Pager p) 18 | { 19 | var appId = p["appId"].ToInt(-1); 20 | var clientId = p["clientId"]; 21 | 22 | var start = p["dtStart"].ToDateTime(); 23 | var end = p["dtEnd"].ToDateTime(); 24 | 25 | return ConfigOnline.Search(appId, clientId, start, end, p["Q"], p); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/Views/AppConfig/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using Stardust.Data.Configs 5 | @using XCode; 6 | @using Stardust.Data.Deployment; 7 | @{ 8 | var fact = ViewBag.Factory as IEntityFactory; 9 | var page = ViewBag.Page as Pager; 10 | } 11 |
12 | 13 | @Html.ForDropDownList("category", AppConfig.GetCategoryList(), page["category"], "全部", true) 14 |
15 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/Views/AppConfig/_List_Toolbar_Custom.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @{ 3 | } 4 | 7 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/Views/ConfigData/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @{ 6 | var fact = ViewBag.Factory as IEntityFactory; 7 | var page = ViewBag.Page as Pager; 8 | } 9 | @*@await Html.PartialAsync("_DateRange")*@ -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/Views/ConfigData/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @{ 3 | var user = ViewBag.User as IUser ?? User.Identity as IUser; 4 | var fact = ViewBag.Factory as IEntityFactory; 5 | var page = ViewBag.Page as Pager; 6 | var configId = page["configId"].ToInt(-1); 7 | 8 | var set = ViewBag.PageSetting as PageSetting; 9 | } 10 | @if (set.EnableSelect) 11 | { 12 | 15 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/Views/ConfigHistory/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Configs; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | 10 | var dic = new Dictionary(); 11 | dic[1] = "成功"; 12 | dic[0] = "失败"; 13 | } 14 |
15 | 16 | @Html.ForDropDownList("action", ConfigHistory.FindAllActions(), page["action"], "全部", true) 17 |
18 |
19 | 20 | @Html.ForDropDownList("success", dic, page["success"], "全部", true) 21 |
22 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Configs/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | @using NewLife 3 | @using NewLife.Cube 4 | @using NewLife.Reflection 5 | @using NewLife.Web 6 | @using XCode 7 | @using XCode.Membership 8 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/Controllers/AppDeployOnlineController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NewLife.Cube; 4 | using NewLife.Web; 5 | using Stardust.Data.Deployment; 6 | 7 | namespace Stardust.Web.Areas.Deployment.Controllers 8 | { 9 | [Menu(88)] 10 | [DeploymentArea] 11 | public class AppDeployOnlineController : ReadOnlyEntityController 12 | { 13 | static AppDeployOnlineController() => ListFields.RemoveCreateField(); 14 | 15 | protected override IEnumerable Search(Pager p) 16 | { 17 | var id = p["id"].ToInt(-1); 18 | if (id > 0) 19 | { 20 | var entity = AppDeployOnline.FindById(id); 21 | if (entity != null) return new List { entity }; 22 | } 23 | 24 | var appId = p["appId"].ToInt(-1); 25 | var nodeId = p["nodeId"].ToInt(-1); 26 | 27 | var start = p["dtStart"].ToDateTime(); 28 | var end = p["dtEnd"].ToDateTime(); 29 | 30 | PageSetting.EnableAdd = false; 31 | 32 | return AppDeployOnline.Search(appId, nodeId, start, end, p["Q"], p); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/DeploymentArea.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife; 3 | using NewLife.Cube; 4 | 5 | namespace Stardust.Web.Areas.Deployment; 6 | 7 | [DisplayName("发布中心")] 8 | [Menu(555, true, LastUpdate = "20240407")] 9 | public class DeploymentArea : AreaBase 10 | { 11 | public DeploymentArea() : base(nameof(DeploymentArea).TrimEnd("Area")) { } 12 | 13 | static DeploymentArea() => RegisterArea(); 14 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/Views/AppDeploy/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Deployment; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | } 10 | @* @await Html.PartialAsync("_SelectApp", new SelectAppModel { Id = "appId", AppId = page["appId"].ToInt() }) *@ 11 |
12 | 13 | @Html.ForDropDownList("category", AppDeploy.GetCategoryList(), page["category"], "全部", true) 14 |
15 | @await Html.PartialAsync("_Enable") 16 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/Views/AppDeploy/_List_Toolbar_Custom.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @{ 3 | } 4 | 7 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/Views/AppDeployNode/_Form_Body.cshtml: -------------------------------------------------------------------------------- 1 | @model AppDeployNode 2 | @using NewLife.Cube.ViewModels 3 | @using Stardust.Data.Deployment; 4 | @using NewLife; 5 | @using NewLife.Web; 6 | @using XCode; 7 | @using XCode.Configuration; 8 | @using XCode.Membership; 9 | @using NewLife.Cube; 10 | @using Stardust.Web.Models; 11 | @{ 12 | var entity = Model; 13 | var fields = ViewBag.Fields as FieldCollection; 14 | var isNew = (entity as IEntity).IsNullKey; 15 | 16 | var projectId = entity.Deploy?.ProjectId ?? 0; 17 | 18 | var set = CubeSetting.Current; 19 | var cls = set.FormGroupClass; 20 | if (cls.IsNullOrEmpty()) { cls = "form-group col-xs-12 col-sm-6 col-lg-4"; } 21 | } 22 | @foreach (var item in fields) 23 | { 24 | if (!item.Field.IsIdentity) 25 | { 26 | if (item.Name == "NodeName") 27 | { 28 |
29 | 30 |
31 | @await Html.PartialAsync("_SelectNode", new SelectNodeModel { Id = "nodeId", NodeId = entity.NodeId, ProjectId = projectId, Product = "StarAgent" }) 32 |
33 |
34 | } 35 | else 36 | { 37 | @await Html.PartialAsync("_Form_Group", new ValueTuple(entity, item)) 38 | } 39 | } 40 | } 41 | @*@await Html.PartialAsync("_Form_Footer", entity) 42 | @await Html.PartialAsync("_Form_Action", entity)*@ -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/Views/AppDeployNode/_Form_SelectNode.cshtml: -------------------------------------------------------------------------------- 1 | @model EntityField 2 | @using NewLife; 3 | @using NewLife.Cube.ViewModels 4 | @using Stardust.Data.Deployment 5 | @using XCode; 6 | @using XCode.Configuration; 7 | @{ 8 | var entity = Model.Entity as AppDeployNode; 9 | var field = Model.Field; 10 | 11 | var projectId = entity.Deploy?.ProjectId ?? 0; 12 | 13 | var set = NewLife.Cube.CubeSetting.Current; 14 | var cls = set.FormGroupClass; 15 | if (cls.IsNullOrEmpty()) { cls = "form-group col-xs-12 col-sm-6 col-lg-4"; } 16 | } 17 |
18 | 19 |
20 | @await Html.PartialAsync("_SelectNode", new SelectNodeModel { Id = "nodeId", NodeId = entity.NodeId, ProjectId = projectId, Product = "StarAgent" }) 21 |
22 |
23 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/Views/AppDeployNode/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Deployment; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | } 10 | @await Html.PartialAsync("_Enable") 11 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/Views/AppDeployNode/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @using System.Collections.Generic; 3 | @{ 4 | var set = ViewBag.PageSetting as PageSetting; 5 | } 6 | @if (set.EnableSelect) 7 | { 8 | 11 | 14 | 17 | 20 | 23 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/Views/AppDeployVersion/_Form_File.cshtml: -------------------------------------------------------------------------------- 1 | @model EntityField 2 | @using NewLife; 3 | @using NewLife.Cube 4 | @using NewLife.Cube.ViewModels; 5 | @using XCode; 6 | @using XCode.Configuration; 7 | @{ 8 | var entity = Model.Entity; 9 | var field = Model.Field; 10 | 11 | var value = entity[field.Name] as String; 12 | 13 | var accept = "application/zip,application/x-zip,application/x-zip-compressed"; 14 | } 15 | @Html.TextBox(field.Name, entity[field.Name], new { @class = "form-control" }) 16 | @Html.TextBox(field.Name+"_attachment", entity[field.Name], new { type = "file", accept }) 17 | @if (!value.IsNullOrEmpty()) 18 | { 19 | 下载 20 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Deployment/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | @using NewLife 3 | @using NewLife.Cube 4 | @using NewLife.Reflection 5 | @using NewLife.Web 6 | @using XCode 7 | @using XCode.Membership 8 | @using Stardust.Web.Models; 9 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Controllers/AlarmHistoryController.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Cube; 3 | using NewLife.Web; 4 | using Stardust.Data.Monitors; 5 | 6 | namespace Stardust.Web.Areas.Monitors.Controllers; 7 | 8 | [Menu(0, false)] 9 | [MonitorsArea] 10 | public class AlarmHistoryController : ReadOnlyEntityController 11 | { 12 | protected override IEnumerable Search(Pager p) 13 | { 14 | var groupId = p["groupId"].ToInt(-1); 15 | 16 | var start = p["dtStart"].ToDateTime(); 17 | var end = p["dtEnd"].ToDateTime(); 18 | 19 | return AlarmHistory.Search(groupId, start, end, p["Q"], p); 20 | } 21 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Controllers/SampleData2Controller.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Cube; 3 | using NewLife.Web; 4 | using Stardust.Data.Monitors; 5 | using XCode; 6 | 7 | namespace Stardust.Web.Areas.Monitors.Controllers; 8 | 9 | [Menu(0, false)] 10 | [MonitorsArea] 11 | public class SampleData2Controller : ReadOnlyEntityController 12 | { 13 | static SampleData2Controller() 14 | { 15 | ListFields.RemoveField("ID"); 16 | ListFields.RemoveField("DataId"); 17 | 18 | var df = ListFields.AddListField("trace", "TraceId"); 19 | df.DisplayName = "追踪"; 20 | df.Header = "追踪"; 21 | df.Url = "/trace?id={TraceId}"; 22 | } 23 | 24 | protected override IEnumerable Search(Pager p) 25 | { 26 | var traceId = p["traceId"]; 27 | 28 | // 指定追踪标识后,分页500 29 | if (!traceId.IsNullOrEmpty()) 30 | { 31 | if (p.PageSize == 20) p.PageSize = 500; 32 | } 33 | if (p.Sort.IsNullOrEmpty()) p.OrderBy = SampleData2._.Id.Desc(); 34 | 35 | return SampleData2.Search(traceId, p["Q"], p); 36 | } 37 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Controllers/TraceController.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Microsoft.AspNetCore.Mvc; 3 | using NewLife.Cube; 4 | using XCode.Membership; 5 | 6 | namespace Stardust.Web.Areas.Monitors.Controllers; 7 | 8 | [DisplayName("链路查询")] 9 | [Menu(10, true)] 10 | [MonitorsArea] 11 | public class TraceController : ControllerBaseX 12 | { 13 | public ActionResult Index() 14 | { 15 | PageSetting.EnableNavbar = false; 16 | 17 | return View(); 18 | } 19 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Controllers/TraceRuleController.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Cube; 3 | using NewLife.Web; 4 | using Stardust.Data.Monitors; 5 | using XCode.Membership; 6 | 7 | namespace Stardust.Web.Areas.Monitors.Controllers; 8 | 9 | /// 跟踪规则。全局黑白名单,白名单放行,黑名单拦截 10 | [Menu(50, true, Icon = "fa-table")] 11 | [MonitorsArea] 12 | public class TraceRuleController : EntityController 13 | { 14 | static TraceRuleController() 15 | { 16 | LogOnChange = true; 17 | 18 | //ListFields.RemoveField("Id", "Creator"); 19 | ListFields.RemoveCreateField(); 20 | 21 | //{ 22 | // var df = ListFields.GetField("Code") as ListField; 23 | // df.Url = "?code={Code}"; 24 | //} 25 | //{ 26 | // var df = ListFields.AddListField("devices", null, "Onlines"); 27 | // df.DisplayName = "查看设备"; 28 | // df.Url = "Device?groupId={Id}"; 29 | // df.DataVisible = e => (e as TraceRule).Devices > 0; 30 | //} 31 | //{ 32 | // var df = ListFields.GetField("Kind") as ListField; 33 | // df.GetValue = e => ((Int32)(e as TraceRule).Kind).ToString("X4"); 34 | //} 35 | //ListFields.TraceUrl("TraceId"); 36 | } 37 | 38 | /// 高级搜索。列表页查询、导出Excel、导出Json、分享页等使用 39 | /// 分页器。包含分页排序参数,以及Http请求参数 40 | /// 41 | protected override IEnumerable Search(Pager p) 42 | { 43 | //var deviceId = p["deviceId"].ToInt(-1); 44 | 45 | var start = p["dtStart"].ToDateTime(); 46 | var end = p["dtEnd"].ToDateTime(); 47 | 48 | return TraceRule.Search(start, end, p["Q"], p); 49 | } 50 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/MonitorsArea.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife; 3 | using NewLife.Cube; 4 | 5 | namespace Stardust.Web.Areas.Monitors; 6 | 7 | [DisplayName("监控中心")] 8 | [Menu(444, true, LastUpdate = "20240407")] 9 | public class MonitorsArea : AreaBase 10 | { 11 | public MonitorsArea() : base(nameof(MonitorsArea).TrimEnd("Area")) { } 12 | 13 | static MonitorsArea() => RegisterArea(); 14 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/AppDayStat/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Monitors; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | 10 | var dic = AppTracer.FindAllWithCache().ToDictionary(e => e.ID, e => e + ""); 11 | 12 | // 优先使用monitorId 13 | var appId = page["appId"].ToInt(-1); 14 | var monitorId = page["monitorId"].ToInt(-1); 15 | // if (appId <= 0) appId = monitorId; 16 | // if (monitorId > 0) page["appId"] = (appId = monitorId) + ""; 17 | 18 | // 星尘监控,子系统内部跳转到当前页,只有appId;外部跳转到当前页,有appId和monitorId 19 | var app = AppTracer.FindByID(appId); 20 | if (appId > 0 && monitorId <= 0) 21 | { 22 | monitorId = appId; 23 | if (app != null) appId = app.AppId; 24 | } 25 | else if (appId > 0 && monitorId > 0) 26 | { 27 | app = AppTracer.FindByID(monitorId); 28 | } 29 | } 30 | @if (appId > 0) 31 | { 32 |
33 | @app 34 |
35 |
36 | @Html.ActionLink("每分钟", null, "appMinuteStat", new { appId = monitorId }) 37 | @Html.ActionLink("每天", null, "appDayStat", new { appId, monitorId }) 38 |
39 | } 40 |
41 | 42 | @Html.ForDropDownList("monitorId", dic, page["monitorId"], "全部", true) 43 |
44 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/AppDayStat/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @{ 3 | var user = ViewBag.User as IUser ?? User.Identity as IUser; 4 | var fact = ViewBag.Factory as IEntityFactory; 5 | var set = ViewBag.PageSetting as PageSetting; 6 | } 7 | @if (set.EnableSelect) 8 | { 9 | 12 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/AppMinuteStat/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Monitors; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | 10 | var dic = AppTracer.FindAllWithCache().ToDictionary(e => e.ID, e => e + ""); 11 | var appId = page["appId"].ToInt(-1); 12 | } 13 | @if (appId > 0) 14 | { 15 |
16 | @Html.ActionLink("每分钟", null, "appMinuteStat", new { appId }) 17 | @Html.ActionLink("每天", null, "appDayStat", new { appId }) 18 |
19 | } 20 |
21 | 22 | @Html.ForDropDownList("appId", dic, page["appId"], "全部", true) 23 |
24 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/AppTracer/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Monitors; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | } 10 |
11 | 12 | @Html.ForDropDownList("category", AppTracer.GetCategoryList(), page["category"], "全部", true) 13 |
14 | @await Html.PartialAsync("_Enable", "") 15 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/AppTracer/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @{ 3 | var user = ViewBag.User as IUser ?? User.Identity as IUser; 4 | var fact = ViewBag.Factory as IEntityFactory; 5 | var set = ViewBag.PageSetting as PageSetting; 6 | } 7 | @if (set.EnableSelect) 8 | { 9 | 12 | 15 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/Trace/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | var theme = NewLife.Cube.CubeSetting.Current.Theme; 3 | if (String.IsNullOrEmpty(theme)) theme = "ACE"; 4 | 5 | Layout = "~/Views/" + theme + "/_Layout.cshtml"; 6 | }
7 |
8 |

全链路追踪

9 |
10 |
11 |
12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 |
23 |
24 |
25 |
26 |
-------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/TraceData/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Monitors; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | 10 | var dic = AppTracer.FindAllWithCache().ToDictionary(e => e.ID, e => e + ""); 11 | var appId = page["appId"].ToInt(-1); 12 | var itemId = page["itemId"].ToInt(-1); 13 | } 14 | @if (itemId > 0) 15 | { 16 | var ti = TraceItem.FindById(itemId); 17 |
18 | @ti 19 |
20 | } 21 | @if (appId > 0) 22 | { 23 | var app = AppTracer.FindByID(appId); 24 |
25 | @app 26 |
27 | } 28 | @*
29 | 30 | @Html.ForDropDownList("appId", dic, page["appId"], "全部", true) 31 |
*@ 32 |
33 | 34 | @Html.CheckBox("searchTag", page["searchTag"].ToBoolean()) 35 |
36 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/TraceDayStat/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Monitors; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | 10 | var dic = AppTracer.FindAllWithCache().ToDictionary(e => e.ID, e => e + ""); 11 | var appId = page["monitorId"].ToInt(-1); 12 | if (appId <= 0) appId = page["appId"].ToInt(-1); 13 | var itemId = page["itemId"].ToInt(-1); 14 | } 15 | @if (itemId > 0) 16 | { 17 | var ti = TraceItem.FindById(itemId); 18 |
19 | @ti 20 |
21 | } 22 | @if (appId > 0) 23 | { 24 | var app = AppTracer.FindByID(appId); 25 |
26 | @app 27 |
28 | } 29 | @if (appId > 0 && itemId > 0) 30 | { 31 |
32 | @Html.ActionLink("每5分钟", null, "traceMinuteStat", new { appId, itemId }) 33 | @Html.ActionLink("每小时", null, "traceHourStat", new { appId, itemId }) 34 | @Html.ActionLink("每天", null, "traceDayStat", new { appId, itemId }) 35 |
36 | } 37 |
38 | 39 | @Html.ForDropDownList("appId", dic, page["appId"], "全部", true) 40 |
41 | @if (page["date"].IsNullOrEmpty()) 42 | { 43 | @await Html.PartialAsync("_DateRange") 44 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/TraceHourStat/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Monitors; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | 10 | var dic = AppTracer.FindAllWithCache().ToDictionary(e => e.ID, e => e + ""); 11 | var appId = page["appId"].ToInt(-1); 12 | var itemId = page["itemId"].ToInt(-1); 13 | } 14 | @if (itemId > 0) 15 | { 16 | var ti = TraceItem.FindById(itemId); 17 |
18 | @ti 19 |
20 | } 21 | @if (appId > 0) 22 | { 23 | var app = AppTracer.FindByID(appId); 24 |
25 | @app 26 |
27 | } 28 | @if (appId > 0 && itemId > 0) 29 | { 30 |
31 | @Html.ActionLink("每5分钟", null, "traceMinuteStat", new { appId, itemId }) 32 | @Html.ActionLink("每小时", null, "traceHourStat", new { appId, itemId }) 33 | @Html.ActionLink("每天", null, "traceDayStat", new { appId, itemId }) 34 |
35 | } 36 |
37 | 38 | @Html.ForDropDownList("appId", dic, page["appId"], "全部", true) 39 |
40 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/TraceItem/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Monitors; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | var dic = AppTracer.FindAllWithCache().ToDictionary(e => e.ID, e => e + ""); 10 | } 11 |
12 | 13 | @Html.ForDropDownList("appId", dic, page["appId"], "全部", true) 14 |
15 |
16 | 17 | @Html.ForDropDownList("kind", TraceItem.GetKinds(), page["kind"], "全部", true) 18 |
19 | @await Html.PartialAsync("_Enable", "") 20 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/TraceItem/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @{ 3 | var user = ViewBag.User as IUser ?? User.Identity as IUser; 4 | var fact = ViewBag.Factory as IEntityFactory; 5 | var set = ViewBag.PageSetting as PageSetting; 6 | } 7 | @if (set.EnableSelect) 8 | { 9 | 12 | 15 | 18 | 21 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/TraceMinuteStat/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Monitors; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | 10 | var dic = AppTracer.FindAllWithCache().ToDictionary(e => e.ID, e => e + ""); 11 | var appId = page["appId"].ToInt(-1); 12 | var itemId = page["itemId"].ToInt(-1); 13 | } 14 | @if (itemId > 0) 15 | { 16 | var ti = TraceItem.FindById(itemId); 17 |
18 | @ti 19 |
20 | } 21 | @if (appId > 0) 22 | { 23 | var app = AppTracer.FindByID(appId); 24 |
25 | @app 26 |
27 | } 28 | @if (appId > 0 && itemId > 0) 29 | { 30 |
31 | @Html.ActionLink("每5分钟", null, "traceMinuteStat", new { appId, itemId }) 32 | @Html.ActionLink("每小时", null, "traceHourStat", new { appId, itemId }) 33 | @Html.ActionLink("每天", null, "traceDayStat", new { appId, itemId }) 34 |
35 | } 36 |
37 | 38 | @Html.ForDropDownList("appId", dic, page["appId"], "全部", true) 39 |
40 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Monitors/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | @using NewLife 3 | @using NewLife.Cube 4 | @using NewLife.Reflection 5 | @using NewLife.Web 6 | @using XCode 7 | @using XCode.Membership 8 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Controllers/NodeRuleController.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Cube; 3 | using NewLife.Web; 4 | using Stardust.Data.Nodes; 5 | 6 | namespace Stardust.Web.Areas.Nodes.Controllers; 7 | 8 | [Menu(10)] 9 | [NodesArea] 10 | public class NodeRuleController : EntityController 11 | { 12 | static NodeRuleController() 13 | { 14 | LogOnChange = true; 15 | 16 | ListFields.RemoveField("Remark"); 17 | 18 | { 19 | var df = ListFields.AddListField("Log", "CreateUserID"); 20 | df.DisplayName = "审计日志"; 21 | df.Header = "审计日志"; 22 | df.Url = "/Admin/Log?category=节点规则&linkId={Id}"; 23 | df.Target = "_frame"; 24 | } 25 | } 26 | 27 | protected override IEnumerable Search(Pager p) 28 | { 29 | //var appId = p["appId"].ToInt(-1); 30 | 31 | var start = p["dtStart"].ToDateTime(); 32 | var end = p["dtEnd"].ToDateTime(); 33 | 34 | return NodeRule.Search(start, end, p["Q"], p); 35 | } 36 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/NodesArea.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife; 3 | using NewLife.Cube; 4 | 5 | namespace Stardust.Web.Areas.Nodes; 6 | 7 | [DisplayName("节点管理")] 8 | [Menu(888, true, LastUpdate = "20240407")] 9 | public class NodesArea : AreaBase 10 | { 11 | public NodesArea() : base(nameof(NodesArea).TrimEnd("Area")) { } 12 | 13 | static NodesArea() => RegisterArea(); 14 | } 15 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/Node/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Nodes; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | } 10 |
11 | 12 | @Html.ForDropDownList("category", Node.FindAllCategory(), page["category"], "全部", true) 13 |
14 |
15 | 16 | @Html.ForDropDownList("product", Node.FindAllProduct(), page["product"], "全部", true) 17 |
18 |
19 | 20 | @Html.ForDropDownList("version", Node.FindAllVersion(), page["version"], "全部", true) 21 |
22 |
23 | 24 | @Html.ForDropDownList("osKind", Node.FindAllOSKind(), page["osKind"], "全部", true) 25 |
26 | @*@await Html.PartialAsync("_Area2", "")*@ 27 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/Node/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @using System.Collections.Generic; 3 | @{ 4 | var set = ViewBag.PageSetting as PageSetting; 5 | } 6 | @if (set.EnableSelect) 7 | { 8 | 11 | 14 | 15 | 18 | 21 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/NodeCommand/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using Stardust.Data.Nodes 2 | @using NewLife; 3 | @using NewLife.Web; 4 | @using XCode; 5 | @{ 6 | var fact = ViewBag.Factory as IEntityFactory; 7 | var page = ViewBag.Page as Pager; 8 | } 9 | @await Html.PartialAsync("_SelectNode", new Stardust.Web.Models.SelectNodeModel { Id = "nodeId" }) 10 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/NodeData/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using Stardust.Data.Nodes 2 | @using NewLife; 3 | @using NewLife.Web; 4 | @using XCode; 5 | @{ 6 | var fact = ViewBag.Factory as IEntityFactory; 7 | var page = ViewBag.Page as Pager; 8 | } 9 | @await Html.PartialAsync("_SelectNode", new Stardust.Web.Models.SelectNodeModel { Id= "nodeId" }) 10 | @await Html.PartialAsync("_DateRange", "yyyy-MM-dd") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/NodeFramework/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Nodes; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | } 10 |
11 | 12 | @Html.ForDropDownList("category", Node.FindAllCategory(), page["category"], "全部", true) 13 |
14 |
15 | 16 | @Html.ForDropDownList("product", Node.FindAllProduct(), page["product"], "全部", true) 17 |
18 |
19 | 20 | @Html.ForDropDownList("version", Node.FindAllVersion(), page["version"], "全部", true) 21 |
22 |
23 | 24 | @Html.ForDropDownList("osKind", Node.FindAllOSKind(), page["osKind"], "全部", true) 25 |
26 | @*@await Html.PartialAsync("_Area2", "")*@ 27 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/NodeFramework/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @using System.Collections.Generic; 3 | @{ 4 | var set = ViewBag.PageSetting as PageSetting; 5 | var page = ViewBag.Page as Pager; 6 | } 7 | @if (set.EnableSelect) 8 | { 9 |
10 | 11 | @Html.TextBox("ver", page["ver"]) 12 | 13 | @Html.TextBox("baseUrl", page["baseUrl"]) 14 |
15 | 18 | 21 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/NodeHistory/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Nodes; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | 10 | var dic = new Dictionary(); 11 | dic.Add(1, "成功"); 12 | dic.Add(0, "失败"); 13 | } 14 | @*
15 | 16 | @Html.ForDropDownList("action", NodeHistory.FindAllAction(), page["action"], "全部", true) 17 |
*@ 18 |
19 | 20 | @Html.ForDropDownList("success", dic, page["success"], "全部", true) 21 |
22 | @await Html.PartialAsync("_SelectNode", new Stardust.Web.Models.SelectNodeModel { Id = "nodeId" }) 23 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/NodeOnline/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using Stardust.Data.Nodes; 2 | @using NewLife; 3 | @using NewLife.Web; 4 | @using XCode; 5 | @{ 6 | var fact = ViewBag.Factory as IEntityFactory; 7 | var page = ViewBag.Page as Pager; 8 | } 9 |
10 | 11 | @Html.ForDropDownList("category", Node.FindAllCategory(), page["category"], "全部", true) 12 |
13 | @await Html.PartialAsync("_Area2", "") 14 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/NodeOnline/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @using System.Collections.Generic; 3 | @{ 4 | var set = ViewBag.PageSetting as PageSetting; 5 | var page = ViewBag.Page as Pager; 6 | } 7 | @if (set.EnableSelect) 8 | { 9 | 12 | 15 | 18 | 21 |
22 | 23 | @Html.TextBox("command", page["command"]) 24 | 25 | @Html.TextBox("argument", page["argument"]) 26 |
27 | 30 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/NodeStat/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using Stardust.Data.Nodes; 2 | @using NewLife; 3 | @using NewLife.Web; 4 | @using XCode; 5 | @{ 6 | var fact = ViewBag.Factory as IEntityFactory; 7 | var page = ViewBag.Page as Pager; 8 | } 9 |
10 | 11 | @Html.ForDropDownList("category", NodeStat.FindAllCategory(), page["category"], "全部", true) 12 |
13 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/NodeVersion/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Nodes; 6 | 7 | @await Html.PartialAsync("_Enable") 8 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Nodes/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | @using NewLife 3 | @using NewLife.Cube 4 | @using NewLife.Reflection 5 | @using NewLife.Web 6 | @using XCode 7 | @using XCode.Membership 8 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Platform/Controllers/StarServerController.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife.Cube; 3 | using Stardust.Server; 4 | 5 | namespace Stardust.Web.Areas.Platform.Controllers; 6 | 7 | /// 平台设置控制器 8 | [Menu(10, true)] 9 | [DisplayName("平台设置")] 10 | [PlatformArea] 11 | public class StarServerController : ConfigController 12 | { 13 | } 14 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Platform/PlatformArea.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife; 3 | using NewLife.Cube; 4 | 5 | namespace Stardust.Web.Areas.Platform; 6 | 7 | [DisplayName("平台管理")] 8 | [Menu(999, true, LastUpdate = "20240407")] 9 | public class PlatformArea : AreaBase 10 | { 11 | public PlatformArea() : base(nameof(PlatformArea).TrimEnd("Area")) { } 12 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Redis/Controllers/RedisMessageQueueController.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Cube; 3 | using NewLife.Cube.Extensions; 4 | using NewLife.Web; 5 | using Stardust.Data.Nodes; 6 | using XCode.Membership; 7 | 8 | namespace Stardust.Web.Areas.Redis.Controllers; 9 | 10 | [Menu(30, false)] 11 | [RedisArea] 12 | public class RedisMessageQueueController : EntityController 13 | { 14 | static RedisMessageQueueController() 15 | { 16 | LogOnChange = true; 17 | 18 | ListFields.RemoveCreateField(); 19 | ListFields.RemoveUpdateField(); 20 | ListFields.AddField("UpdateTime"); 21 | ListFields.RemoveField("WebHook"); 22 | 23 | //{ 24 | // var df = ListFields.GetField("TraceId") as ListField; 25 | // df.DisplayName = "跟踪"; 26 | // df.Url = StarHelper.BuildUrl("{TraceId}"); 27 | // df.DataVisible = e => e is RedisMessageQueue entity && !entity.TraceId.IsNullOrEmpty(); 28 | //} 29 | ListFields.TraceUrl(); 30 | { 31 | var df = ListFields.AddListField("Log", "UpdateTime"); 32 | df.DisplayName = "审计日志"; 33 | df.Header = "审计日志"; 34 | df.Url = "/Admin/Log?category=Redis消息队列&linkId={Id}"; 35 | df.Target = "_frame"; 36 | } 37 | } 38 | 39 | protected override IEnumerable Search(Pager p) 40 | { 41 | var redisId = p["redisId"].ToInt(-1); 42 | 43 | var category = p["category"]; 44 | var start = p["dtStart"].ToDateTime(); 45 | var end = p["dtEnd"].ToDateTime(); 46 | 47 | return RedisMessageQueue.Search(redisId, category, start, end, p["Q"], p); 48 | } 49 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Redis/RedisArea.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife; 3 | using NewLife.Cube; 4 | 5 | namespace Stardust.Web.Areas.Redis; 6 | 7 | [DisplayName("Redis管理")] 8 | [Menu(887, true, LastUpdate = "20240407")] 9 | public class RedisArea : AreaBase 10 | { 11 | public RedisArea() : base(nameof(RedisArea).TrimEnd("Area")) { } 12 | 13 | static RedisArea() => RegisterArea(); 14 | } 15 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Redis/Views/RedisData/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using Stardust.Data.Nodes 2 | @using NewLife; 3 | @using NewLife.Web; 4 | @using XCode; 5 | @{ 6 | var fact = ViewBag.Factory as IEntityFactory; 7 | var page = ViewBag.Page as Pager; 8 | } 9 | @await Html.PartialAsync("_SelectRedis", "redisId") 10 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Redis/Views/RedisMessageQueue/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Nodes; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | } 10 | @await Html.PartialAsync("_SelectRedis", "redisId") 11 |
12 | 13 | @Html.ForDropDownList("category", RedisMessageQueue.GetCategoryList(), page["category"], "全部", true) 14 |
15 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Redis/Views/RedisNode/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data.Nodes; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | } 10 |
11 | 12 | @Html.ForDropDownList("category", RedisNode.GetCategoryList(), page["category"], "全部", true) 13 |
14 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Redis/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | @using NewLife 3 | @using NewLife.Cube 4 | @using NewLife.Reflection 5 | @using NewLife.Web 6 | @using XCode 7 | @using XCode.Membership 8 | -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Controllers/AppClientLogController.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Cube; 3 | using NewLife.Web; 4 | using Stardust.Data; 5 | using XCode.Membership; 6 | 7 | namespace Stardust.Web.Areas.Registry.Controllers; 8 | 9 | /// 应用日志 10 | [Menu(10, true, Icon = "fa-table")] 11 | [RegistryArea] 12 | public class AppClientLogController : EntityController 13 | { 14 | static AppClientLogController() 15 | { 16 | //LogOnChange = true; 17 | 18 | //ListFields.RemoveField("Id", "Creator"); 19 | ListFields.RemoveCreateField(); 20 | 21 | //{ 22 | // var df = ListFields.GetField("Code") as ListField; 23 | // df.Url = "?code={Code}"; 24 | //} 25 | //{ 26 | // var df = ListFields.AddListField("devices", null, "Onlines"); 27 | // df.DisplayName = "查看设备"; 28 | // df.Url = "Device?groupId={Id}"; 29 | // df.DataVisible = e => (e as AppClientLog).Devices > 0; 30 | //} 31 | //{ 32 | // var df = ListFields.GetField("Kind") as ListField; 33 | // df.GetValue = e => ((Int32)(e as AppClientLog).Kind).ToString("X4"); 34 | //} 35 | //ListFields.TraceUrl("TraceId"); 36 | } 37 | 38 | /// 高级搜索。列表页查询、导出Excel、导出Json、分享页等使用 39 | /// 分页器。包含分页排序参数,以及Http请求参数 40 | /// 41 | protected override IEnumerable Search(Pager p) 42 | { 43 | //var deviceId = p["deviceId"].ToInt(-1); 44 | 45 | var start = p["dtStart"].ToDateTime(); 46 | var end = p["dtEnd"].ToDateTime(); 47 | 48 | return AppClientLog.Search(start, end, p["Q"], p); 49 | } 50 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Controllers/AppLogController.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Cube; 3 | using NewLife.Web; 4 | using Stardust.Data; 5 | using XCode.Membership; 6 | 7 | namespace Stardust.Web.Areas.Registry.Controllers; 8 | 9 | [RegistryArea] 10 | [Menu(0, false)] 11 | public class AppLogController : ReadOnlyEntityController 12 | { 13 | protected override AppClientLog Find(Object key) => AppClientLog.FindById(key.ToLong()); 14 | 15 | protected override IEnumerable Search(Pager p) 16 | { 17 | PageSetting.EnableAdd = false; 18 | PageSetting.EnableNavbar = false; 19 | 20 | var appId = p["appId"].ToInt(-1); 21 | var clientId = p["clientId"]; 22 | var threadId = p["threadId"].ToInt(-1); 23 | 24 | var start = p["dtStart"].ToDateTime(); 25 | var end = p["dtEnd"].ToDateTime(); 26 | 27 | if (start.Year < 2000) 28 | { 29 | start = DateTime.Today; 30 | p["dtStart"] = start.ToString("yyyy-MM-dd"); 31 | } 32 | 33 | return AppClientLog.Search(appId, clientId, threadId, start, end, p["Q"], p); 34 | } 35 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Controllers/ServiceController.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Cube; 3 | using NewLife.Cube.ViewModels; 4 | using NewLife.Web; 5 | using Stardust.Data; 6 | using XCode.Membership; 7 | 8 | namespace Stardust.Web.Areas.Registry.Controllers; 9 | 10 | /// 服务信息。服务提供者发布的服务 11 | [Menu(40, true, Icon = "fa-table")] 12 | [RegistryArea] 13 | public class ServiceController : EntityController 14 | { 15 | static ServiceController() 16 | { 17 | LogOnChange = true; 18 | ListFields.RemoveCreateField(); 19 | 20 | ListFields.RemoveField("Secret", "HealthAddress"); 21 | ListFields.RemoveCreateField() 22 | .RemoveUpdateField() 23 | .RemoveRemarkField(); 24 | 25 | { 26 | var df = ListFields.GetField("Providers") as ListField; 27 | df.DisplayName = "{Providers}"; 28 | df.Url = "/Registry/AppService?serviceId={Id}"; 29 | } 30 | { 31 | var df = ListFields.GetField("Consumers") as ListField; 32 | df.DisplayName = "{Consumers}"; 33 | df.Url = "/Registry/AppConsume?serviceId={Id}"; 34 | } 35 | } 36 | 37 | /// 高级搜索。列表页查询、导出Excel、导出Json、分享页等使用 38 | /// 分页器。包含分页排序参数,以及Http请求参数 39 | /// 40 | protected override IEnumerable Search(Pager p) 41 | { 42 | //var deviceId = p["deviceId"].ToInt(-1); 43 | var name = p["name"]; 44 | 45 | var start = p["dtStart"].ToDateTime(); 46 | var end = p["dtEnd"].ToDateTime(); 47 | 48 | return Service.Search(name, start, end, p["Q"], p); 49 | } 50 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/RegistryArea.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife; 3 | using NewLife.Cube; 4 | 5 | namespace Stardust.Web.Areas.Registry; 6 | 7 | [DisplayName("应用中心")] 8 | [Menu(777, true, LastUpdate = "20240727")] 9 | public class RegistryArea : AreaBase 10 | { 11 | public RegistryArea() : base(nameof(RegistryArea).TrimEnd("Area")) { } 12 | 13 | static RegistryArea() => RegisterArea(); 14 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Views/App/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using Stardust.Data 5 | @using XCode; 6 | @using Stardust.Data.Nodes; 7 | @{ 8 | var fact = ViewBag.Factory as IEntityFactory; 9 | var page = ViewBag.Page as Pager; 10 | } 11 |
12 | 13 | @Html.ForDropDownList("category", App.FindAllCategory(), page["category"], "全部", true) 14 |
15 | @*@await Html.PartialAsync("_Area2", "")*@ 16 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Views/App/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @using System.Collections.Generic; 3 | @{ 4 | var set = ViewBag.PageSetting as PageSetting; 5 | } 6 | @if (set.EnableSelect) 7 | { 8 | 11 | 14 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Views/AppHistory/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using Stardust.Data 5 | @using XCode; 6 | @using Stardust.Data.Nodes; 7 | @{ 8 | var fact = ViewBag.Factory as IEntityFactory; 9 | var page = ViewBag.Page as Pager; 10 | } 11 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Views/AppLog/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using XCode; 5 | @using Stardust.Data; 6 | @{ 7 | var fact = ViewBag.Factory as IEntityFactory; 8 | var page = ViewBag.Page as Pager; 9 | } 10 |
11 | 12 | @Html.ForDropDownList("appId", App.FindAllWithCache(), page["appId"], "全部", true) 13 |
14 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Views/AppMeter/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using Stardust.Data 2 | @using NewLife; 3 | @using NewLife.Web; 4 | @using XCode; 5 | @{ 6 | var fact = ViewBag.Factory as IEntityFactory; 7 | var page = ViewBag.Page as Pager; 8 | } 9 | @*
10 | 11 | @Html.ForDropDownList("clientId", AppMeter.GetClientIds(page["appId"].ToInt()), page["clientId"], "全部", true) 12 |
*@ 13 | @await Html.PartialAsync("_DateRange", "yyyy-MM-dd") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Views/AppOnline/_List_Search.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife; 2 | @using NewLife.Web; 3 | @using NewLife.Cube; 4 | @using Stardust.Data 5 | @using XCode; 6 | @using Stardust.Data.Nodes; 7 | @{ 8 | var fact = ViewBag.Factory as IEntityFactory; 9 | var page = ViewBag.Page as Pager; 10 | } 11 |
12 | 13 | @Html.ForDropDownList("category", App.FindAllCategory(), page["category"], "全部", true) 14 |
15 | @*@await Html.PartialAsync("_Area2", "")*@ 16 | @await Html.PartialAsync("_DateRange") -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Views/AppOnline/_List_Toolbar_Batch.cshtml: -------------------------------------------------------------------------------- 1 | @using NewLife.Common; 2 | @using System.Collections.Generic; 3 | @{ 4 | var set = ViewBag.PageSetting as PageSetting; 5 | var page = ViewBag.Page as Pager; 6 | } 7 | @if (set.EnableSelect) 8 | { 9 | 12 |
13 | 14 | @Html.TextBox("command", page["command"]) 15 | 16 | @Html.TextBox("argument", page["argument"]) 17 |
18 | 21 | } -------------------------------------------------------------------------------- /Stardust.Web/Areas/Registry/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | @using NewLife 3 | @using NewLife.Cube 4 | @using NewLife.Reflection 5 | @using NewLife.Web 6 | @using XCode 7 | @using XCode.Membership 8 | -------------------------------------------------------------------------------- /Stardust.Web/Models/GraphViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Web.Models 2 | { 3 | public class GraphViewModel 4 | { 5 | public String TraceId { get; set; } 6 | 7 | public String Title { get; set; } 8 | 9 | public String Layout { get; set; } 10 | 11 | public GraphCategory[] Categories { get; set; } 12 | 13 | public GraphLink[] Links { get; set; } 14 | 15 | public GraphNode[] Nodes { get; set; } 16 | } 17 | 18 | public class GraphCategory 19 | { 20 | public String Name { get; set; } 21 | 22 | public String Symbol { get; set; } 23 | } 24 | 25 | public class GraphLink 26 | { 27 | public String Source { get; set; } 28 | 29 | public String Target { get; set; } 30 | } 31 | 32 | public class GraphNode 33 | { 34 | public String Id { get; set; } 35 | 36 | public String Name { get; set; } 37 | 38 | public Int32 Category { get; set; } 39 | 40 | public Double SymbolSize { get; set; } 41 | 42 | //public Boolean Draggable { get; set; } = true; 43 | 44 | //public Boolean Fixed { get; set; } = false; 45 | 46 | //public Double X { get; set; } 47 | 48 | //public Double Y { get; set; } 49 | 50 | public Double Value { get; set; } 51 | } 52 | } -------------------------------------------------------------------------------- /Stardust.Web/Models/SelectAppModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Stardust.Web.Models 7 | { 8 | public class SelectAppModel 9 | { 10 | public String Id { get; set; } 11 | 12 | public String Category { get; set; } 13 | 14 | public Int32 AppId { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Stardust.Web/Models/SelectNodeModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Web.Models; 2 | 3 | public class SelectNodeModel 4 | { 5 | public String Id { get; set; } 6 | 7 | public Int32 ProjectId { get; set; } 8 | 9 | public String Category { get; set; } 10 | 11 | public String Product { get; set; } 12 | 13 | public Int32 NodeId { get; set; } 14 | } 15 | -------------------------------------------------------------------------------- /Stardust.Web/Models/TraceViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using NewLife.Web; 6 | using Stardust.Data.Monitors; 7 | 8 | namespace Stardust.Web.Models 9 | { 10 | public class TraceViewModel 11 | { 12 | public Pager Page { get; set; } 13 | 14 | public IList Data { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Stardust.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore; 3 | using Microsoft.AspNetCore.Hosting; 4 | using NewLife.Log; 5 | 6 | namespace Stardust.Web 7 | { 8 | public class Program 9 | { 10 | public static void Main(String[] args) 11 | { 12 | XTrace.UseConsole(); 13 | 14 | CreateWebHostBuilder(args).Build().Run(); 15 | } 16 | 17 | public static IHostBuilder CreateWebHostBuilder(String[] args) 18 | { 19 | var builder = Host.CreateDefaultBuilder(args); 20 | builder.ConfigureWebHostDefaults(webBuilder => 21 | { 22 | webBuilder.UseStartup(); 23 | }); 24 | 25 | return builder; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Stardust.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Stardust.Web": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | }, 9 | "applicationUrl": "http://localhost:6680" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Stardust.Web/Views/Trace/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model TraceViewModel 2 | @using Stardust.Data.Monitors 3 | @using NewLife; 4 | @using NewLife.Web; 5 | @using XCode; 6 | @using XCode.Configuration; 7 | @using XCode.Membership; 8 | @using NewLife.Cube; 9 | @using System.Web; 10 | @using Stardust.Web.Models; 11 | @{ 12 | //Layout = NewLife.Cube.Setting.Current.Layout; 13 | 14 | var page = Model.Page; 15 | var list = Model.Data; 16 | var traceId = page["id"]; 17 | } 18 |
19 | @if (!traceId.IsNullOrEmpty()) 20 | { 21 | await Html.RenderPartialAsync("_Nav", traceId); 22 | } 23 | @* @if (!traceId.IsNullOrEmpty() && list.Select(e => e.AppId).Distinct().Count() > 1) 24 | { 25 | await Html.RenderPartialAsync("_AppChain", list); 26 | }*@ 27 | @if (list.Count > 0) 28 | { 29 | await Html.RenderPartialAsync("_CallChain", list); 30 | } 31 |
-------------------------------------------------------------------------------- /Stardust.Web/Views/Trace/_Nav.cshtml: -------------------------------------------------------------------------------- 1 | @model String 2 | @{ 3 | var traceId = Model; 4 | } 5 |
6 | 调用链 7 | 日志详情 8 | 关系图 9 | 关系环 10 |
-------------------------------------------------------------------------------- /Stardust.Web/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | @using NewLife 3 | @using NewLife.Cube 4 | @using NewLife.Reflection 5 | @using NewLife.Web 6 | @using XCode 7 | @using XCode.Membership 8 | @using NewLife.Cube.Areas.Admin.Models 9 | @using NewLife.Cube.Extensions 10 | @using NewLife.Cube.ViewModels -------------------------------------------------------------------------------- /Stardust.Web/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "Urls": "http://*:6680", 11 | "StarServer": "http://127.0.0.1:6600", 12 | "ConnectionStrings": { 13 | "Stardust": "Data Source=..\\Data\\Stardust.db;Provider=SQLite", 14 | "StardustData": "Data Source=..\\Data\\StardustData.db;Provider=SQLite", 15 | "Membership": "Data Source=..\\Data\\Membership.db;Provider=SQLite", 16 | 17 | // 各种数据库连接字符串模版 18 | //"Stardust": "Server=.;Port=3306;Database=star;Uid=root;Pwd=root;Provider=MySql", 19 | //"StardustData": "MapTo=Stardust", 20 | //"Membership": "Server=.;Port=3306;Database=star;Uid=root;Pwd=root;Provider=MySql", 21 | 22 | //"Stardust": "Data Source=.;Initial Catalog=star;user=sa;password=sa;Provider=SqlServer", 23 | //"StardustData": "MapTo=Stardust", 24 | //"Membership": "Data Source=.;Initial Catalog=star;user=sa;password=sa;Provider=SqlServer", 25 | 26 | //"Stardust": "Server=.;Database=star;Uid=root;Pwd=root;Provider=PostgreSql", 27 | //"StardustData": "MapTo=Stardust", 28 | //"Membership": "Server=.;Database=star;Uid=root;Pwd=root;Provider=PostgreSql", 29 | 30 | //"Stardust": "Data Source=Tcp://127.0.0.1/ORCL;User Id=scott;Password=tiger;Provider=Oracle" 31 | //"StardustData": "MapTo=Stardust", 32 | //"Membership": "Data Source=Tcp://127.0.0.1/ORCL;User Id=scott;Password=tiger;Provider=Oracle" 33 | 34 | // 魔方审计日志使用Membership的连接字符串 35 | "Log": "MapTo=Membership", 36 | "Cube": "MapTo=Membership" 37 | } 38 | } -------------------------------------------------------------------------------- /Stardust.Web/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Stardust.Web/wwwroot/icons/app.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Stardust.Web/wwwroot/icons/db.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Stardust.Web/wwwroot/icons/modbus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Stardust.Web/wwwroot/icons/mq.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Stardust/Deployment/CopyModes.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Deployment; 2 | 3 | /// 拷贝模式。发布时拷贝文件的行为模式 4 | /// 5 | /// 对于配置文件,常用Skip,因为配置文件可能在部署时被修改,如果覆盖,可能会导致配置丢失。 6 | /// 对于可执行文件,常用Overwrite,因为被发布的可执行文件一般被修改过。 7 | /// 8 | public enum CopyModes 9 | { 10 | /// 11 | None = 0, 12 | 13 | /// 跳过已存在 14 | SkipExists = 1, 15 | 16 | /// 覆盖已存在 17 | Overwrite = 2, 18 | 19 | /// 拷贝前清空 20 | ClearBeforeCopy = 3, 21 | } 22 | -------------------------------------------------------------------------------- /Stardust/Managers/ProcessInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Managers; 2 | 3 | /// 服务运行信息 4 | public class ProcessInfo 5 | { 6 | /// 名称 7 | public String Name { get; set; } = null!; 8 | 9 | /// 进程Id 10 | public Int32 ProcessId { get; set; } 11 | 12 | /// 进程名 13 | public String? ProcessName { get; set; } 14 | 15 | /// 创建时间 16 | public DateTime CreateTime { get; set; } 17 | 18 | /// 更新时间 19 | public DateTime UpdateTime { get; set; } 20 | } -------------------------------------------------------------------------------- /Stardust/Managers/VerInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Managers; 2 | 3 | /// 版本信息 4 | public class VerInfo 5 | { 6 | /// 名称 7 | public String Name { get; set; } = null!; 8 | 9 | /// 版本 10 | public String Version { get; set; } = null!; 11 | 12 | /// 补丁 13 | public String? Sp { get; set; } 14 | 15 | /// 已重载。 16 | /// 17 | public override String ToString() => String.IsNullOrEmpty(Sp) ? $"{Name} {Version}" : $"{Name} {Version} Sp{Sp}"; 18 | } -------------------------------------------------------------------------------- /Stardust/Models/AppModel.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Remoting.Models; 2 | 3 | namespace Stardust.Models; 4 | 5 | /// 应用模型 6 | public class AppModel : LoginRequest 7 | { 8 | /// 应用标识 9 | public String? AppId { get => Code; set => Code = value; } 10 | 11 | /// 应用名 12 | public String? AppName { get; set; } 13 | 14 | /// 节点编码 15 | public String? NodeCode { get; set; } 16 | 17 | /// 项目名。新应用默认所需要加入的项目 18 | public String? Project { get; set; } 19 | } -------------------------------------------------------------------------------- /Stardust/Models/CommandEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 4 | /// 命令事件参数 5 | /// 6 | public class CommandEventArgs : EventArgs 7 | { 8 | /// 9 | /// 命令 10 | /// 11 | public CommandModel? Model { get; set; } 12 | 13 | /// 14 | /// 响应 15 | /// 16 | public CommandReplyModel? Reply { get; set; } 17 | } -------------------------------------------------------------------------------- /Stardust/Models/CommandInModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 平台级发送命令参数模型 4 | public class CommandInModel 5 | { 6 | /// 编码。节点编码或应用编码 7 | public String? Code { get; set; } 8 | 9 | /// 命令 10 | public String Command { get; set; } = null!; 11 | 12 | /// 参数 13 | public String? Argument { get; set; } 14 | 15 | /// 有效期。多久之后指令过期,单位秒,未指定时表示不限制 16 | public Int32 Expire { get; set; } 17 | 18 | /// 超时时间。等待响应的时间,单位秒,未指定时表示不等待 19 | public Int32 Timeout { get; set; } 20 | } -------------------------------------------------------------------------------- /Stardust/Models/CommandModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 命令模型 4 | public class CommandModel 5 | { 6 | /// 序号 7 | public Int32 Id { get; set; } 8 | 9 | /// 命令 10 | public String Command { get; set; } = null!; 11 | 12 | /// 参数 13 | public String? Argument { get; set; } 14 | 15 | /// 开始执行时间。用于提前下发指令后延期执行,暂时不支持取消 16 | public DateTime StartTime { get; set; } 17 | 18 | /// 过期时间。未指定时表示不限制 19 | public DateTime Expire { get; set; } 20 | 21 | /// 跟踪标识。传输traceParent,用于建立全局调用链,便于查找问题 22 | public String? TraceId { get; set; } 23 | } -------------------------------------------------------------------------------- /Stardust/Models/CommandReplyModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 4 | /// 命令响应模型 5 | /// 6 | public class CommandReplyModel 7 | { 8 | /// 服务编号 9 | public Int32 Id { get; set; } 10 | 11 | /// 状态 12 | public CommandStatus Status { get; set; } 13 | 14 | /// 返回数据 15 | public String? Data { get; set; } 16 | } -------------------------------------------------------------------------------- /Stardust/Models/CommandStatus.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 命令状态 4 | public enum CommandStatus 5 | { 6 | /// 就绪 7 | 就绪 = 0, 8 | 9 | /// 处理中 10 | 处理中 = 1, 11 | 12 | /// 已完成 13 | 已完成 = 2, 14 | 15 | /// 取消 16 | 取消 = 3, 17 | 18 | /// 错误 19 | 错误 = 4, 20 | } -------------------------------------------------------------------------------- /Stardust/Models/CompileCommand.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 编译命令参数 4 | public class CompileCommand 5 | { 6 | /// 代码库。下载代码的位置 7 | public String? Repository { get; set; } 8 | 9 | /// 分支 10 | public String? Branch { get; set; } 11 | 12 | /// 项目路径。需要编译的项目路径 13 | public String? ProjectPath { get; set; } 14 | 15 | /// 项目类型。默认dotnet 16 | public ProjectKinds ProjectKind { get; set; } 17 | 18 | /// 打包过滤器。需要打包哪些文件,支持通配符,多项分号隔开 19 | public String? PackageFilters { get; set; } 20 | } 21 | -------------------------------------------------------------------------------- /Stardust/Models/ConfigInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 配置信息 4 | public class ConfigInfo 5 | { 6 | /// 版本 7 | public Int32 Version { get; set; } 8 | 9 | /// 作用域。dev/test/stag/pro 10 | public String? Scope { get; set; } 11 | 12 | /// 来源IP地址 13 | public String? SourceIP { get; set; } 14 | 15 | /// 下一个版本。如果不同于的当前版本,则说明有新版本等待发布 16 | public Int32 NextVersion { get; set; } 17 | 18 | /// 下次发布时间。用于定时发布 19 | public String? NextPublish { get; set; } 20 | 21 | /// 更新时间 22 | public DateTime UpdateTime { get; set; } 23 | 24 | /// 配置项集合 25 | public IDictionary? Configs { get; set; } 26 | } -------------------------------------------------------------------------------- /Stardust/Models/ConsumeServiceInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 消费服务信息 4 | public class ConsumeServiceInfo 5 | { 6 | /// 服务名 7 | public String ServiceName { get; set; } = null!; 8 | 9 | /// 客户端。IP加进程 10 | public String? ClientId { get; set; } 11 | 12 | /// 最低版本 13 | public String? MinVersion { get; set; } 14 | 15 | /// 标签。带有指定特性,逗号分隔 16 | public String? Tag { get; set; } 17 | } -------------------------------------------------------------------------------- /Stardust/Models/DeployInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 应用发布信息 4 | public class DeployInfo 5 | { 6 | /// 发布编号。部署节点的编号 7 | public Int32 Id { get; set; } 8 | 9 | /// 应用名称 10 | public String? Name { get; set; } 11 | 12 | /// 应用版本 13 | public String? Version { get; set; } 14 | 15 | /// 应用包地址 16 | public String? Url { get; set; } 17 | 18 | /// 哈希散列 19 | public String? Hash { get; set; } 20 | 21 | /// 覆盖文件。需要拷贝覆盖已存在的文件或子目录,支持*模糊匹配,多文件分号隔开。如果目标文件不存在,配置文件等自动拷贝 22 | public String? Overwrite { get; set; } 23 | 24 | /// 发布模式。1部分包,仅覆盖;2标准包,清空可执行文件再覆盖;3完整包,清空所有文件 25 | public DeployModes Mode { get; set; } 26 | 27 | /// 应用服务 28 | public ServiceInfo? Service { get; set; } 29 | } -------------------------------------------------------------------------------- /Stardust/Models/DeployModes.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace Stardust.Models; 4 | 5 | /// 发布模式 6 | public enum DeployModes 7 | { 8 | ///// 默认 9 | //Default = 0, 10 | 11 | /// 部分包。覆盖已有文件,保留其它文件 12 | [Description("部分包")] 13 | Partial = 1, 14 | 15 | /// 标准包。清空所有可执行文件,保留配置和数据等其它文件 16 | [Description("标准包")] 17 | Standard = 2, 18 | 19 | /// 完整包。清空所有文件 20 | [Description("完整包")] 21 | Full = 3, 22 | } -------------------------------------------------------------------------------- /Stardust/Models/EventModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 事件模型 4 | public class EventModel 5 | { 6 | /// 时间。Unix毫秒,UTC 7 | public Int64 Time { get; set; } 8 | 9 | /// 事件类型。info/alert/error 10 | public String? Type { get; set; } 11 | 12 | /// 名称。事件名称,例如LightOpen 13 | public String? Name { get; set; } 14 | 15 | /// 内容。事件详情 16 | public String? Remark { get; set; } 17 | } -------------------------------------------------------------------------------- /Stardust/Models/FrameworkModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 框架模型 4 | public class FrameworkModel 5 | { 6 | /// 要安装的目标版本 7 | public String? Version { get; set; } 8 | 9 | /// 基准路径。将从该路径下载框架安装文件 10 | public String? BaseUrl { get; set; } 11 | 12 | /// 是否强制。如果true,则已安装版本存在也强制安装。默认false 13 | public Boolean Force { get; set; } 14 | } -------------------------------------------------------------------------------- /Stardust/Models/LocalPingInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 本地心跳 4 | public class LocalPingInfo 5 | { 6 | /// 进程标识 7 | public Int32 ProcessId { get; set; } 8 | 9 | /// 进程名称 10 | public String? ProcessName { get; set; } 11 | 12 | /// 版本 13 | public String? Version { get; set; } 14 | 15 | /// 应用名 16 | public String? AppName { get; set; } 17 | 18 | /// 看门狗超时时间。默认0秒 19 | /// 20 | /// 设置看门狗超时时间,超过该时间未收到心跳,将会重启本应用进程。 21 | /// 0秒表示不启用看门狗。 22 | /// 23 | public Int32 WatchdogTimeout { get; set; } 24 | } 25 | -------------------------------------------------------------------------------- /Stardust/Models/LoginInfo.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Remoting.Models; 2 | 3 | namespace Stardust.Models; 4 | 5 | /// 节点登录信息 6 | public class LoginInfo : ILoginRequest 7 | { 8 | #region 属性 9 | /// 节点编码 10 | public String? Code { get; set; } 11 | 12 | /// 节点密钥 13 | public String? Secret { get; set; } 14 | 15 | /// 产品编码 16 | public String? ProductCode { get; set; } 17 | 18 | /// 实例。应用可能多实例部署,ip@proccessid 19 | public String? ClientId { get; set; } 20 | 21 | /// 项目名。新节点默认所需要加入的项目 22 | public String? Project { get; set; } 23 | 24 | /// 节点信息 25 | public NodeInfo? Node { get; set; } 26 | #endregion 27 | } 28 | 29 | ///// 节点登录响应 30 | //public class LoginResponse : ILoginResponse 31 | //{ 32 | // #region 属性 33 | // /// 节点编码 34 | // public String? Code { get; set; } 35 | 36 | // /// 节点密钥 37 | // public String? Secret { get; set; } 38 | 39 | // /// 名称 40 | // public String? Name { get; set; } 41 | 42 | // /// 令牌 43 | // public String? Token { get; set; } 44 | 45 | // /// 服务器时间。Unix毫秒(UTC) 46 | // public Int64 Time { get; set; } 47 | // #endregion 48 | //} -------------------------------------------------------------------------------- /Stardust/Models/MigrationEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace Stardust.Models; 4 | 5 | /// 迁移服务器事件参数 6 | public class MigrationEventArgs : CancelEventArgs 7 | { 8 | /// 新服务器 9 | public String? NewServer { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /Stardust/Models/ProjectKinds.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 项目类型 4 | public enum ProjectKinds 5 | { 6 | /// dotnet项目,SDK编译 7 | DotNet = 1, 8 | 9 | /// dotnet项目,MSBuild编译 10 | MSBuild = 2, 11 | 12 | /// 自定义项目,执行自定义脚本编译 13 | Custom = 99, 14 | } 15 | -------------------------------------------------------------------------------- /Stardust/Models/PublishServiceInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 生产服务信息 4 | public class PublishServiceInfo 5 | { 6 | /// 服务名 7 | public String ServiceName { get; set; } = null!; 8 | 9 | /// 客户端。IP加进程 10 | public String? ClientId { get; set; } 11 | 12 | /// 本地IP地址 13 | public String? IP { get; set; } 14 | 15 | /// 版本 16 | public String? Version { get; set; } 17 | 18 | /// 服务地址。本地服务地址,可能是固定地址,也可能是http://*:8080,https://*:8001之类的形式 19 | public String? Address { get; set; } 20 | 21 | /// 外部地址 22 | public String? ExternalAddress { get;set; } 23 | 24 | /// 健康检测地址 25 | public String? Health{ get; set; } 26 | 27 | /// 标签。带有指定特性,逗号分隔 28 | public String? Tag { get; set; } 29 | 30 | internal Func? AddressCallback; 31 | } -------------------------------------------------------------------------------- /Stardust/Models/RuntimeIdentifier.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 运行时标识符。定义应用包可运行的操作系统与处理器架构 4 | public enum RuntimeIdentifier 5 | { 6 | /// 任意 7 | Any = 0, 8 | 9 | /// 任意Windows系统 10 | Win = 10, 11 | /// Windows系统(32位) 12 | WinX86 = 11, 13 | /// Windows系统(64位) 14 | WinX64 = 12, 15 | /// Windows系统(32位Arm) 16 | WinArm = 13, 17 | /// Windows系统(64位Arm) 18 | WinArm64 = 14, 19 | 20 | /// 任意Linux系统 21 | Linux = 20, 22 | ///// Linux系统(32位) 23 | //LinuxX86 = 21, 24 | /// Linux系统(64位) 25 | LinuxX64 = 22, 26 | /// Linux系统(32位Arm) 27 | LinuxArm = 23, 28 | /// Linux系统(64位Arm) 29 | LinuxArm64 = 24, 30 | /// Linux系统(64位MIPS) 31 | LinuxMips64 = 26, 32 | /// Linux系统(龙芯) 33 | LinuxLA64 = 27, 34 | /// Linux系统(RISC) 35 | LinuxRiscV64 = 28, 36 | 37 | /// 任意Linux系统(musl库) 38 | LinuxMusl = 30, 39 | /// Linux系统(musl库64位) 40 | LinuxMuslX64 = 32, 41 | /// Linux系统(musl库32位Arm) 42 | LinuxMuslArm = 33, 43 | /// Linux系统(musl库64位Arm) 44 | LinuxMuslArm64 = 34, 45 | 46 | /// 任意OSX系统 47 | Osx = 40, 48 | ///// OSX系统(32位) 49 | //OsxX86 = 41, 50 | /// OSX系统(64位) 51 | OsxX64 = 42, 52 | ///// OSX系统(32位Arm) 53 | //OsxArm = 43, 54 | /// OSX系统(64位Arm) 55 | OsxArm64 = 44, 56 | } 57 | -------------------------------------------------------------------------------- /Stardust/Models/ServiceModel.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 服务模型 4 | public class ServiceModel 5 | { 6 | /// 服务名 7 | public String ServiceName { get; set; } = null!; 8 | 9 | /// 显示名 10 | public String? DisplayName { get; set; } 11 | 12 | /// 客户端。IP加进程 13 | public String? Client { get; set; } 14 | 15 | /// 版本 16 | public String? Version { get; set; } 17 | 18 | /// 服务地址。本地局域网地址 19 | public String? Address { get; set; } 20 | 21 | /// 外部地址。经过网关之前的外部地址 22 | public String? Address2 { get; set; } 23 | 24 | /// 作用域 25 | public String? Scope { get; set; } 26 | 27 | /// 标签 28 | public String? Tag { get; set; } 29 | 30 | /// 权重 31 | public Int32 Weight { get; set; } 32 | 33 | /// 创建时间 34 | public DateTime CreateTime { get; set; } 35 | 36 | /// 最后活跃时间 37 | public DateTime UpdateTime { get; set; } 38 | } -------------------------------------------------------------------------------- /Stardust/Models/ServiceModes.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 服务工作模式 4 | public enum ServiceModes 5 | { 6 | /// 默认。单例运行exe或zip 7 | Default = 0, 8 | 9 | /// 解压缩。仅解压缩文件,由外部主机托管,如IIS 10 | Extract = 1, 11 | 12 | /// 解压并运行。 13 | ExtractAndRun = 2, 14 | 15 | /// 仅运行一次。运行后自动进入禁用状态 16 | RunOnce = 3, 17 | 18 | /// 多实例。直接运行exe或zip,支持多实例 19 | Multiple = 4, 20 | } -------------------------------------------------------------------------------- /Stardust/Models/TokenModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Stardust.Models 5 | { 6 | /// 访问令牌模型 7 | public class TokenModel 8 | { 9 | /// 访问令牌 10 | [DataMember(Name = "access_token")] 11 | public String AccessToken { get; set; } 12 | 13 | /// 令牌类型 14 | [DataMember(Name = "token_type")] 15 | public String TokenType { get; set; } 16 | 17 | /// 过期时间。秒 18 | [DataMember(Name = "expire_in")] 19 | public Int32 ExpireIn { get; set; } 20 | 21 | /// 刷新令牌 22 | [DataMember(Name = "refresh_token")] 23 | public String RefreshToken { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /Stardust/Models/UpgradeInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Models; 2 | 3 | /// 更新响应 4 | public class UpgradeInfo 5 | { 6 | /// 版本号 7 | public String? Version { get; set; } 8 | 9 | /// 更新源,Url地址 10 | public String? Source { get; set; } 11 | 12 | /// 文件哈希 13 | public String? FileHash { get; set; } 14 | 15 | /// 更新前要执行的命令。解压缩后,在解压缩目录执行 16 | public String? Preinstall { get; set; } 17 | 18 | /// 更新后要执行的命令 19 | public String? Executor { get; set; } 20 | 21 | /// 是否强制更新,覆盖文件后即刻重启应用,不需要用户同意 22 | public Boolean Force { get; set; } 23 | 24 | /// 描述 25 | public String? Description { get; set; } 26 | } -------------------------------------------------------------------------------- /Stardust/Monitors/MyBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using NewLife.Log; 5 | 6 | namespace Stardust.Monitors 7 | { 8 | /// 构建器 9 | public class MyBuilder : ISpanBuilder 10 | { 11 | #region 属性 12 | /// 操作名 13 | public String Name { get; set; } 14 | 15 | /// 开始时间。Unix毫秒 16 | public Int64 StartTime { get; set; } 17 | 18 | /// 结束时间。Unix毫秒 19 | public Int64 EndTime { get; set; } 20 | 21 | /// 采样总数 22 | public Int32 Total { get; set; } 23 | 24 | /// 错误次数 25 | public Int32 Errors { get; set; } 26 | 27 | /// 总耗时。所有请求耗时累加,单位ms 28 | public Int64 Cost { get; set; } 29 | 30 | /// 最大耗时。单位ms 31 | public Int32 MaxCost { get; set; } 32 | 33 | /// 最小耗时。单位ms 34 | public Int32 MinCost { get; set; } 35 | 36 | /// 正常采样 37 | public List Samples { get; set; } 38 | 39 | /// 异常采样 40 | public List ErrorSamples { get; set; } 41 | #endregion 42 | 43 | ITracer ISpanBuilder.Tracer => throw new NotImplementedException(); 44 | 45 | IList ISpanBuilder.Samples => Samples?.Cast().ToList(); 46 | 47 | IList ISpanBuilder.ErrorSamples => ErrorSamples?.Cast().ToList(); 48 | 49 | void ISpanBuilder.Finish(ISpan span) => throw new NotImplementedException(); 50 | 51 | ISpan ISpanBuilder.Start() => throw new NotImplementedException(); 52 | } 53 | } -------------------------------------------------------------------------------- /Stardust/Monitors/MySpan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NewLife.Log; 3 | 4 | namespace Stardust.Monitors 5 | { 6 | /// 片段 7 | public class MySpan : ISpan 8 | { 9 | #region 属性 10 | /// 唯一标识。随线程上下文、Http、Rpc传递,作为内部片段的父级 11 | public String Id { get; set; } 12 | 13 | /// 父级片段标识 14 | public String ParentId { get; set; } 15 | 16 | /// 跟踪标识。可用于关联多个片段,建立依赖关系,随线程上下文、Http、Rpc传递 17 | public String TraceId { get; set; } 18 | 19 | /// 开始时间。Unix毫秒 20 | public Int64 StartTime { get; set; } 21 | 22 | /// 结束时间。Unix毫秒 23 | public Int64 EndTime { get; set; } 24 | 25 | /// 数据标签。记录一些附加数据 26 | public String Tag { get; set; } 27 | 28 | /// 错误信息 29 | public String Error { get; set; } 30 | #endregion 31 | 32 | void IDisposable.Dispose() => throw new NotImplementedException(); 33 | 34 | void ISpan.SetError(Exception ex, Object tag) => throw new NotImplementedException(); 35 | } 36 | } -------------------------------------------------------------------------------- /Stardust/Monitors/MyTraceModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Stardust.Monitors 4 | { 5 | /// 跟踪模型 6 | public class MyTraceModel 7 | { 8 | /// 应用标识 9 | public String AppId { get; set; } 10 | 11 | /// 应用名 12 | public String AppName { get; set; } 13 | 14 | /// 实例。应用可能多实例部署,ip@proccessid 15 | public String ClientId { get; set; } 16 | 17 | /// 跟踪数据 18 | public MyBuilder[] Builders { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /Stardust/Monitors/StarTracerResolver.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using NewLife; 3 | using NewLife.Log; 4 | 5 | namespace Stardust.Monitors; 6 | 7 | /// 星尘追踪解析器 8 | public class StarTracerResolver : DefaultTracerResolver 9 | { 10 | /// 单个域名最大埋点数。默认16 11 | public Int32 MaxTracePerHost { get; set; } = 16; 12 | 13 | /// 请求标签长度。HttpClient请求和WebApi请求响应作为数据标签的最大长度,小于0时不使用,默认1024字符 14 | public Int32 RequestTagLength { get; set; } = 1024; 15 | 16 | private ConcurrentDictionary> _cache = new(); 17 | 18 | /// 从Uri中解析出埋点名称 19 | /// 20 | /// 21 | /// 22 | public override String ResolveName(Uri uri, Object? userState) 23 | { 24 | String name; 25 | HashSet? keys = null; 26 | if (uri.IsAbsoluteUri) 27 | { 28 | // 域名下Http埋点过多时,埋点名称降级到域名,不再使用整个Url 29 | keys = _cache.GetOrAdd(uri.Host, k => []); 30 | if (keys.Count >= MaxTracePerHost) return $"{uri.Scheme}://{uri.Authority}"; 31 | 32 | // 太长的Url分段,不适合作为埋点名称 33 | var segments = uri.Segments.Skip(1).TakeWhile(e => e.Length <= 16).ToArray(); 34 | name = segments.Length > 0 35 | ? $"{uri.Scheme}://{uri.Authority}/{String.Concat(segments)}" 36 | : $"{uri.Scheme}://{uri.Authority}"; 37 | } 38 | else 39 | { 40 | name = uri.ToString(); 41 | var p = name.IndexOf('?'); 42 | if (p > 0) name = name[..p]; 43 | } 44 | 45 | name = ResolveName(name, userState); 46 | if (name.IsNullOrEmpty()) return name; 47 | 48 | keys?.Add(name); 49 | 50 | return name; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Stardust/Monitors/TraceModel.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Log; 2 | using Stardust.Models; 3 | 4 | namespace Stardust.Monitors; 5 | 6 | /// 追踪请求模型 7 | public class TraceModel 8 | { 9 | /// 应用标识 10 | public String? AppId { get; set; } 11 | 12 | /// 应用名 13 | public String? AppName { get; set; } 14 | 15 | /// 实例。应用可能多实例部署,ip@proccessid 16 | public String? ClientId { get; set; } 17 | 18 | /// 版本 19 | public String? Version { get; set; } 20 | 21 | /// 应用信息 22 | public AppInfo? Info { get; set; } 23 | 24 | /// 追踪数据 25 | public ISpanBuilder[]? Builders { get; set; } 26 | } 27 | 28 | /// 追踪响应模型 29 | public class TraceResponse 30 | { 31 | /// 采样周期。默认60s 32 | public Int32 Period { get; set; } = 60; 33 | 34 | /// 最大正常采样数。采样周期内,最多只记录指定数量的正常事件,用于绘制依赖关系 35 | public Int32 MaxSamples { get; set; } = 1; 36 | 37 | /// 最大异常采样数。采样周期内,最多只记录指定数量的异常事件,默认10 38 | public Int32 MaxErrors { get; set; } = 10; 39 | 40 | /// 超时时间。超过该时间时,当作异常来进行采样,默认5000毫秒 41 | public Int32 Timeout { get; set; } 42 | 43 | /// 最大标签长度。超过该长度时将截断,默认1024字符 44 | public Int32 MaxTagLength { get; set; } = 1024; 45 | 46 | /// 请求标签长度。HttpClient请求和WebApi请求响应作为数据标签的最大长度,小于0时不使用,默认1024字符 47 | public Int32 RequestTagLength { get; set; } = 1024; 48 | 49 | /// 性能收集。收集应用性能信息,数量较大的客户端可以不必收集应用性能信息 50 | public Boolean? EnableMeter { get; set; } 51 | 52 | /// 要排除的操作名 53 | public String[]? Excludes { get; set; } 54 | } -------------------------------------------------------------------------------- /Stardust/Plugins/IAgentPlugin.cs: -------------------------------------------------------------------------------- 1 | using NewLife; 2 | using NewLife.Model; 3 | 4 | namespace Stardust.Plugins; 5 | 6 | /// 星尘代理插件 7 | public interface IAgentPlugin : IPlugin 8 | { 9 | /// 开始工作 10 | public void Start(); 11 | 12 | /// 停止工作 13 | /// 14 | public void Stop(String reason); 15 | } 16 | 17 | /// 星尘代理插件基类 18 | [Plugin("StarAgent")] 19 | public abstract class AgentPlugin : DisposeBase, IAgentPlugin 20 | { 21 | /// 服务提供者 22 | public IServiceProvider? Provider { get; set; } 23 | 24 | /// 初始化插件 25 | /// 26 | /// 27 | /// 28 | /// 29 | public virtual Boolean Init(String? identity, IServiceProvider provider) 30 | { 31 | if (identity != "StarAgent") return false; 32 | 33 | Provider = provider; 34 | 35 | return true; 36 | } 37 | 38 | /// 开始工作 39 | public virtual void Start() { } 40 | 41 | /// 停止工作 42 | /// 43 | public virtual void Stop(String reason) { } 44 | } -------------------------------------------------------------------------------- /Stardust/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | Any CPU 10 | net45 11 | ..\Bin\ 12 | 13 | -------------------------------------------------------------------------------- /Stardust/Services/CacheService.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Caching; 2 | 3 | namespace Stardust.Services; 4 | 5 | /// 分布式缓存架构服务。提供基础缓存及队列服务 6 | [Obsolete] 7 | public class CacheService 8 | { 9 | #region 属性 10 | /// 全局缓存。各功能模块跨进程共享数据,分布式部署时可用Redis,需要考虑序列化成本。默认单机使用内存缓存 11 | public ICache Cache { get; set; } 12 | 13 | /// 应用内本地缓存。默认内存缓存,无需考虑对象序列化成本,缺点是不支持跨进程共享数据 14 | public ICache InnerCache { get; set; } 15 | #endregion 16 | 17 | #region 构造 18 | /// 使用默认缓存实例化 19 | public CacheService() 20 | { 21 | var cache = NewLife.Caching.Cache.Default ?? new MemoryCache(); 22 | Cache = cache; 23 | InnerCache = cache; 24 | } 25 | #endregion 26 | 27 | #region 方法 28 | /// 获取队列。各功能模块跨进程共用的队列 29 | /// 消息类型 30 | /// 主题 31 | /// 消费组 32 | /// 33 | public virtual IProducerConsumer GetQueue(String topic, String group = null) => Cache?.GetQueue(topic); 34 | 35 | /// 获取内部队列。默认内存队列 36 | /// 消息类型 37 | /// 主题 38 | /// 39 | public virtual IProducerConsumer GetInnerQueue(String topic) => InnerCache?.GetQueue(topic); 40 | 41 | /// 申请分布式锁 42 | /// 43 | /// 44 | /// 45 | public virtual IDisposable AcquireLock(String lockKey, Int32 msTimeout) => Cache?.AcquireLock(lockKey, msTimeout); 46 | #endregion 47 | } -------------------------------------------------------------------------------- /Stardust/Services/IEventProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.Services; 2 | 3 | /// 事件客户端 4 | public interface IEventProvider 5 | { 6 | /// 写事件 7 | /// 8 | /// 9 | /// 10 | Boolean WriteEvent(String type, String name, String? remark); 11 | 12 | ///// 应用心跳。上报应用信息 13 | ///// 14 | ///// 15 | //Int32 AppPing(AppInfo inf); 16 | } 17 | 18 | /// 事件客户端助手 19 | public static class EventProviderHelper 20 | { 21 | /// 写信息事件 22 | /// 23 | /// 24 | /// 25 | public static void WriteInfoEvent(this IEventProvider client, String name, String? remark) => client.WriteEvent("info", name, remark); 26 | 27 | /// 写错误事件 28 | /// 29 | /// 30 | /// 31 | public static void WriteErrorEvent(this IEventProvider client, String name, String? remark) => client.WriteEvent("error", name, remark); 32 | } -------------------------------------------------------------------------------- /Stardust/Services/StarTimeProvider.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Remoting.Clients; 2 | 3 | namespace Stardust.Services; 4 | 5 | #if !NET40 6 | internal class StarTimeProvider : TimeProvider 7 | { 8 | public ClientBase Client { get; set; } = null!; 9 | 10 | public override DateTimeOffset GetUtcNow() => Client != null ? Client.GetNow().ToUniversalTime() : base.GetUtcNow(); 11 | } 12 | #endif -------------------------------------------------------------------------------- /Stardust/StarHelper.cs: -------------------------------------------------------------------------------- 1 | using NewLife.Configuration; 2 | using NewLife.Model; 3 | 4 | namespace Stardust; 5 | 6 | /// 星尘辅助类 7 | public static class StarHelper 8 | { 9 | /// 添加星尘,提供监控、配置和服务注册发现能力。先后从参数配置和本机StarAgent读取星尘平台地址 10 | /// 11 | /// 12 | /// 13 | public static StarFactory AddStardust(this IObjectContainer services, String appId) => AddStardust(services, null, appId, null); 14 | 15 | /// 添加星尘,提供监控、配置和服务注册发现能力。先后从参数配置和本机StarAgent读取星尘平台地址 16 | /// 17 | /// 服务端地址。为空时先后读取appsettings.json、本地StarAgent、star.config,初始值为空,不连接服务端 18 | /// 应用标识。为空时读取star.config,初始值为入口程序集名称 19 | /// 应用密钥。为空时读取star.config,初始值为空 20 | /// 21 | public static StarFactory AddStardust(this IObjectContainer services, String? server = null, String? appId = null, String? secret = null) 22 | { 23 | var star = new StarFactory(server, appId, secret); 24 | 25 | // 替换为混合配置提供者,优先本地配置 26 | var old = JsonConfigProvider.LoadAppSettings(); 27 | star.SetLocalConfig(old); 28 | 29 | star.Register(services); 30 | 31 | return star; 32 | } 33 | } -------------------------------------------------------------------------------- /Stardust/StarSetting.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using NewLife.Configuration; 3 | using NewLife.Remoting.Clients; 4 | 5 | namespace Stardust; 6 | 7 | /// 星尘客户端配置 8 | [Config("Star")] 9 | public class StarSetting : Config, IClientSetting 10 | { 11 | #region 属性 12 | /// 调试开关。默认false 13 | [Description("调试开关。默认false")] 14 | public Boolean Debug { get; set; } 15 | 16 | /// 服务端地址。如http://star.newlifex.com:6600,默认为空 17 | [Description("服务端地址。如http://star.newlifex.com:6600,默认为空")] 18 | public String Server { get; set; } = ""; 19 | 20 | /// 应用标识 21 | [Description("应用标识")] 22 | public String? AppKey { get; set; } 23 | 24 | /// 应用密钥 25 | [Description("应用密钥")] 26 | public String? Secret { get; set; } 27 | 28 | ///// 服务地址。人工设定,用于提交注册中心,默认为空,自动识别外部访问地址 29 | //[Description("服务地址。人工设定,用于提交注册中心,默认为空,自动识别外部访问地址")] 30 | //public String ServiceAddress { get; set; } 31 | 32 | ///// 用户访问地址。自动记录用户访问的主机地址(反向代理之外),用于内部构造其它Url,多地址逗号隔开 33 | //[Description("用户访问地址。自动记录用户访问的主机地址(反向代理之外),用于内部构造其它Url,多地址逗号隔开")] 34 | //public String UserAddress { get; set; } 35 | 36 | /// 跟踪采样周期。默认60s 37 | [Description("跟踪采样周期。默认60s")] 38 | public Int32 TracerPeriod { get; set; } = 60; 39 | 40 | /// 最大正常采样数。采样周期内,最多只记录指定数量的正常事件,用于绘制依赖关系,默认1 41 | [Description("最大正常采样数。采样周期内,最多只记录指定数量的正常事件,用于绘制依赖关系,默认1")] 42 | public Int32 MaxSamples { get; set; } = 1; 43 | 44 | /// 最大异常采样数。采样周期内,最多只记录指定数量的异常事件,默认10 45 | [Description("最大异常采样数。采样周期内,最多只记录指定数量的异常事件,默认10")] 46 | public Int32 MaxErrors { get; set; } = 10; 47 | 48 | String IClientSetting.Code { get => AppKey!; set => AppKey = value; } 49 | #endregion 50 | } -------------------------------------------------------------------------------- /Stardust/WeiXin/Article.cs: -------------------------------------------------------------------------------- 1 | namespace Stardust.WeiXin; 2 | 3 | /// 企业微信文章消息 4 | public class Article 5 | { 6 | /// 标题,不超过128个字节,超过会自动截断 7 | public String? Title { get; set; } 8 | 9 | /// 描述,不超过512个字节,超过会自动截断 10 | public String? Description { get; set; } 11 | 12 | /// 点击后跳转的链接。 13 | public String? Url { get; set; } 14 | 15 | /// 图文消息的图片链接,支持JPG、PNG格式,较好的效果为大图 1068*455,小图150*150。 16 | public String? PicUrl { get; set; } 17 | } -------------------------------------------------------------------------------- /Test/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | ..\Bin\Test\publish\ 10 | FileSystem 11 | net5.0 12 | linux-x64 13 | false 14 | False 15 | 16 | -------------------------------------------------------------------------------- /Test/Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | 1.0 7 | $([System.DateTime]::Now.ToString(`yyyy.MMdd`)) 8 | $(VersionPrefix).$(VersionSuffix) 9 | $(Version) 10 | $(VersionPrefix).* 11 | false 12 | ..\Bin\Test 13 | false 14 | latest 15 | False 16 | 1701;1702;NU5104;NETSDK1138;CS7035 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | PreserveNewest 26 | true 27 | PreserveNewest 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Test/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*", 8 | "StarServer": "http://127.0.0.1:6600,http://star.newlifex.com:6600", 9 | "ConnectionStrings": { 10 | "Stardust": { 11 | "connectionString": "Data Source=..\\Data\\Stardust.db", 12 | "providerName": "SQLite" 13 | }, 14 | "StardustData": { 15 | "connectionString": "Data Source=..\\Data\\StardustData.db", 16 | "providerName": "SQLite" 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Tools/Resources/Plugins/SQLite.Interop.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Tools/Resources/Plugins/SQLite.Interop.dll -------------------------------------------------------------------------------- /Tools/Resources/Plugins/System.Data.SQLite.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Tools/Resources/Plugins/System.Data.SQLite.dll -------------------------------------------------------------------------------- /Tools/Resources/backup/StarAgent.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | 10 | 5500 11 | 12 | Release 13 | 14 | 3000 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tools/Resources/linux-service.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | 4 | echo "Install Stardust on Linux" 5 | 6 | if [ ! -d "/usr/share/dotnet/" ]; then 7 | curl https://x.newlifex.com/dotnet/net8.sh | sudo bash 8 | fi 9 | 10 | sudo dotnet agent\StarAgent.dll -install -server http://127.0.0.1:6600 11 | -------------------------------------------------------------------------------- /Tools/Resources/run.bat: -------------------------------------------------------------------------------- 1 | 2 | echo "Run Stardust on Windows" 3 | 4 | clover40.exe net8-host -silent 5 | 6 | start agent\StarAgent.exe -run -server http://127.0.0.1:6600 7 | 8 | ping 127.0.0.1 -n 5 > nul 9 | start http://localhost:6600/api 10 | ping 127.0.0.1 -n 5 > nul 11 | start http://localhost:6680 12 | -------------------------------------------------------------------------------- /Tools/Resources/windows-service.bat: -------------------------------------------------------------------------------- 1 | 2 | echo "Install Stardust as service on Windows" 3 | 4 | clover40.exe net8-host -silent 5 | 6 | agent\StarAgent.exe -install -server http://127.0.0.1:6600 7 | 8 | ping 127.0.0.1 -n 5 > nul 9 | start http://localhost:6600/api 10 | ping 127.0.0.1 -n 5 > nul 11 | start http://localhost:6680 12 | -------------------------------------------------------------------------------- /Tools/Scripts/net6.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | 4 | # 获取处理器架构 5 | arch=$(uname -m) 6 | ver="6.0.36" 7 | prefix="aspnetcore-runtime-$ver-linux" 8 | source="http://x.newlifex.com" 9 | 10 | echo arch: $arch 11 | 12 | # 识别Alpine 13 | if [ -f "/proc/version" ]; then 14 | cat /proc/version | grep -q -E 'musl|Alpine' 15 | if [ $? -eq 0 ]; then 16 | prefix="$prefix-musl" 17 | apk add libgcc libstdc++ 18 | fi 19 | fi 20 | 21 | # 根据处理器架构选择下载的文件 22 | if [ $arch == "x86_64" ]; then 23 | gzfile="$prefix-x64.tar.gz" 24 | elif [ $arch == "amd64" ]; then 25 | gzfile="$prefix-x64.tar.gz" 26 | elif [ $arch == "aarch64" ]; then 27 | gzfile="$prefix-arm64.tar.gz" 28 | elif [ $arch == "armv7l" ]; then 29 | gzfile="$prefix-arm.tar.gz" 30 | else 31 | gzfile="$prefix-$arch.tar.gz" 32 | fi 33 | 34 | echo gzfile: $gzfile 35 | 36 | if [ ! -f "$gzfile" ]; then 37 | wget $source/dotnet/$ver/$gzfile 38 | fi 39 | 40 | # Ubuntu默认安装在/usr/lib目录 41 | target="/usr/lib/dotnet" 42 | if [ ! -d $target ]; then 43 | target="/usr/share/dotnet" 44 | fi 45 | 46 | echo target: $target 47 | 48 | if [ ! -d $target ]; then 49 | mkdir $target 50 | fi 51 | tar -xzf $gzfile -C $target 52 | if [ ! -f "/usr/bin/dotnet" ]; then 53 | ln $target/dotnet /usr/bin/dotnet -s 54 | fi 55 | 56 | dotnet --info 57 | -------------------------------------------------------------------------------- /Tools/Scripts/star.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | 4 | if [ ! -d "/usr/lib/dotnet/" ] && [ ! -d "/usr/share/dotnet/" ]; then 5 | curl http://x.newlifex.com/dotnet/net.sh | bash 6 | fi 7 | 8 | gzfile="staragent90.tar.gz" 9 | if [ ! -f "$gzfile" ]; then 10 | wget "http://x.newlifex.com/star/"$gzfile 11 | fi 12 | if [ ! -d "agent/" ]; then 13 | mkdir agent 14 | fi 15 | tar -xzf $gzfile -C agent 16 | 17 | cd agent 18 | 19 | dotnet StarAgent.dll -uninstall 20 | dotnet StarAgent.dll -install -server http://s.newlifex.com:6600 21 | 22 | cd .. 23 | rm $gzfile -f 24 | rm star.sh -f 25 | -------------------------------------------------------------------------------- /Tools/Scripts/star8.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | 4 | if [ ! -d "/usr/lib/dotnet/" ] && [ ! -d "/usr/share/dotnet/" ]; then 5 | curl http://x.newlifex.com/dotnet/net8.sh | bash 6 | fi 7 | 8 | gzfile="staragent80.tar.gz" 9 | if [ ! -f "$gzfile" ]; then 10 | wget "http://x.newlifex.com/star/"$gzfile 11 | fi 12 | if [ ! -d "agent/" ]; then 13 | mkdir agent 14 | fi 15 | tar -xzf $gzfile -C agent 16 | 17 | cd agent 18 | 19 | dotnet StarAgent.dll -uninstall 20 | dotnet StarAgent.dll -install -server http://s.newlifex.com:6600 21 | 22 | cd .. 23 | rm $gzfile -f 24 | rm star.sh -f 25 | -------------------------------------------------------------------------------- /Tools/build.bat: -------------------------------------------------------------------------------- 1 | set base=..\Bin\Star 2 | 3 | del %base%\*.* /f/s/q 4 | 5 | set out=%base%\server 6 | rmdir /s/q %out% 7 | dotnet publish ..\Stardust.Server\Stardust.Server.csproj --nologo -c Release -o %out% 8 | del /f/s/q %out%\*.pdb %out%\*.xml %out%\*.deps.json 9 | 10 | set out=%base%\web 11 | rmdir /s/q %out% 12 | dotnet publish ..\Stardust.Web\Stardust.Web.csproj --nologo -c Release -o %out% 13 | del /f/s/q %out%\*.pdb %out%\*.xml %out%\*.deps.json 14 | rmdir /s/q %out%\wwwroot 15 | 16 | clover.exe zip %base%\StarWeb.zip %out%\ 17 | del %out%\*.exe %out%\*.dll %out%\*.config /f/s/q 18 | move %base%\StarWeb.zip %out%\StarWeb.zip 19 | 20 | set out=%base%\agent 21 | rmdir /s/q %out% 22 | dotnet publish ..\StarAgent\StarAgent.csproj --nologo -c Release -f net8.0 -o %out% 23 | del /f/s/q %out%\*.pdb %out%\*.xml %out%\*.deps.json 24 | 25 | mkdir %out%\Config 26 | xcopy Resources\backup\*.config %out%\Config\ /y/s 27 | 28 | xcopy Resources\*.bat %base%\ /y/s 29 | xcopy Resources\*.sh %base%\ /y/s 30 | copy clover40.exe %base%\clover40.exe /y 31 | 32 | mkdir %base%\Plugins 33 | 34 | del %base%\..\star.zip /f 35 | clover.exe zip %base%\..\star.zip %base%\ 36 | move %base%\..\star.zip %base%\ 37 | -------------------------------------------------------------------------------- /Tools/clover.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Tools/clover.exe -------------------------------------------------------------------------------- /Tools/clover40.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Tools/clover40.exe -------------------------------------------------------------------------------- /Tools/clover80.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewLifeX/Stardust/3258e69f81a5500be0ad23962a3fe018cf0df2ff/Tools/clover80.exe -------------------------------------------------------------------------------- /Tools/pack-agent.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set base=..\Bin\Agent 4 | set clover=..\..\..\Tools\clover.exe 5 | 6 | del %base%\*.zip /f/q 7 | del %base%\*.tar.gz /f/q 8 | 9 | pushd %base%\net9.0 10 | set name=staragent90 11 | %clover% tar ..\%name%.tar.gz *.exe *.dll *.runtimeconfig.json 12 | %clover% zip ..\%name%.zip *.exe *.dll *.runtimeconfig.json 13 | popd 14 | 15 | pushd %base%\net8.0 16 | set name=staragent80 17 | %clover% tar ..\%name%.tar.gz *.exe *.dll *.runtimeconfig.json 18 | %clover% zip ..\%name%.zip *.exe *.dll *.runtimeconfig.json 19 | popd 20 | 21 | pushd %base%\net7.0 22 | set name=staragent70 23 | %clover% tar ..\%name%.tar.gz *.exe *.dll *.runtimeconfig.json 24 | %clover% zip ..\%name%.zip *.exe *.dll *.runtimeconfig.json 25 | popd 26 | 27 | pushd %base%\net6.0 28 | set name=staragent60 29 | %clover% tar ..\%name%.tar.gz *.exe *.dll *.runtimeconfig.json 30 | %clover% zip ..\%name%.zip *.exe *.dll *.runtimeconfig.json 31 | popd 32 | 33 | pushd %base%\net5.0 34 | set name=staragent50 35 | %clover% tar ..\%name%.tar.gz *.exe *.dll *.runtimeconfig.json 36 | %clover% zip ..\%name%.zip *.exe *.dll *.runtimeconfig.json 37 | popd 38 | 39 | pushd %base%\netcoreapp3.1 40 | set name=staragent31 41 | %clover% tar ..\%name%.tar.gz *.exe *.dll *.runtimeconfig.json 42 | %clover% zip ..\%name%.zip *.exe *.dll *.runtimeconfig.json 43 | popd 44 | 45 | pushd %base%\net461 46 | set name=staragent461 47 | %clover% zip ..\%name%.zip *.exe *.dll StarAgent.exe.config 48 | popd 49 | 50 | pushd %base%\net45 51 | set name=staragent45 52 | %clover% zip ..\%name%.zip *.exe *.dll StarAgent.exe.config 53 | popd 54 | -------------------------------------------------------------------------------- /Tools/pack.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set name=StarWeb 4 | set clover=..\..\Tools\clover.exe 5 | if not exist "%clover%" ( 6 | set clover=..\..\Doc\clover.exe 7 | ) 8 | 9 | for %%f in (*.exe) do ( 10 | rem 获取文件名(去掉扩展名) 11 | set "name=%%~nf" 12 | goto :found 13 | ) 14 | 15 | :found 16 | if defined name ( 17 | del %name%.zip /f/q 18 | %clover% zip %name%.zip *.exe *.dll *.pdb appsettings.json *.runtimeconfig.json 19 | ) else ( 20 | echo No exe file found in the current directory. 21 | ) 22 | -------------------------------------------------------------------------------- /Tools/通用或专用平台.txt: -------------------------------------------------------------------------------- 1 | build.bat 通用平台,dotnet IoTServer.dll 启动应用 2 | build-linux 专用平台,./IoTServer 启动应用 3 | build-windows 专用平台,IoTServer.exe 启动应用,支持部署到IIS 4 | 5 | 输出目录: 6 | ..\Bin\iot 7 | ..\Bin\iot-linux 8 | ..\Bin\iot-windows 9 | --------------------------------------------------------------------------------