7.4 AspNetCore.Builder;Assembly.getEntryAssembly;UseSerilog;MinimumLevel.ControlledBy

发布时间:2026/10/6 10:55:33

7.4 AspNetCore.Builder;Assembly.getEntryAssembly;UseSerilog;MinimumLevel.ControlledBy 问题1ItemGroupFrameworkReferenceIncludeMicrosoft.AspNetCore.App//ItemGroupItemGroupFrameworkReferenceIncludeMicrosoft.AspNetCore.App//ItemGroup2ItemGroupFrameworkReferenceIncludeMicrosoft.AspNetCore.App//ItemGroup语法2vardomainAssembly.GetEntryAssembly()?.GetName().Name!;这行代码的作用是自动获取当前主程序的程序集名称结合你正在写的 Serilog 日志配置通常用来做日志标识、文件命名。下面逐段拆解语法并补充场景说明。一、逐部分语法拆解vardomainAssembly.GetEntryAssembly()?.GetName().Name!;Assembly.GetEntryAssembly()属于System.Reflection反射命名空间获取当前程序的入口程序集也就是程序启动时的主 exe 对应的程序集对象你的 WPF 主程序生成的 exe。通俗理解拿到当前正在运行的这个软件本身的元数据信息。?.空条件运算符安全调用机制如果前面的GetEntryAssembly()返回 null极少数特殊场景下入口程序集为空后面的.GetName()不会执行直接返回 null避免触发空引用异常崩溃。.GetName()从程序集对象中提取完整的名称信息对象里面包含程序名、版本号、公钥标记等程序元数据。.Name从名称信息中取出程序集的短名称也就是你的项目名称比如项目叫XrayDetection.UI这里拿到的就是这个字符串。!空值消除运算符和你之前学的_serviceProvider!完全一致告诉编译器这里的Name一定不会为 null强制消除“可能为空”的编译警告。正常 WPF 桌面程序启动时入口程序集必然存在Name也一定有值这里使用!是安全的。var domain隐式类型声明变量存储最终拿到的程序集名称字符串。varenvDirEnvironment.GetEnvironmentVariable(XRay_PROFILE_DIR);从 Windows 系统环境变量中读取一个自定义的目录路径是工业软件常用的「外部配置路径」写法配合你正在写的 Serilog 日志配置大概率是用来指定日志文件、配置文件的存储目录。一、语法逐段拆解Environment.NET 内置的系统环境类命名空间System用来读取系统信息、环境变量、当前用户、桌面路径等系统级数据。GetEnvironmentVariable(变量名)读取 Windows 系统中指定名称的环境变量值参数是环境变量的键名这里是自定义的XRay_PROFILE_DIR。环境变量存在返回对应的字符串路径比如D:\XRayDevice\Profile环境变量不存在返回nullvar envDir存储读取到的目录路径字符串后续代码会用这个路径来存放日志、配置文件等数据。第一个 !Assembly.GetEntryAssembly()!Assembly.GetEntryAssembly() 返回类型是 Assembly?可空编译器提示「可能为 null」! 作用告诉编译器开发者能保证这个返回值一定不为 null强制消除空引用警告场景说明你的 WPF 上位机正常双击 exe 启动时必然存在入口程序集这里不会是 null使用!是安全的极端例外单元测试、反射动态加载程序集场景才可能返回 null工控软件正常运行不会触发。二、工业项目核心价值为什么不把路径写死在代码里这是工控软件的标准设计思路核心是路径配置与代码解耦适配现场个性化要求客户现场通常会要求日志、检测数据存放在指定盘符比如 D 盘、数据盘不能放在 C 盘程序目录防止系统崩溃丢失数据。直接在系统环境变量里配置路径程序自动读取无需修改代码、重新编译打包。多设备统一部署同一款软件部署到多台设备每台设备的存储路径可能不同通过环境变量差异化配置安装包完全通用。权限兼容部分工业系统对程序目录有写保护日志、配置文件必须写到指定可写目录通过环境变量灵活适配。四、补充说明环境变量的生效范围该方法默认会依次读取「进程级环境变量 → 当前用户环境变量 → 系统环境变量」工业现场一般配置系统环境变量所有用户运行程序都能读到。空值兜底必备现场忘记配置环境变量时方法会返回 null代码里必须加空判断和默认路径兜底否则后续拼接路径会直接抛空引用异常。命名约定自定义环境变量通常用项目/设备名做前缀和系统变量区分开你这里的XRay_前缀就是典型的工业项目命名习惯。3publicstaticLoggingLevelSwitchDefaultLevelSwitch{get;}new(LogEventLevel.Verbose);LoggingLevelSwitch LogEventLevel.Verbose1.LoggingLevelSwitch是什么Serilog 提供的动态日志级别切换控制器核心作用程序运行时不用重启软件随时修改日志输出级别无需改代码重编译。内置属性MinimumLevel赋值LogEventLevel枚举控制最低输出等级典型工控场景正常生产设Information现场调试故障时界面按钮切换为Verbose打印完整硬件报文排查完切回低等级减少日志文件体积。2.LogEventLevel.Verbose日志等级从低到高完整排序等级含义工控使用场景Verbose最详细跟踪日志最低级别打印Modbus原始寄存器、EtherCAT周期数据、算法中间计算值仅本地调试用Debug调试信息仿真参数、流程步骤、函数入参输出Information正常业务记录扫描启停、用户登录、配方切换、批次完成Warning告警不中断流程单次通讯超时、温度接近阈值Error功能异常PLC断线、数据库写入失败、扫描报错Fatal致命崩溃最高级别高压异常、设备急停、程序闪退初始化new(LogEventLevel.Verbose) 默认开启全部日志所有等级日志都会输出。三、工控项目优势免重启调试产线设备故障时操作员在软件界面点“开启调试日志”立刻打印底层硬件原始报文排查完成一键关闭不用重启上位机打断生产统一全局管控WPF界面、后台WebApi、PLC心跳服务、检测算法共用一套日志级别不会出现有的模块打印、有的模块不打印过滤系统冗余日志搭配MinimumLevel.Override屏蔽微软框架大量冗余Debug日志只保留自己业务代码的详细日志。4rollOnFileSizeLimit5builder.Host.UseSerilog((context,services,config)1. 参数1context——HostBuilderContext核心能力承载程序启动时的全局配置、运行环境读取appsettings.json、环境变量配置context.Configuration[MesServerIp]获取运行环境标识context.Environment.IsDevelopment()判断是调试/生产模式2. 参数2services——IServiceProvider服务容器核心能力DI 容器实例可从容器取出已注册的服务参与日志配置工控典型用法读取数据库配置、硬件服务参数写入日志标识注入自定义加密服务过滤日志敏感字段设备密钥、账号密码示例// 从容器拿到设备基础信息服务附加到每条日志vardeviceInfoservices.GetRequiredServiceIDeviceInfoService();config.Enrich.WithProperty(DeviceCode,deviceInfo.DeviceCode);3. 参数3config——LoggerConfigurationSerilog日志配置构建器核心能力你整条日志配置的操作对象所有日志规则都靠它链式调用管控日志最低输出级别.MinimumLevel.XXX()附加日志字段.Enrich.XXX()配置输出目标文件/控制台/数据库.WriteTo.XXX()日志过滤、分流、模块独立文件.Filter.XXX()你代码里所有链式调用操作的都是这个config对象config.MinimumLevel.ControlledBy(DefaultLevelSwitch)// 操作日志级别.Enrich.FromLogContext()// 附加上下文.WriteTo.File(...)// 输出文件.WriteTo.Console(...)// 输出控制台ConfigureServiceIndependentLogs(config,baseLogPath);// 传给自定义分流方法三者完整协作逻辑context拿环境、配置文件信息做环境差异化日志策略services读取DI容器内业务服务把设备/批次信息附加进日志config最终承载全部日志输出、过滤、存储规则是Serilog的配置核心载体四、执行时序WebApplication.CreateBuilder() 创建 builder初始化 Host、DI、配置builder.Host.UseSerilog()注册日志框架到宿主内部回调执行你的日志配置代码拼接日志路径、创建文件夹、配置文件 / 控制台输出、模块分流builder.Build() 构建WebApplication实例DI 容器正式生成程序运行时所有ILogger注入自动绑定 Serilog 配置。补充说明重载区别UseSerilog有两类常用重载单参数重载UseSerilog(config {})缺少context、services无法读取配置文件和DI服务三参数重载UseSerilog((context, services, config) {})工业项目首选配置灵活性最高也是你当前使用的版本。6config.MinimumLevel.ControlledBy(DefaultLevelSwitch).Enrich.FromLogContext()MinimumLevel.ControlledBy(DefaultLevelSwitch)绑定全局静态日志级别控制器程序运行时无需重启直接修改DefaultLevelSwitch.MinimumLevel 切换日志粒度产线正常生产设 Information只保留业务、告警、报错日志减少磁盘占用硬件故障调试切 Verbose打印完整 Modbus/EtherCAT 底层报文方便定位通讯问题。Enrich.FromLogContext()开启日志上下文传递支持局部附加业务字段// 扫描单个工件时给当前流程所有日志绑定批次ID using (LogContext.PushProperty(BatchNo, scanBatch.BatchCode)) { _logger.LogInformation(开始检测工件); }每条日志自动携带批次、设备号、工位标识多任务并行时可精准过滤单流程日志。7.WriteTo.Console(outputTemplate:LogOutputTemplate);ConfigureServiceIndependentLogs(config,baseLogPath);一、.WriteTo.Console(outputTemplate:LogOutputTemplate);完整解析1. 功能作用把所有满足级别条件的日志同步输出到程序控制台窗口和文件日志共用一套格式化模板。2. 参数说明outputTemplate:LogOutputTemplate复用你定义好的全局日志模板控制台打印格式与磁盘日志文件完全统一模板示例publicconststringLogOutputTemplate{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception};输出效果示例2026-07-04 15:20:30.123 [INF] 启动X光检测上位机Web服务3. 工控项目使用建议Debug开发阶段保留实时看硬件交互、接口请求日志调试更高效Release现场生产打包可注释掉这一行减少IO性能消耗同时隐藏内部调试细节避免无关日志干扰操作员。二、ConfigureServiceIndependentLogs(config, baseLogPath);自定义分流方法解析1. 入参含义configSerilog 日志配置构建器实例和前面文件、控制台输出共用同一个配置对象baseLogPath日志根目录拼接好的D:/xrayprofiles/logs或环境变量指定目录用来存放各模块独立日志文件。2. 核心业务逻辑工控标准设计这个方法内部会通过 Serilog 的过滤器Filter按命名空间/业务模块拆分独立日志文件实现日志分层隔离典型拆分规则硬件通讯模块PLC、运动轴、相机→ 输出{domain}-Hardware.log检测算法、图像处理模块 → 输出{domain}-Detect.logMES对接WebAPI、远程接口模块 → 输出{domain}-WebApi.log主界面、业务流程模块 → 保留写入主日志{domain}-.log4. 现场落地价值产线故障排查时不用在全量混合日志里检索PLC断线 → 直接打开硬件独立日志查看原始通讯报文检测图像报错 → 只看算法模块日志大幅缩短设备故障定位时间。三、两行代码执行顺序说明先执行.WriteTo.Console()完成控制台输出配置再调用自定义方法ConfigureServiceIndependentLogs()在同一个config对象上追加多模块独立文件输出所有输出目标主文件、控制台、各模块独立文件并行生效日志会同时写入所有配置的输出通道。
延伸阅读

