Created
May 13, 2025 13:26
-
-
Save JosiahSiegel/627f2fdb4f535ef1eb80db1384b75626 to your computer and use it in GitHub Desktop.
SQL Server Event Session - LoginTracking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Create an Extended Events session to track login activities | |
CREATE EVENT SESSION [LoginTracking] ON SERVER | |
ADD EVENT sqlserver.login( | |
ACTION( | |
sqlserver.client_app_name, -- Application name | |
sqlserver.client_hostname, -- Client hostname | |
sqlserver.client_pid, -- Client process ID | |
sqlserver.database_name, -- Database name | |
sqlserver.nt_username, -- Windows username | |
sqlserver.server_principal_name, -- SQL Server login name | |
sqlserver.session_id, -- Session ID | |
sqlserver.session_nt_username, -- Windows username for the session | |
sqlserver.username -- Username | |
) | |
WHERE ([package0].[greater_than_uint64]([sqlserver].[session_id],(50))) -- Filter out system sessions | |
), | |
ADD EVENT sqlserver.logout( | |
ACTION( | |
sqlserver.client_app_name, | |
sqlserver.client_hostname, | |
sqlserver.client_pid, | |
sqlserver.database_name, | |
sqlserver.nt_username, | |
sqlserver.server_principal_name, | |
sqlserver.session_id, | |
sqlserver.session_nt_username, | |
sqlserver.username | |
) | |
WHERE ([package0].[greater_than_uint64]([sqlserver].[session_id],(50))) | |
), | |
ADD EVENT sqlserver.error_reported( | |
ACTION( | |
sqlserver.client_app_name, | |
sqlserver.client_hostname, | |
sqlserver.client_pid, | |
sqlserver.database_name, | |
sqlserver.nt_username, | |
sqlserver.server_principal_name, | |
sqlserver.session_id, | |
sqlserver.username | |
) | |
WHERE ( | |
[error_number]=(18456) -- Login failed error | |
AND [package0].[greater_than_uint64]([sqlserver].[session_id],(50)) | |
) | |
) | |
-- Add file target using relative path (will be stored in SQL Server's default log directory) | |
ADD TARGET package0.event_file(SET | |
filename=N'LoginTracking.xel', -- Relative path will place it in SQL Server's log directory | |
max_file_size=(100), | |
max_rollover_files=(5) | |
) | |
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=OFF, | |
STARTUP_STATE=ON | |
); | |
GO | |
-- Start the Extended Events session | |
ALTER EVENT SESSION [LoginTracking] ON SERVER STATE = START; | |
GO | |
-- Script to query login data using the relative path for .xel files | |
SELECT | |
DATEADD(hour, DATEDIFF(hour, GETUTCDATE(), CURRENT_TIMESTAMP), event_data.value('(event/@timestamp)[1]', 'datetime2')) AS local_time, | |
event_data.value('(event/action[@name="server_principal_name"]/value)[1]', 'nvarchar(max)') AS login_name, | |
event_data.value('(event/action[@name="client_app_name"]/value)[1]', 'nvarchar(max)') AS application_name, | |
event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'nvarchar(max)') AS hostname, | |
event_data.value('(event/action[@name="database_name"]/value)[1]', 'nvarchar(max)') AS database_name, | |
object_name AS event_type | |
FROM | |
( | |
SELECT | |
CAST(event_data AS XML) AS event_data, | |
object_name | |
FROM | |
sys.fn_xe_file_target_read_file('LoginTracking*.xel', NULL, NULL, NULL) | |
) AS XEvents | |
ORDER BY local_time DESC; | |
GO | |
-- Daily login summary report using the relative path | |
-- Daily login summary report - Fixed to avoid XML methods in GROUP BY | |
WITH LoginData AS ( | |
SELECT | |
DATEADD(hour, DATEDIFF(hour, GETUTCDATE(), CURRENT_TIMESTAMP), event_data.value('(event/@timestamp)[1]', 'datetime2')) AS event_time, | |
event_data.value('(event/action[@name="server_principal_name"]/value)[1]', 'nvarchar(max)') AS login_name, | |
event_data.value('(event/action[@name="client_app_name"]/value)[1]', 'nvarchar(max)') AS application_name, | |
event_data.value('(event/action[@name="database_name"]/value)[1]', 'nvarchar(max)') AS database_name, | |
event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'nvarchar(max)') AS hostname, | |
object_name | |
FROM | |
( | |
SELECT | |
CAST(event_data AS XML) AS event_data, | |
object_name | |
FROM | |
sys.fn_xe_file_target_read_file('LoginTracking*.xel', NULL, NULL, NULL) | |
) AS XEvents | |
WHERE object_name = 'login' | |
) | |
SELECT TOP 100 PERCENT | |
CONVERT(date, event_time) AS login_date, | |
login_name, | |
application_name, | |
database_name, | |
hostname, | |
COUNT(*) AS login_count | |
FROM LoginData | |
GROUP BY | |
CONVERT(date, event_time), | |
login_name, | |
application_name, | |
database_name, | |
hostname | |
ORDER BY | |
login_date DESC, | |
login_count DESC; | |
GO | |
/* | |
-- Monitor the Extended Events session with: | |
SELECT * FROM sys.dm_xe_sessions WHERE name = 'LoginTracking'; | |
GO | |
-- Stop the Extended Events session (run when you no longer need to track logins) | |
ALTER EVENT SESSION [LoginTracking] ON SERVER STATE = STOP; | |
GO | |
-- Drop the session if needed | |
DROP EVENT SESSION [LoginTracking] ON SERVER; | |
GO | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment