【发布时间】:2018-06-05 18:44:34
【问题描述】:
我希望 SQL Server 创建一个记录所有(成功)登录/连接到数据库的日志文件。日志应至少包含:
- 连接客户端的IP地址和端口
- 客户端的应用程序名称
- 用户名
- 数据库名称
- 连接时间或适用交易时间
看起来像a server trace likely can capture all this information,但微软表示不推荐使用服务器跟踪以支持扩展事件。
所以我试图通过扩展事件收集这些信息。对于我的测试,我使用的是 SQL Server 2017 Developer Edition(在 Windows 10 上的 Docker 容器中运行)和 SSMS v17.7。我在创建或查看扩展事件时以“sa”身份登录。
到目前为止,我已经能够通过扩展事件收集大部分此类信息。问题是收集客户端 IP 和端口。我可以单独获得任何一部分,但不能同时获得两者。下面列出了我正在使用的 XEvent。 connection_accept 被列出两次这一事实并非错误。 SQL Server 实际上有两个名称完全相同的不同事件(!!!)。
-
Login:没有收集客户端 IP 或端口的选项(字段或操作)。至少它确实提供client_hostname! -
Logout:没有收集客户端 IP 或端口的选项(字段或操作)。这也捕获了client_hostname。 -
connection_accept:- 收集客户端 IP,但它会屏蔽最低八位字节(例如 192.168.1.XX)!!!
- 收集客户端端口!好!
- 不收集 session_id,因此无法与
Login或Logout事件关联。 - 我的
EVENT SESSION指定了username、client_app_name和client_hostname的集合,但这些字段/操作都不存在于收集的数据中。 :(
-
connection_accept:- 收集客户端端口,但不收集客户端IP!!!
- 有sesstion_id,所以至少可以关联
Login和Logout - 注意:我还没有在野外捕捉到这个特定的事件,所以我没有更多关于它的信息。
这些事件都没有提供客户端的 IP 地址,但我会接受客户端主机名作为合理的替代。但是,获得端口号是一个真正的问题。端口号仅在 connection_accept 事件中找到,并且没有明显的方法可以将其与具有主机名的 login 事件相关联。简而言之,扩展事件似乎根本无法提供这种基本的客户端 IP 和端口配对。我想相信我错了,因为它是如此基本的数据。非常感谢我忽略的任何帮助或建议。
扩展事件 DDL
这是我一直在测试的EVENT SESSION 的 DDL:
CREATE EVENT SESSION [Connections] ON SERVER
ADD EVENT SQLSatellite.connection_accept(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.context_info,sqlserver.database_name,sqlserver.nt_username,sqlserver.request_id,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[not_equal_i_sql_unicode_string]([sqlserver].[client_app_name],N'SQLServerCEIP'))),
ADD EVENT sqlserver.connection_accept(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.context_info,sqlserver.database_name,sqlserver.nt_username,sqlserver.request_id,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[not_equal_i_sql_unicode_string]([sqlserver].[client_app_name],N'SQLServerCEIP'))),
ADD EVENT sqlserver.connectivity_ring_buffer_recorded(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[client_app_name]<>N'SQLServerCEIP')),
ADD EVENT sqlserver.login(SET collect_options_text=(1)
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[client_app_name]<>N'SQLServerCEIP')),
ADD EVENT sqlserver.logout(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[client_app_name]<>N'SQLServerCEIP'))
ADD TARGET package0.event_file(SET filename=N'c:\xevents\connections')
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO
替代方案
除了扩展事件,"security audits" is another mechanism 没有被弃用。所以我想我也试试这个:
USE [master]
GO
CREATE SERVER AUDIT [AuditTest]
TO FILE
( FILEPATH = N'C:\xevents\'
,MAXSIZE = 2 MB
,MAX_FILES = 5
,RESERVE_DISK_SPACE = OFF
)
WITH
( QUEUE_DELAY = 1000
,ON_FAILURE = CONTINUE
)
CREATE SERVER AUDIT SPECIFICATION [Connections]
FOR SERVER AUDIT [AuditTest]
ADD (SUCCESSFUL_LOGIN_GROUP),
ADD (LOGOUT_GROUP)
GO
提供的字段包括“客户端应用程序”、“客户端 IP”、“会话 ID”和用户名(即“服务器主体名称”)。但是,无法将其与connection_accept XEvent 关联起来。所以没有办法提取我想要的两条信息:客户端IP和端口号。 :(
奖金
除了收集客户端 IP 和端口,我还对collecting SQL Server network traffic volume 感兴趣。但是,我还没有看到任何方法可以做到这一点。提示赞赏!我只看到vaguely related posts。
更新
我注意到一个名为task_address 的全局操作(字段)似乎与login、logout 和connection_accept 事件相关。因此,现在可以通过组合login:client_hostname 和connection_accept:port 来找到IP 和端口。我唯一担心的是我找不到task_address 的文档来验证我的观察。
【问题讨论】:
-
这可能值得在 dba.stackexchange.com 中提出,它更适合该群体。
-
@MJH 我在 dba.stackexchange 上看到六个左右的 dba 介入评论这个问题(其他人已经问过),并且反复出现的反馈是“我没有工作带有扩展事件。”所以我想我会提出这个问题。此外,开发和运营之间的差距不断缩小!
标签: sql-server monitoring network-monitoring extended-events