深度解析:Azure App Service 上的日志集成、运行时安装与构建指南)
ASP.NET Core 站点扩展Site Extensions深度解析Azure App Service 上的日志集成、运行时安装与构建指南【免费下载链接】aspnetcoreASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.项目地址: https://gitcode.com/GitHub_Trending/as/aspnetcore导读本文以src/SiteExtensions/README.md为骨架深入剖析 ASP.NET Core 仓库中面向Azure App Service的站点扩展Site Extensions体系。你将了解LoggingAggregate、LoggingBranch、Runtime三个子项目各自的职责与底层实现机制XDT 配置转换、HostingStartup 程序集注入、共享运行时安装并掌握如何从源码构建这些扩展包。读完本文你既能理解 Azure App Service 上 ASP.NET Core 日志与运行时能力是如何通过站点扩展注入的也能独立完成该目录下项目的本地构建与调试。什么是 Site Extensions站点扩展是Azure App Service 专有的扩展机制不是通用 .NET 包PackageType为AzureSiteExtension。它通过预打包的内容配置文件、程序集、运行时二进制在 Azure App Service 站点上启用或增强特定能力。在本仓库中src/SiteExtensions目录下共有三个核心子项目子目录职责LoggingAggregate为 Azure App Service 上的 ASP.NET Core 应用提供日志集成的站点扩展LoggingBranch为 Azure WebSites 上的 ASP.NET Core 启用附加功能如启用 Azure 日志的站点扩展Runtime安装Microsoft.AspNetCore.App与Microsoft.NetCore.App共享运行时三者配合关系LoggingBranch是“内容生产者”产出含 HostingStartup 依赖、运行时商店的 nupkgLoggingAggregate是“聚合打包者”将多个版本、多个架构的LoggingBranch包内容聚合进一个最终扩展包Runtime则独立负责把 .NET 共享运行时与 ASP.NET Core 模块ANCM安装到 Azure App Service 环境中。LoggingAggregate日志集成扩展目录结构src/Microsoft.AspNetCore.AzureAppServices.SiteExtension扩展主体包含两个关键 XDT 转换文件与项目文件test/Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests针对 XDT 转换逻辑的单元测试TransformTest.cs及多组config_*.xml测试夹具核心机制applicationHost.xdt该扩展的关键在于 applicationHost.xdt。XDTXML Document Transform是 Azure App Service 用于在部署时改写站点applicationHost.config的声明式机制。此文件向system.webServer/runtime/environmentVariables注入三个环境变量add nameDOTNET_ADDITIONAL_DEPS value%XDT_EXTENSIONPATH%\additionalDeps\;%XDT_EXTENSIONPATH%\additionalDeps\Microsoft.AspNetCore.AzureAppServices.HostingStartup\;%ProgramFiles%\dotnet\additionalDeps\Microsoft.AspNetCore.AzureAppServices.HostingStartup\ xdt:LocatorMatch(name) xdt:TransformInsertOrAppendAttribute(Attributevalue) / add nameDOTNET_SHARED_STORE value%XDT_EXTENSIONPATH%\store xdt:LocatorMatch(name) xdt:TransformInsertOrAppendAttribute(Attributevalue) / add nameASPNETCORE_HOSTINGSTARTUPASSEMBLIES valueMicrosoft.AspNetCore.AzureAppServices.HostingStartup xdt:LocatorMatch(name) xdt:TransformInsertOrAppendAttribute(Attributevalue) /各变量的作用DOTNET_ADDITIONAL_DEPS追加的deps.json搜索路径指向扩展包内的additionalDeps目录以及全局安装的Microsoft.AspNetCore.AzureAppServices.HostingStartup位置使应用能解析到由 HostingStartup 引入的附加依赖DOTNET_SHARED_STORE指向扩展包内的运行时商店runtime store目录供共享框架外的附加程序集按需加载ASPNETCORE_HOSTINGSTARTUPASSEMBLIES声明Microsoft.AspNetCore.AzureAppServices.HostingStartup作为 HostingStartup 程序集在应用启动时被自动加载执行。该程序集的源码位于 src/Azure/AzureAppServices.HostingStartup是 Azure 日志、KeyVault 配置、数据保护等集成的入口。值得注意的细节三个变量都使用自定义转换InsertOrAppendAttribute(Attributevalue)而非覆盖式写入。这意味着如果站点环境变量已存在同名项其值会以;分隔追加而不是被替换避免破坏用户已有配置。该自定义转换由仓库内 Microsoft.Web.Xdt.Extensions 项目提供见下文。scmApplicationHost.xdt保护 SCM 主机同目录下的 scmApplicationHost.xdt 内容为空其注释道明了意图This file exists to prevent applicationHost.xdt from being applied to scm host that runs other dotnet processes (dotnet build, csc etc.)SCMSite Control Manager / Kudu主机运行dotnet build、csc等构建进程。若将日志集成的 HostingStartup 注入到这些进程会造成不必要甚至有害的干扰。因此用一个空的scmApplicationHost.xdt“占位”阻止applicationHost.xdt被应用到 SCM 主机。测试验证TransformTest.cs 配合config_empty.xml、config_existingvalue.xml、config_existingline.xml、config_existingemptyvalue.xml等夹具覆盖了“目标节点不存在 / 已存在同名变量且有值 / 已存在同名变量且值为空”等多种场景验证InsertOrAppendAttribute的追加语义与幂等性——这是本扩展正确性的重要保障。Microsoft.Web.Xdt.Extensions自定义 XDT 转换LoggingAggregate与Runtime都依赖仓库内自研的 Microsoft.Web.Xdt.Extensions其核心是 InsertOrAppendAttribute.cs 中定义的InsertOrAppendAttribute : Transform类从转换参数中解析Attribute参数名GetArgumentValue若目标节点不存在子节点则直接追加转换节点若目标节点已存在当同名属性值为空时直接赋值当值相同已应用过时直接返回保证幂等否则以;分隔进行追加。其配套测试见 InsertOrAppendAttributeTests.cs测试夹具包括config_empty.xml、config_existingvalue.xml、config_existingline.xml、config_existingemptyvalue.xml与transform.xdt与 LoggingAggregate 的测试场景相互印证。该项目的公共 API 通过 PublicAPI.Shipped.txt 与 PublicAPI.Unshipped.txt 进行基线管理。LoggingBranch附加功能与内容生产LoggingBranch/LB.csproj 描述为“This extension enables additional functionality for ASP.NET Core on Azure WebSites, such as enabling Azure logging.”。关键属性PackageId为Microsoft.AspNetCore.AzureAppServices.SiteExtension.$(AspNetCoreMajorMinorVersion).$(TargetArchitecture)即按主次版本 × 架构如8.0.x64、10.0.x86分别产出包PackageTypeAzureSiteExtension、IncludeBuildOutputfalse即只打包内容不打包编译输出通过 SiteExtension.targets 中的GenerateHostingStartupDeps目标在打包前生成两类关键内容HostingStartup 的deps.json借助HostingStartup/模板项目HostingStartup.csproj 与Program.cs引用Microsoft.AspNetCore.AzureAppServices.HostingStartup包Restore 并 Publish 后取其deps.json放置到包内additionalDeps\shared\Microsoft.AspNetCore.App\$(AspNetCoreMajorMinorVersion).0\路径下。版本固定为Major.Minor.0注释说明这是为了在补丁patch构建期间生成的扩展仍可兼容非补丁版本运行时运行时商店runtime store以ComposeStore目标生成store\目录内容供DOTNET_SHARED_STORE指向。该目标同时支持win-x64与win-x86两个 RID与扩展按 x64/x86 分架构打包的策略一致。Runtime共享运行时安装扩展Runtime/Microsoft.AspNetCore.Runtime.SiteExtension.pkgproj 描述为“This site extension installs Microsoft.AspNetCore.App and Microsoft.NetCore.App shared runtimes.”产出包名为AspNetCoreRuntime.$(AspNetCoreMajorMinorVersion).$(TargetArchitecture)。它将 ASP.NET Core 运行时发布 zip通过ResolveReferenceItemsForPackage目标从$(CrossArchitectureInstallerBasePath)解压作为content打包同时打包ANCMASP.NET Core Module V2aspnetcorev2.dll来自 src/Servers/IIS/AspNetCoreModuleV2 的AspNetCore.vcxproj与OutOfProcessRequestHandler.vcxproj两个原生项目放到包内content\ancm\目录连同Microsoft.Web.Xdt.Extensions.dll一起放入包内容。其 applicationHost.xdt 在安装时执行三项关键变更环境变量注入InsertIfMissing仅当不存在时插入避免覆盖已有配置PATH前置追加%XDT_EXTENSIONPATH%与%USERPROFILE%\.dotnet\tools使dotnet工具链可用DOTNET_SKIP_FIRST_TIME_EXPERIENCE1跳过 .NET CLI 首次运行体验遥测提示等保证无人值守环境稳定DOTNET_ROOT%XDT_EXTENSIONPATH%将 .NET 根目录指向扩展目录使运行时从扩展位置加载。替换 ANCM 全局模块Replace将AspNetCoreModuleV2的image指向扩展内的ancm\aspnetcorev2.dll确保站点使用与运行时版本匹配的 ASP.NET Core 模块。注册模块锁InsertIfMissinglockItemtrue在location级别锁定AspNetCoreModuleV2模块项防止被其他配置改写。同样地scmApplicationHost.xdt 为空文件用于防止运行时扩展被应用到 SCM 主机。install.cmd安装辅助脚本install.cmd 展示了安装期的行为FOR /R %%x IN (*.nupkg_) DO REN %%x *.nupkg SET DOTNETD:\Program Files (x86)\dotnet SET RUNTIMES%DOTNET%\shared\Microsoft.NETCore.App IF %ASPNETCORE_COPY_EXISTING_RUNTIMES% NEQ 1 EXIT /b 0 robocopy %DOTNET% . /E /XC /XN /XO /NFL /NDL ^ /XD %DOTNET%\sdk ^ /XD %RUNTIMES%\1.0.8 ^ /XD %RUNTIMES%\1.1.5 ^ /XD %RUNTIMES%\2.0.3 IF %errorlevel% geq 8 EXIT /b 1 EXIT /b 0逻辑要点先把带.nupkg_后缀的文件改名为.nupkg对应打包时为了避免包自包含问题而做的后缀重命名当环境变量ASPNETCORE_COPY_EXISTING_RUNTIMES为1时用robocopy将本机 dotnet 目录复制到扩展目录排除sdk与几个旧版本运行时目录robocopy退出码 ≥ 8 视为失败。这说明该扩展既可直接携带运行时也可按需复用目标机上已有的运行时布局。从源码构建 SiteExtensions原 README 提供了两种构建方式方式一按仓库标准流程构建遵循 仓库构建指南其中“Step 3: Build the repo”对应仓库标准构建步骤先 fork 并 clone 仓库包含子模块需--recursive按平台执行restore./restore.cmd或./restore.sh激活本地 .NET 环境后即可构建目标项目。注意该仓库含 C 原生组件如 ANCMWindows 上需要安装带 C 组件的 Visual Studio。方式二目录内直接构建在src/SiteExtensions目录内直接运行 ./build.cmd每个项目目录自带构建脚本如build.cmd/build.sh它们与eng目录的仓库级脚本不同只负责构建当前项目区域速度更快、更聚焦。以-test参数可附带运行测试例如 LoggingAggregate 下的 XDT 转换测试。构建产物与依赖关系构建是分层的LoggingBranchLB.csproj先生成按架构区分的扩展内容包LoggingAggregate的 SiteExtension.csproj 通过_SiteExtensionsReference/PackageReference引用并解压这些包包含8.0、9.0、10.0的 x64/x86 各版本以及Microsoft.AspNetCore.AzureAppServices.SiteExtension.$(AspNetCoreMajorMinorVersion).x64/.x86当前版本聚合为最终扩展包Runtime则依赖 App.Runtime 的运行时发布产物与 ANCM 原生二进制。RestoreAdditionalProjectSources指向$(ArtifactsNonShippingPackagesDir)保证包引用在仓库内闭环解析。更多信息站点扩展只是 ASP.NET Core 仓库的一小部分完整项目概览见 仓库根 README与日志集成相关的 HostingStartup 实现在 src/Azure/AzureAppServices.HostingStartup其单元测试与集成测试位于src/Azure下对应 test 目录XDT 转换的自定义扩展与测试见 Microsoft.Web.Xdt.Extensions仓库级构建、测试与排错细节可继续查阅 docs/BuildFromSource.md 与 docs/BuildErrors.md。总结src/SiteExtensions展示了微软如何用“XDT 配置转换 HostingStartup 程序集注入 共享运行时安装”三件套把 ASP.NET Core 的日志集成、附加功能和运行时能力无缝嵌入 Azure App Service。理解这一体系的关键在于三件事applicationHost.xdt/scmApplicationHost.xdt的注入与隔离设计、InsertOrAppendAttribute的幂等追加语义以及LoggingBranch → LoggingAggregate → Runtime的分层打包依赖。无论是排查 Azure App Service 上 ASP.NET Core 的日志问题还是自行构建扩展包本文梳理的源码路径与构建方式都可直接作为入手依据。【免费下载链接】aspnetcoreASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.项目地址: https://gitcode.com/GitHub_Trending/as/aspnetcore创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考