更多相关文章

2026/10/7 1:38:20

卡梅德生物科普:CD94(NKG2A)

在人体免疫系统的精密调控网络中,膜表面受体蛋白作为介导细胞识别与信号传导的核心载体,始终是免疫生物学与生物医药研发的关键靶点。CD94(由KLRD1基因编码)作为C型凝集素受体家族的重要成员,主要表达于自然杀伤细胞&a…

2026/10/6 2:32:02

web安全代码基础-PHP(防护过滤操作)

目录 php.ini 全局安全配置(服务器层面,第一道防线) safe_mode 安全模式(废弃,仅历史了解) open_basedir 目录访问限制(防目录遍历 / 跨目录文件读取) disable_functions 禁用危险…

2026/10/5 14:36:15

Android随笔-启动Zygote的rc文件是什么?

Zygote 启动使用 rc 文件(init 配置文件),是因为 Android 的启动流程基于 init 进程 的启动机制设计。 一、rc 文件是什么 属性说明全称init runtime configuration(init 运行时配置)格式Android init 语言&#xff…

2026/10/7 6:15:21

AI Agent工程化落地:架构、选型与实战指南

做AI应用方向这几年,我有个挺深的感受:行业最热闹的时候,不是某个模型发布的那天,而是大量开发者开始讨论“怎么把它真正用起来”的那天。2026年9月22日这天的热搜关键词里,“AI Agent”和“AI应用开发”同时挂在头部&…

