
后端工作流自动化流程编排低代码【免费下载链接】elsa-coreThe Workflow Engine for .NET项目地址https://gitcode.com/gh_mirrors/el/elsa-core点击查看免费下载导读本文围绕 ElsaThe Workflow Engine for .NET诊断能力中的“结构化日志持久化”Structured Log Persistence专项展开完整梳理该特性从需求分解、存储抽象重构到 SQLite 持久化落地与关系型提供方扩展的全部实现路径。读者将掌握结构化日志模块如何把“查询存储”“实时推送”“日志采集”三类职责拆分为可替换契约如何在不回归既有行为的前提下新增 SQLite 持久化FluentMigrator 建表、异步批量写队列、优雅停机冲刷、可选保留策略以及如何按任务清单分阶段验收并在未来接入 SQL Server、PostgreSQL、MySQL 等更多关系型数据库。该专项的完整设计文档位于specs/005-structured-log-persistence/目录本文以其中的tasks.md任务清单为骨架结合spec.md、plan.md、data-model.md、quickstart.md、contracts/persistence-contract.md以及src/modules/下的实际实现展开讲解。一、特性背景与设计目标1.1 输入需求特性的原始需求一句话可以概括为见 spec.md让结构化日志存储成为一个可插拔的关注点保留内存支持先提供简单易用的 SQLite 持久化存储使用 FluentMigrator 管理 Schema并推迟 OpenTelemetry/导出器范围。即存储可插拔、内存默认、SQLite 先行、FluentMigrator 管 Schema、导出器后置。1.2 关键设计决策Clarifications在规格澄清阶段2026-05-12 与 2026-05-13 两次会话敲定的核心决策如下决策项结论是否现在就加 Logstash / Datadog / Splunk / Loki / Seq 等厂商 Sink否第一刀保持最小范围是否现在就加 OTLP 日志导出器否推迟到诊断 OpenTelemetry 边界更清晰时初始存储提供方有哪些保留内存存储新增 opt-in 的 SQLite 持久化SQLite 是否做成一次性实现否作为第一个关系型提供方便于后续扩展 SQL Server / PostgreSQL / MySQL是否使用 EF Core否本特性避免 EF Core 与各提供方的 EF 迁移Schema 创建与升级用谁FluentMigrator 做版本化迁移热路径用显式 SQL / Dapper 风格访问SQLite 写入的持久性保证异步批量写入 优雅停机冲刷进程崩溃可能丢失排队未刷的事件写队列满了怎么办丢弃最新入队事件并上报丢弃计数/指标绝不阻塞日志调用、不无限增长内存SQLite 迁移何时运行默认启动时自动迁移提供 opt-out时间戳如何存以 UTC ISO-8601 文本存储默认保留策略默认不删除仅当配置了最大年龄或最大行数时才执行清理1.3 范围边界明确不做OTLP 日志导出、厂商 Sink、原始控制台流式输出、Trace/Metric 探索见 quickstart.md 的 Out of scope 与 spec.md 的 Assumptions。必须保留脱敏redaction必须先于任何存储与实时投递FR-005Studio 的 REST 与 SignalR 契约不变FR-024、US3 验收场景 3。二、总体架构存储 / 实时 / 采集三职责拆分2.1 为什么必须重构在持久化之前IStructuredLogProvider同时承担了“查询最近日志”“订阅实时日志”“发布日志事件”等多个职责。若直接为 SQLite 写一个一次性的 Store会造成不可扩展的死胡同。因此plan.md的 Phase 2 明确要求拆分 Store 与 Live-Feed 关注点同时保留现有IStructuredLogProvider门面plan.md 的 Summary。2.2 核心契约Phase 2任务 T009–T011设计文档 contracts/persistence-contract.md 定义了四个核心契约仓库中对应的实现位于 src/modules/Elsa.Diagnostics.StructuredLogs/Contracts/IStructuredLogSink只追加的写入边界接收单个事件或批量事件不必支持查询。源码见 IStructuredLogSink.cs。IStructuredLogStore : IStructuredLogSink可查询的存储边界负责追加脱敏事件、按StructuredLogFilter查询最近事件、列出StructuredLogSource。源码见 IStructuredLogStore.cs。IStructuredLogLiveFeed运行时实时投递边界向 SignalR 订阅者发布新事件、应用订阅过滤器、在订阅队列溢出时报告丢弃摘要不保证持久性。源码见 IStructuredLogLiveFeed.cs。在契约层面三个接口的形态为// IStructuredLogSink —— 只追加 public interface IStructuredLogSink { ValueTask WriteAsync(StructuredLogEvent logEvent, CancellationToken cancellationToken default); ValueTask WriteManyAsync(IReadOnlyCollectionStructuredLogEvent logEvents, CancellationToken cancellationToken default); } // IStructuredLogStore —— 可查询存储 public interface IStructuredLogStore : IStructuredLogSink { ValueTaskRecentStructuredLogsResult QueryAsync(StructuredLogFilter filter, CancellationToken cancellationToken default); ValueTaskIReadOnlyCollectionStructuredLogSource ListSourcesAsync(CancellationToken cancellationToken default); } // IStructuredLogLiveFeed —— 实时推送 public interface IStructuredLogLiveFeed { ValueTask PublishAsync(StructuredLogEvent logEvent, CancellationToken cancellationToken default); IAsyncEnumerableStructuredLogStreamItem SubscribeAsync(StructuredLogFilter filter, CancellationToken cancellationToken default); }2.3 门面保持不变IStructuredLogProviderREST 端点与 SignalR 订阅管理器继续面向IStructuredLogProviderT021–T023它由新的组合型实现DefaultStructuredLogProvider承担T015DefaultStructuredLogProvider.cs内部组合IStructuredLogStore与IStructuredLogLiveFeedPublishAsync依次写 Store、推 LiveFeed查询与来源列表透传 Store。默认注册路径在 ServiceCollectionExtensions.csT016。内存默认实现被拆分为可复用的两块T012–T013InMemoryStructuredLogStoreInMemoryStructuredLogStore.cs负责有界环形缓冲RingBuffer内的最近历史查询、来源列表、容量与过滤行为InMemoryStructuredLogLiveFeedInMemoryStructuredLogLiveFeed.cs负责订阅者分发与丢弃摘要InMemoryStructuredLogProviderInMemoryStructuredLogProvider.cs保留为兼容门面将请求转发给上述 store 与 liveFeed。这一拆分使“默认内存行为”与“未来任何持久化 Store”都能复用同一套 REST/SignalR 接入层。2.4 共享行为约定README 明确说明核心模块 README.md 记录了所有 Store 实现共享的语义MaxRecentLogQuerySize是所有IStructuredLogStore的默认Take与上限钳制由StructuredLogsOptions.ClampRecentLogQueryTake实现负值按 0 处理查询排序固定为Timestamp, ReceivedAt, SourceId, Sequence, IdListSources优先使用进程内源注册表提供身份元数据SourceHeartbeatTimeout到期后标记为StaleQueryAsync.DroppedEvents表示内存环形缓冲溢出计数关系型写队列丢弃通过存储诊断上报不复用该字段大小写不同的相等过滤并非跨实现可移植内存为OrdinalIgnoreCaseSQL 取决于数据库排序规则。三、分阶段任务地图tasks.md 全文骨架tasks.md 将整个实现组织为 6 个阶段、3 个用户故事共 73 项任务T001–T073且全部标记为已完成[X]。任务命名格式为[ID] [P?] [Story] Description[P]满足前置条件后可与其它标记任务并行[Story]来自 spec.md 的用户故事标签每项任务都包含要创建或修改的主文件路径。3.1 Phase 1搭建SetupT001–T008目的为关系型与 SQLite 持久化建立包骨架、包引用与解决方案条目。任务产出T001–T002创建Elsa.Diagnostics.StructuredLogs.Persistence.Relational与.Persistence.Sqlite两个模块项目T003–T004创建关系型单元测试项目与 SQLite 集成测试项目T005–T006创建两个模块的 Shell 特性骨架StructuredLogRelationalPersistenceFeature、SqliteStructuredLogPersistenceFeatureT007将新项目加入Elsa.slnT008在 Directory.Packages.props 中集中管理 FluentMigrator 与 SQLite 依赖版本注意 T008 体现的是“版本集中管理”约定新增的 FluentMigrator、Dapper 等依赖版本统一收口到中央Directory.Packages.props见 spec.md 的 Assumptions。3.2 Phase 2基础存储重构FoundationalT009–T016目的拆分 Store 与 Live-Feed 关注点同时保持IStructuredLogProvider门面不变。关键约束Critical在内存默认实现仍能通过既有结构化日志测试之前不得开始任何 SQLite 故事工作tasks.md 第 35 行。这一“先保持不回归、再谈新功能”的顺序是 MVP 策略的基石。本阶段即 2.2/2.3 节所述的内容新增三个契约T009–T011将内存行为重构进 Store/LiveFeedT012–T013保留兼容门面T014新增组合门面T015更新 DI 注册T016。Checkpoint既有结构化日志行为在新抽象背后被完整保留。3.3 Phase 3US1 —— 保留既有内存行为P1MVP目标只配置UseStructuredLogs的主机获得与之前完全相同的有界内存最近查询、来源列表、实时流、脱敏与丢弃事件行为T021–T023 确保 REST 最近日志端点、来源端点与 SignalR 订阅都继续走IStructuredLogProvider。独立测试不配置持久化、启用结构化日志、发射若干ILogger记录验证最近查询、过滤器、来源列表、实时订阅、脱敏与丢弃摘要。对应测试任务T017默认注册兼容性、T018–T020内存最近查询 / 来源列表 / 实时丢弃事件。CheckpointUS1 完全可用且可独立测试。验证命令见 任务 T024dotnet test test/unit/Elsa.Diagnostics.StructuredLogs.UnitTests/Elsa.Diagnostics.StructuredLogs.UnitTests.csproj。3.4 Phase 4US2 —— SQLite 持久化存储P2目标主机可选择 SQLite 存储默认启动迁移脱敏日志跨重启持久化可查询持久化记录优雅停机冲刷排队写入可显式配置保留策略。独立测试配置 SQLite 存储、发射事件、用同一数据库文件刷新或重建服务验证持久化最近查询、过滤、迁移行为、队列溢出行为、时间戳存储与保留行为。对应测试任务T025–T032空库迁移、跨提供方重建持久化、持久化脱敏、过滤覆盖level/category/source/workflow/correlation/trace/time/limit、写队列冲刷与DroppedWriteCount溢出、启动迁移 opt-out、ISO-8601 时间戳存储、保留opt-in 清理与默认不删除。对应实现任务T033–T054关系型记录模型、关系型选项、连接工厂与方言契约、Schema 迁移器契约、SQL 构建器、JSON/时间戳映射器、FluentMigrator 迁移、关系型 Store、有界写缓冲、保留清理服务、服务注册扩展、关系型与 SQLite 的 Feature/ShellFeature 注册、SQLite 连接工厂/方言/迁移器/启动服务/流式配置扩展。3.5 Phase 5US3 —— 关系型持久化可扩展P3目标未来的关系型提供方可以复用共享的关系型 Store只需提供连接工厂、方言与 FluentMigrator Runner 配置无需改动核心结构化日志模块或 Studio 契约。独立测试审查代码边界并运行使用假方言/连接服务的关系型测试T056–T059SQL 构建器假方言、映射器JSON 与 UTC ISO-8601 时间戳、迁移元数据/版本、以及证明Elsa.Diagnostics.StructuredLogs无 SQLite 依赖的核心边界测试。对应实现任务T060–T062将提供方专属 SQL 留在核心模块之外、SQLite 专属服务留在 SQLite 包内、补充 关系型提供方 README。CheckpointSQLite 是第一个关系型提供方而不是一条一次性的持久化路径。3.6 Phase 6文档与打磨T064–T073更新结构化日志 README 的存储模式指引T064、SQLite 持久化 READMET065、Speckit quickstart 实现说明T066、仅当样例显式选择 SQLite 时才接线样例主机T067Program.cs然后依次执行四个构建/测试命令T068–T072。T073 用rg OpenTelemetry|OTLP|Datadog|Logstash|Splunk|Loki|Seq src/modules/Elsa.Diagnostics.StructuredLogs* specs/005-structured-log-persistence确认只剩范围外的文档引用。四、数据模型与表结构4.1 领域实体data-model.mddata-model.md 定义了本特性的关键实体StructuredLogStore可查询存储边界追加、按StructuredLogFilter查询、列来源不负责订阅者背压。StructuredLogLiveFeed实时投递边界发布新事件、应用订阅过滤器、报告溢出丢弃摘要不保证持久性。StructuredLogSink只追加边界接受单条或批量事件可被 Store 内部使用、也可被未来的导出器包使用。RelationalStructuredLogRecordStructuredLogEvent的关系型表示包含Id、Sequence、TimestampUTC ISO-8601 文本、ReceivedAt、Level、Category、EventId、EventName、Message、MessageTemplate、ExceptionJson、ScopesJson、PropertiesJson、TraceId、SpanId、CorrelationId、TenantId、WorkflowDefinitionId、WorkflowInstanceId、SourceId。RelationalStructuredLogSourceRecord可选的关系型来源记录机器名、进程、Kubernetes/容器元数据、StartedAt/LastSeen、状态。StructuredLogRetentionOptionsMaxAge、MaxRows、CleanupInterval、RunCleanupOnStartup默认不删除任何记录。StructuredLogWriteQueueOptionsCapacity、BatchSize、FlushInterval、ShutdownFlushTimeout、DroppedWriteCount溢出时丢弃新事件绝不阻塞日志调用或无限分配内存。RelationalStructuredLogDialect标识符引用、参数前缀、Limit/Take 语法、时间戳存储与比较、自由文本谓词构造、供 FluentMigrator 分支用的提供方名。StructuredLogMigrationRunner运行 FluentMigrator 迁移、空库建表、按版本顺序升级、SQLite 默认启动执行且可关闭、文档化共享数据库的多实例启动锁约束。4.2 关系型记录与建表迁移关系型记录模型在 RelationalStructuredLogRecord.csT033。SQLite 使用共享关系型迁移创建表T040M001_CreateStructuredLogTables.cs表名StructuredLogEvents迁移版本号[Migration(2026051301)]标量过滤字段建为可查询列IdString(64) 主键、SequenceInt64、Timestamp/ReceivedAtString(40) 非空存 UTC ISO-8601 文本、LevelInt32、CategoryString(512)、EventId、EventName复杂负载存 JSON 文本Message、MessageTemplate、ExceptionJson、ScopesJson、PropertiesJsonString(int.MaxValue)Elsa 上下文列TenantId、WorkflowDefinitionId、WorkflowInstanceId、CorrelationId、SourceId建立 10 个索引Timestamp、ReceivedAt降序、Level、Category、SourceId、TenantId、WorkflowDefinitionId、WorkflowInstanceId、CorrelationId、TraceId。这与>// StructuredLogWriteQueueOptions Capacity 10_000 // 队列容量 BatchSize 100 // 每次刷写的最大事件数 FlushInterval 1s // 后台刷写最大间隔 ShutdownFlushTimeout 10s // 优雅停机冲刷超时 // StructuredLogRetentionOptions MaxAge null // 未配置则不按时间删除 MaxRows null // 未配置则不按行数删除 CleanupOnStartup falseSQLite 选项默认值SqliteStructuredLogOptions.csConnectionString Data Sourceelsa-structured-logs.dbRunMigrationsOnStartup true。5.3 保留清理服务T043StructuredLogRetentionService.cs 实现IStructuredLogRetentionService.CleanupAsync只有MaxAge或MaxRows被配置时才执行删除FR-020默认零删除按MaxAge用ReceivedAt Cutoff删除过期记录BuildDeleteOlderThan按MaxRows用“ReceivedAt DESC, Sequence DESC, Id DESC排序后取第 N 行之后的 Id”删除超量记录BuildDeleteRowsBeyondMax由 SQLite 启动服务决定是否在启动时立即执行CleanupOnStartup。5.4 SQLite 启动服务T051SqliteStructuredLogStartupService.cs 实现IHostedService与IStartupTask用SemaphoreSlim保证幂等执行_executed标志RunMigrationsOnStartup true时调用IStructuredLogSchemaMigrator.MigrateAsyncRelational.Retention.CleanupOnStartup true时调用retentionService.CleanupAsync。注册入口在 SqliteStructuredLogsModuleExtensions.csT052AddSqliteStructuredLogPersistence注册连接工厂、方言、Schema 迁移器、启动服务HostedService IStartupTask并把SqliteStructuredLogOptions.Relational拷贝到RelationalStructuredLogOptionsCopy方法逐项同步 WriteQueue 与 Retention 五个选项最后调用AddRelationalStructuredLogPersistence()挂上共享关系型持久化注册T044。六、配置实战内存默认与 SQLite 持久化6.1 默认内存存储零配置不配置任何持久化提供方即可使用有界内存最近历史与实时 SignalR 流来自 quickstart.mdservices.AddElsa(elsa { elsa.UseStructuredLogs(options { options.RecentLogCapacity 5_000; options.MaxRecentLogQuerySize 1_000; }); });相关选项均定义在 StructuredLogsOptions.csRecentLogCapacity 5_000、SubscriberChannelCapacity 1_000、MaxRecentLogQuerySize 1_000、SourceHeartbeatTimeout 30s以及一组默认脱敏名称/正则authorization、token、password、secret、api-key、cookie、connection-string与 Bearer/Key 类正则。6.2 SQLite 持久化opt-in安装Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite包后在UseStructuredLogs中通过UseSqliteStorage显式选择 SQLite来自 quickstart.md 与 SQLite READMEservices.AddElsa(elsa { elsa.UseStructuredLogs(structuredLogs { structuredLogs.UseSqliteStorage(Data Sourceelsa-structured-logs.db, sqlite { sqlite.RunMigrationsOnStartup true; sqlite.Relational.WriteQueue.Capacity 10_000; sqlite.Relational.WriteQueue.BatchSize 100; }); }); });随后映射既有端点与 Hubapp.UseStructuredLogs();Studio 无需任何 API 改动继续使用以下既有契约/diagnostics/structured-logs/recent—— 最近日志查询/diagnostics/structured-logs/sources—— 来源列表/diagnostics/structured-logs/storage—— 存储诊断/elsa/hubs/diagnostics/structured-logs—— SignalR 实时流注意UseSqliteStorage还提供无连接字符串的重载默认Data Sourceelsa-structured-logs.db源码见 SqliteStructuredLogsModuleExtensions.cs。6.3 保留策略配置SQLite 默认不删除任何持久化记录。需要限制存储增长时显式配置quickstart.mdsqlite.Relational.Retention.MaxAge TimeSpan.FromDays(14); sqlite.Relational.Retention.MaxRows 250_000; sqlite.Relational.Retention.CleanupOnStartup true;6.4 迁移策略说明SQLite 存储默认在启动时运行 FluentMigrator 迁移RunMigrationsOnStartup true这是 SQLite 的推荐默认。生产环境如选择在部署工具中一次性准备 Schema可设false。对于未来的共享关系型数据库SQL Server / PostgreSQLspec 明确要求文档化“多实例启动锁”考虑FR-030、quickstart 的 Migrations 节生产部署可能希望只在部署阶段运行一次迁移而不是由每个应用实例各自执行。6.5 写入缓冲行为摘要SQLite 写入通过有界后台队列批量落盘优雅停机ShutdownFlushTimeout默认 10s内尽力冲刷排队事件进程崩溃排队但未刷写的事件可能丢失FR-016队列满丢弃最新事件递增DroppedWriteCount并输出警告摘要日志调用不阻塞、内存有界。七、测试策略与验收7.1 测试矩阵任务清单将测试与用户故事绑定确保每个增量可独立验证tasks.md 的 Tests 说明故事测试任务覆盖点测试文件均已存在US1T017–T020默认注册兼容、内存最近查询、来源列表、实时丢弃事件Elsa.Diagnostics.StructuredLogs.UnitTestsUS2T025–T032空库迁移、跨提供方重建持久化、持久化脱敏、过滤、队列冲刷与溢出、迁移 opt-out、ISO-8601 时间戳、保留Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.IntegrationTests 下的SqliteStructuredLogMigrationTests.cs、SqliteStructuredLogStoreTests.cs、SqliteStructuredLogFilterTests.cs、SqliteStructuredLogWriteQueueTests.cs、SqliteStructuredLogTimestampTests.cs、SqliteStructuredLogRetentionTests.cs、SqliteStructuredLogSourceTests.csUS3T056–T059SQL 构建器假方言、映射器JSON UTC ISO-8601、迁移元数据/版本、核心模块无 SQLite 依赖Elsa.Diagnostics.StructuredLogs.Persistence.Relational.UnitTests7.2 与成功标准的对应spec.md 的 Success CriteriaSC-001 至 SC-012与上述测试一一对应既有内存测试继续通过SC-001、SQLite 跨重启持久化SC-002、过滤覆盖八类字段SC-003、FluentMigrator 空库建表SC-004、保留仅按配置清理SC-005、优雅停机冲刷SC-006、队列满丢弃并上报计数SC-007、启动迁移默认/可关SC-008、UTC ISO-8601 文本一致存储与过滤SC-009、默认零删除SC-010、文档双模式说明SC-011、核心模块零 SQLite 引用SC-012。7.3 验证命令任务清单中的构建/测试命令可直接执行dotnet build src/modules/Elsa.Diagnostics.StructuredLogs/Elsa.Diagnostics.StructuredLogs.csproj dotnet build src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.csproj dotnet test test/unit/Elsa.Diagnostics.StructuredLogs.UnitTests/Elsa.Diagnostics.StructuredLogs.UnitTests.csproj dotnet test test/unit/Elsa.Diagnostics.StructuredLogs.Persistence.Relational.UnitTests/Elsa.Diagnostics.StructuredLogs.Persistence.Relational.UnitTests.csproj dotnet test test/integration/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.IntegrationTests/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.IntegrationTests.csproj7.4 手动验收步骤quickstart 提供启动开启 SQLite 结构化日志存储的 Elsa Server发射不同 level、category、workflow ID、correlation ID 的若干ILogger记录在 Studio 查询最近日志并验证各过滤器生效用同一 SQLite 数据库文件重启主机再次查询最近日志确认重启前的事件仍可读确认时间戳以 UTC ISO-8601 值存储与过滤在测试环境调低保留设置验证旧行/超量行被清理在测试环境灌满写队列验证最新事件被丢弃且丢弃计数可见。八、依赖关系、并行策略与实施顺序8.1 阶段依赖tasks.md 的 Dependencies 一节明确了依赖链Phase 1无依赖Phase 2依赖 Phase 1阻塞所有用户故事Phase 3US1依赖 Phase 2是 MVPPhase 4US2依赖 Phase 2应在 US1 验证之后进行Phase 5US3依赖 US2 产出的关系型与 SQLite 代码Phase 6依赖所选故事的实现。8.2 用户故事依赖US1P1第一个可执行切片在存储重构后保持既有行为US2P2在新存储边界之上增加持久化 SQLite 存储US3P3为未来关系型存储固化提供方边界。8.3 并行机会任务清单明确标注的可并行任务组T001–T006包骨架T009–T011契约US1 测试 T017–T020Phase 2 之后US2 测试 T025–T032项目骨架存在之后US3 测试 T056–T059关系型契约存在之后文档任务 T064–T066实现 API 稳定之后。8.4 实施策略MVP 先行、增量交付MVP First先完成 Phase 1 Phase 2 → 只完成 Phase 3 → 运行既有测试确认零回归 → 存储边界稳定后再进入 SQLite。Incremental DeliveryUS1内存兼容→ US2SQLite 持久化迁移、队列、时间戳、保留→ US3关系型扩展→ Polish文档、样例、构建、测试。九、边界与注意事项9.1 边缘场景spec.md Edge Cases设计文档明确列出了实现必须考虑的边缘情况持久化写入不得阻塞ILogger调用方SQLite 允许崩溃丢失排队未刷事件写队列满丢弃最新事件并上报丢失计数而非阻塞或无限增长主机可能在迁移完成前发射日志启动顺序错误多应用实例可能并发对共享关系型数据库执行迁移SQLite 文件路径可能缺失、相对或指向无写权限目录进程可能在事件进入后台队列后、刷写前崩溃JSON 字段上的自由文本过滤可能是提供方相关、初始为近似匹配保留清理可能与最近查询或实时订阅竞争Schema 变更必须尽量保留已持久化的事件。9.2 实现约束tasks.md Notes本特性不实现 OTLP 或厂商 Sink不为结构化日志持久化引入 EF Core保持“先脱敏再存储”Studio 的 REST 与 SignalR 契约不变优先使用小而显式的 SQL而非精巧的通用查询抽象除非实现压力证明必要。9.3 清单核对checklists/requirements.md 的 8 项要求全部勾选通过内存默认、SQLite 为唯一初始持久化提供方、存储/实时/门面职责分离、脱敏先行、FluentMigrator 而非 EF Core、未来关系型提供方不破坏 Studio 契约、含保留与优雅停机冲刷、显式推迟 OpenTelemetry 与厂商导出器。十、总结从 tasks.md 的 73 项任务可以看出Elsa 的结构化日志持久化特性走的是“先抽象、再落地、后扩展”的工程路径Phase 2 的存储/实时/采集三契约拆分让IStructuredLogProvider门面与 REST/SignalR 契约完全稳定US2 以 SQLite 作为第一个关系型提供方验证了 FluentMigrator 迁移、有界异步写队列、UTC ISO-8601 时间戳与 opt-in 保留的完整闭环US3 通过方言与连接工厂隔离保证了 SQL Server / PostgreSQL / MySQL 等后续提供方可以复用共享关系型 Store。对想要为 Elsa 主机接入持久化日志、或自行扩展更多关系型数据库的开发者本文提供的配置示例、源码路径与测试命令可以直接复用。赞分享后端工作流自动化流程编排低代码【免费下载链接】elsa-coreThe Workflow Engine for .NET项目地址https://gitcode.com/gh_mirrors/el/elsa-core点击查看免费下载相关推荐Elsa 结构化日志持久化存储契约设计与 SQLite 落地实战Elsa 结构化日志持久化存储契约设计与 SQLite 落地实战 导读 本文围绕 elsa core 仓库 specs/005 structured log后端工作流自动化流程编排低代码Elsa 结构化日志持久化快速上手从零配置内存存储到 SQLite 持久化存储Elsa 结构化日志持久化快速上手从零配置内存存储到 SQLite 持久化存储 导读 本文基于 specs/005 structured log persis后端工作流自动化流程编排低代码Elsa Workflows 结构化日志持久化设计解析从内存缓冲区到 SQLite 的存储抽象与写入可靠性Elsa Workflows 结构化日志持久化设计解析从内存缓冲区到 SQLite 的存储抽象与写入可靠性 导读 本文基于 Elsa 开源仓库中的结构化日志持后端工作流自动化流程编排低代码上一篇fastblock性能测试实战使用block_bench与vhost实现百万级IOPS的完整指南下一篇secGear安全通信通道实现原理保护数据在飞地内外传输的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考