事件日志
要求
Azure Queue(云)
Bitwarden 云实例使用 Azure 队列和表存储来处理事件。以下是它的工作原理:
由用户执行需要被记录的动作
如果事件发生在客户端(例如查看了密码),客户端会将事件的详细信息发送到事件服务器项目,然后事件服务器项目调用
EventService
。如果事件发生在服务器端,则相关项目调用EventService
本身。事件暂时存储在 Azure Queue Storage(专为处理大量消息而设计)中
EventsProcessor 服务器项目运行常规批处理作业以从队列存储中检索事件并将它们保存到表存储中
从表存储中检索事件以供查看
要在本地模拟:
确保您已安装并设置 Azurite,如服务器设置指南中所述
确保未设置
globalSettings:events:connectionString
用户机密,或具有默认值UseDevelopmentStorage=true
使用
dotnet run
或您的 IDE 启动 Events 和 EventsProcessor 项目。(还要确保您的 Api、Identity 和你的 Web Vault 处于运行状态。)
您现在应该可以观察到您的企业组织正在记录事件(例如,当创建项目或邀请用户时)。这些将出现在组织密码库的事件日志部分。
Azure Storage Exporer 允许您检查本地队列和表存储的内容,对调试非常有用。
数据库存储(自托管)
Bitwarden 的自托管实例使用替代的 EventService
实现将事件日志直接写入其数据库的 Event
表中。
要为事件使用数据库存储:
在自托管配置中运行您的本地开发服务器(Api、Identity 和 Web 密码库)
使用
dotnet run
或您的 IDE 启动 Events 项目(注意:自托管不需要 EventsProcessor)
分布式事件(可选)
事件可以通过 AMQP 消息系统进行分发。该消息系统允许新的集成订阅事件。系统支持 RabbitMQ 或 Azure Service Bus。
监听器/处理器模式
将事件迁移到分布式的主要目的是构建额外的服务集成,以消费事件。为了方便支持多个 AMQP 服务(RabbitMQ 和 Azure Service Bus),监听事件流的行为与响应事件的行为是分离的。
监听器
每个通信平台(例如,一个用于 RabbitMQ,一个用于 Azure Service Bus)都有一个监听器。
可以配置多个实例独立运行,每个实例都有自己的处理程序和订阅/队列。
执行消息平台的设置/拆卸、订阅等所有方面,但不会直接处理任何事件。相反,它们将任务委托给已配置的处理程序。
处理程序
每个集成(例如 HTTP POST 或事件数据库存储库)一个处理程序。
完全独立于并不知道所使用的消息平台。这使它们可以在不同的通信平台中自由重用。
执行处理事件的所有方面。
由于它们与更复杂的消息传递相隔离和分离,因此具有很强的可测试性。
此组合允许在 Startup.cs
中进行配置,将当前运行的消息平台监听服务的实例与任何数量的处理器配对。它还允许快速开发新的处理器,因为它们只专注于处理特定事件的任务。
RabbitMQ 实现
RabbitMQ 实现增加了一个步骤,重构了在本地或自托管运行时处理事件的方式。每个事件都会广播到 RabbitMQ 交换,而不是直接通过 EventsRepository
写入 Events
表。使用 EventRepositoryHandler
配置的新 RabbitMqEventListenerService
实例会订阅 RabbitMQ 交换,并通过 EventsRepository
写入 Events
表。最终结果是相同的(事件存储在数据库中),但 RabbitMQ 交换的添加允许其他集成进行订阅。
为了说明广播事件的性能,一个配置了 WebhookEventHandler
的 RabbitMqEventListenerService
实例订阅了 RabbitMQ 事件交换机并将每个事件通过 POST
发送到可配置的 URL。这是一个简单具体的示例,说明了通过分布式事件如何启用多个集成。
运行 RabbitMQ 容器
1、验证您是否在 .env
文件中设置了用户名和密码(请参阅 .env.example
以获取示例)
2、使用 Docker Compose 以当前设置运行容器:
docker compose --profile rabbitmq up -d
Compose 配置使用来自
env
文件的用户名和密码。它配置为在 localhost 上以 RabbitMQ 的标准端口运行,但可以在 Docker 配置中进行自定义。
3、要验证其正在运行,请在浏览器中打开 http://localhost:15672
,并使用您的 .env
文件中的用户名和密码登录。
配置服务器以使用 RabbitMQ 处理事件
1、将以下内容添加到您的 secrets.json
文件中,将默认值更改为与您的 .env
文件匹配:
"eventLogging": {
"rabbitMq": {
"hostName": "localhost",
"username": "bitwarden",
"password": "SET_A_PASSWORD_HERE_123",
"exchangeName": "events-exchange",
"eventRepositoryQueueName": "events-write-queue",
"webhookQueueName": "events-webhook-queue",
}
"webhookUrl": "<HTTP POST URL>",
}
2、(可选)上面指定的 webhookQueueName
和 webhookUrl
是可选的。如果它们被定义,则将添加一个 WebhookEventHandler
到一个 RabbitMqEventListenerService
实例中,该实例将 POST
事件到已配置的 URL。
RequestBin 提供了一个易于设置的接收这些请求并允许您检查它们的简单服务器。
3、重新运行 PowerShell 脚本,将这些秘密添加到每个 Bitwarden 项目中:
pwsh setup_secrets.ps1
4、启动(或重新启动)所有项目以应用新设置
随着这些更改的实施,您应该会看到数据库事件按之前的方式写入,同时您也会在 RabbitMQ 管理界面中看到消息正在通过配置的交换/队列流动。
Azure Service Bus 实现
Azure Service Bus 实现是 Azure Queue 的可配置替代。不是将事件写入队列等待提取,而是将事件发送到配置的 Service Bus 主题。然后使用 AzureTableStorageEventHandler
配置一个实例为 AzureServiceBusEventListenerService
,以订阅该主题并将事件写入 Azure 表存储。类似于上面的 RabbitMQ,最终结果相同(事件存储在 Azure 表存储中),但添加 Service Bus 主题允许其他集成进行订阅。
与上面的 RabbitMQ 实现一样,可以配置一个 WebhookEventHandler
来运行并通过单独的订阅将事件 POST 到 URL。
运行 Azure Service Bus 模拟器
确保您已在本地设置了 Azurite(如之前的用于将事件写入 Azure 表存储的一般说明)。此外,这还假设您正在使用
mssql
默认配置文件并通过.env
设置了${MSSQL_PASSWORD}
使用 Docker Compose 添加/启动本地模拟器:
docker compose --profile servicebus up -d
Service Bus 模拟器启动前会等待 15 秒。您可以在 Docker 桌面中查看控制台或运行 docker logs service-bus
来验证服务是否启动,然后再启动服务器。
配置服务器以使用 Azure Service Bus 处理事件
在
dev
中的secrets.json
中添加以下内容以配置 Service Bus:
"eventLogging": {
"azureServiceBus": {
"connectionString": "\"Endpoint=sb://localhost;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;\"",
"topicName": "event-logging",
"eventRepositorySubscriptionName": "events-write-subscription",
}
},
重新运行机密脚本以发布新的机密
pwsh setup_secrets.ps1 -clear
启动或重新启动所有服务,包括
EventsProcessor
。
配置 webhook(可选)
编辑
servicebusemulator_config.json
文件以添加对主event-logging
主题的订阅 topic:
{
"Name": "events-webhook-subscription"
}
重新启动 server-bus 容器以应用这些更改
将 webhook 订阅名称和 URL 配置添加到
secrets.json
"eventLogging": {
"azureServiceBus": {
"connectionString": "\"Endpoint=sb://localhost;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;\"",
"topicName": "event-logging",
"eventRepositorySubscriptionName": "events-write-subscription",
"webhookSubscriptionName": "events-webhook-subscription"
},
"webhookUrl": "<Optional URL here>"
},
发布新密钥到 App:
pwsh setup_secrets.ps1 -clear
重启所有服务,包括
EventsProcessor
最后更新于