2026/10/7 6:15:21

SSM图书管理系统实战:分层架构、事务控制与SQL优化

简介:这是一套面向计算机专业本科生及Java初学者的毕业设计级实战项目资源,聚焦图书管理业务场景,基于SSM(SpringSpringMVCMyBatis)主流框架完整实现前后端功能,解决课程设计、期末大作业与毕业设计中系统开…

2026/10/7 6:15:21

Servlet+JSP学生选课系统:从部署到改造的JavaWeb项目实战

简介:这是一套基于JavaWeb技术栈实现的学生选课系统,面向计算机相关专业毕业设计学生及需要项目实战的Java学习者,可解决课程管理、选课、成绩录入等常见业务场景的完整开发需求。系统采用Servlet与JSP及MySQL架构,前端结合Bootst…

2026/10/7 6:15:21

LSTM时间序列预测实战:实例代码解析与避坑指南

简介:面向机器学习初学者与时间序列预测开发者的LSTM入门实例,以房地产价格预测为场景,完整演示长短期记忆网络从数据预处理到权重更新的实现过程。LSTM通过输入门、遗忘门、输出门与细胞状态协同解决传统RNN的梯度消失问题,该实例…

2026/10/7 6:15:21

上下文工程与Agent Harness:AI编码代理10x效率实践指南

这两年AI编码代理的讨论热度一直在涨,但绝大多数人的用法还停留在“开个对话窗口、把报错贴进去”的阶段。真正拉开差距的,其实不是模型选谁、参数多大,而是两件常常被忽略的事:Context Engineering(上下文工程&#x…

2026/10/7 6:10:21

AI编程工作流实战:三个可立刻复用的高效开发流程

1. 为什么“能立刻复用”比“功能强大”更重要我见过太多人收藏了几百个AI编程工具,从代码补全到Agent框架,硬盘里塞满了各种教程和配置,但真正每天在用的工作流,掰着手指头数不超过三个。问题出在哪?不是工具不够好&a…

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/6 4:01:51

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/6 17:46:51

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:05:03

ESP32免重刷固件:浏览器直接修改NVS键值实现WiFi配置更新

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:05:03

SAP HANA查询结果导出CSV:避开乱码、性能与权限的实用指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:05:03

数字后端Placement阶段Density与Congestion控制实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