Event File target code for extended events in Azure SQL Database and SQL Managed Instance
Applies to:
Azure SQL Database
Azure SQL Managed Instance
You want a complete code sample for a robust way to capture and report information for an extended event.
In Microsoft SQL Server, the Event File target is used to store event outputs into a local hard drive file. But local storage is not available to Azure SQL Database or SQL Managed Instance. Instead, use Azure Blob Storage to support the Event File target.
This article presents a two-phase code sample:
- PowerShell, to create an Azure Storage container in the cloud.
- Transact-SQL:
- To assign the Azure Storage container to an Event File target.
- To create and start the event session, and so on.
Prerequisites
Note
This article uses the Azure Az PowerShell module, which is the recommended PowerShell module for interacting with Azure. To get started with the Az PowerShell module, see Install Azure PowerShell. To learn how to migrate to the Az PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.
Important
The PowerShell Azure Resource Manager module is still supported by Azure SQL Database, but all future development is for the Az.Sql module. For these cmdlets, see AzureRM.Sql. The arguments for the commands in the Az module and in the AzureRm modules are substantially identical.
An Azure account and subscription. You can sign up for a free trial.
Any database you can create a table in.
- Optionally you can create an AdventureWorksLT demonstration database in minutes.
SQL Server Management Studio (ssms.exe), ideally its latest monthly update version: Download SQL Server Management Studio
You must have the Azure PowerShell modules installed.
- The modules provide commands, such as -
New-AzStorageAccount
.
- The modules provide commands, such as -
Phase 1: PowerShell code for Azure Storage container
This PowerShell is phase 1 of the two-phase code sample.
The script starts with commands to clean up after a possible previous run, and is rerunnable.
Paste the PowerShell script into a simple text editor such as Notepad.exe, and save the script as a file with the extension .ps1.
Start PowerShell ISE as an Administrator.
At the prompt, type
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
and then press Enter.In PowerShell ISE, open your .ps1 file. Run the script.
The script first starts a new window in which you sign in to Azure.
- If you rerun the script without disrupting your session, you have the convenient option of commenting out the Add-AzureAccount command.
PowerShell code
This PowerShell script assumes you've already installed the Az
module. For information, see Install the Azure PowerShell module.
## TODO: Before running, find all 'TODO' and make each edit!!
cls;
#--------------- 1 -----------------------
'Script assumes you have already logged your PowerShell session into Azure.
But if not, run Connect-AzAccount (or Connect-AzAccount), just one time.';
#Connect-AzAccount; # Same as Connect-AzAccount.
#-------------- 2 ------------------------
'
TODO: Edit the values assigned to these variables, especially the first few!
';
# Ensure the current date is between
# the Expiry and Start time values that you edit here.
$subscriptionName = 'YOUR_SUBSCRIPTION_NAME';
$resourceGroupName = 'YOUR_RESOURCE-GROUP-NAME';
$policySasExpiryTime = '2018-08-28T23:44:56Z';
$policySasStartTime = '2017-10-01';
$storageAccountLocation = 'YOUR_STORAGE_ACCOUNT_LOCATION';
$storageAccountName = 'YOUR_STORAGE_ACCOUNT_NAME';
$containerName = 'YOUR_CONTAINER_NAME';
$policySasToken = ' ? ';
$policySasPermission = 'rwl'; # Leave this value alone, as 'rwl'.
#--------------- 3 -----------------------
# The ending display lists your Azure subscriptions.
# One should match the $subscriptionName value you assigned
# earlier in this PowerShell script.
'Choose an existing subscription for the current PowerShell environment.';
Select-AzSubscription -Subscription $subscriptionName;
#-------------- 4 ------------------------
'
Clean up the old Azure Storage Account after any previous run,
before continuing this new run.';
if ($storageAccountName) {
Remove-AzStorageAccount `
-Name $storageAccountName `
-ResourceGroupName $resourceGroupName;
}
#--------------- 5 -----------------------
[System.DateTime]::Now.ToString();
'
Create a storage account.
This might take several minutes, will beep when ready.
...PLEASE WAIT...';
New-AzStorageAccount `
-Name $storageAccountName `
-Location $storageAccountLocation `
-ResourceGroupName $resourceGroupName `
-SkuName 'Standard_LRS';
[System.DateTime]::Now.ToString();
[System.Media.SystemSounds]::Beep.Play();
'
Get the access key for your storage account.
';
$accessKey_ForStorageAccount = `
(Get-AzStorageAccountKey `
-Name $storageAccountName `
-ResourceGroupName $resourceGroupName
).Value[0];
"`$accessKey_ForStorageAccount = $accessKey_ForStorageAccount";
'Azure Storage Account cmdlet completed.
Remainder of PowerShell .ps1 script continues.
';
#--------------- 6 -----------------------
# The context will be needed to create a container within the storage account.
'Create a context object from the storage account and its primary access key.
';
$context = New-AzStorageContext `
-StorageAccountName $storageAccountName `
-StorageAccountKey $accessKey_ForStorageAccount;
'Create a container within the storage account.
';
$containerObjectInStorageAccount = New-AzStorageContainer `
-Name $containerName `
-Context $context;
'Create a security policy to be applied to the SAS token.
';
New-AzStorageContainerStoredAccessPolicy `
-Container $containerName `
-Context $context `
-Policy $policySasToken `
-Permission $policySasPermission `
-ExpiryTime $policySasExpiryTime `
-StartTime $policySasStartTime;
'
Generate a SAS token for the container.
';
try {
$sasTokenWithPolicy = New-AzStorageContainerSASToken `
-Name $containerName `
-Context $context `
-Policy $policySasToken;
}
catch {
$Error[0].Exception.ToString();
}
#-------------- 7 ------------------------
'Display the values that YOU must edit into the Transact-SQL script next!:
';
"storageAccountName: $storageAccountName";
"containerName: $containerName";
"sasTokenWithPolicy: $sasTokenWithPolicy";
'
REMINDER: sasTokenWithPolicy here might start with "?" character, which you must exclude from Transact-SQL.
';
'
(Later, return here to delete your Azure Storage account. See the preceding Remove-AzStorageAccount -Name $storageAccountName)';
'
Now shift to the Transact-SQL portion of the two-part code sample!';
# EOFile
Take note of the few named values that the PowerShell script prints when it ends. You must edit those values into the Transact-SQL script that follows as phase 2.
Note
In the preceding PowerShell code example, SQL extended events are not compatible with the ADLS Gen2 storage accounts.
Phase 2: Transact-SQL code that uses Azure Storage container
- In phase 1 of this code sample, you ran a PowerShell script to create an Azure Storage container.
- Next in phase 2, the following Transact-SQL script must use the container.
The script starts with commands to clean up after a possible previous run, and is rerunnable.
The PowerShell script printed a few named values when it ended. You must edit the Transact-SQL script to use those values. Find TODO in the Transact-SQL script to locate the edit points.
- Open SQL Server Management Studio (ssms.exe).
- Connect to your database in Azure SQL Database or SQL Managed Instance.
- Select to open a new query pane.
- Paste the following Transact-SQL script into the query pane.
- Find every TODO in the script and make the appropriate edits.
- Save, and then run the script.
Warning
The SAS key value generated by the preceding PowerShell script might begin with a '?' (question mark). When you use the SAS key in the following T-SQL script, you must remove the leading '?'. Otherwise your efforts might be blocked by security.
Transact-SQL code
---- TODO: First, run the earlier PowerShell portion of this two-part code sample.
---- TODO: Second, find every 'TODO' in this Transact-SQL file, and edit each.
---- Transact-SQL code for Event File target on Azure SQL Database or SQL Managed Instance.
SET NOCOUNT ON;
GO
---- Step 1. Establish one little table, and ---------
---- insert one row of data.
IF EXISTS
(SELECT * FROM sys.objects
WHERE type = 'U' and name = 'gmTabEmployee')
BEGIN
DROP TABLE gmTabEmployee;
END
GO
CREATE TABLE gmTabEmployee
(
EmployeeGuid uniqueIdentifier not null default newid() primary key,
EmployeeId int not null identity(1,1),
EmployeeKudosCount int not null default 0,
EmployeeDescr nvarchar(256) null
);
GO
INSERT INTO gmTabEmployee ( EmployeeDescr )
VALUES ( 'Jane Doe' );
GO
------ Step 2. Create key, and ------------
------ Create credential (your Azure Storage container must already exist).
IF NOT EXISTS
(SELECT * FROM sys.symmetric_keys
WHERE symmetric_key_id = 101)
BEGIN
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '0C34C960-6621-4682-A123-C7EA08E3FC46' -- Or any newid().
END
GO
IF EXISTS
(SELECT * FROM sys.database_scoped_credentials
-- TODO: Assign AzureStorageAccount name, and the associated Container name.
WHERE name = 'https://gmstorageaccountxevent.blob.core.windows.net/gmcontainerxevent')
BEGIN
DROP DATABASE SCOPED CREDENTIAL
-- TODO: Assign AzureStorageAccount name, and the associated Container name.
[https://gmstorageaccountxevent.blob.core.windows.net/gmcontainerxevent] ;
END
GO
CREATE
DATABASE SCOPED
CREDENTIAL
-- use '.blob.', and not '.queue.' or '.table.' etc.
-- TODO: Assign AzureStorageAccount name, and the associated Container name.
[https://gmstorageaccountxevent.blob.core.windows.net/gmcontainerxevent]
WITH
IDENTITY = 'SHARED ACCESS SIGNATURE', -- "SAS" token.
-- TODO: Paste in the long SasToken string here for Secret, but exclude any leading '?'.
SECRET = 'sv=2014-02-14&sr=c&si=gmpolicysastoken&sig=EjAqjo6Nu5xMLEZEkMkLbeF7TD9v1J8DNB2t8gOKTts%3D'
;
GO
------ Step 3. Create (define) an event session. --------
------ The event session has an event with an action,
------ and a has a target.
IF EXISTS
(SELECT * from sys.database_event_sessions
WHERE name = 'gmeventsessionname240b')
BEGIN
DROP
EVENT SESSION
gmeventsessionname240b
ON DATABASE;
END
GO
CREATE
EVENT SESSION
gmeventsessionname240b
ON DATABASE
ADD EVENT
sqlserver.sql_statement_starting
(
ACTION (sqlserver.sql_text)
WHERE statement LIKE 'UPDATE gmTabEmployee%'
)
ADD TARGET
package0.event_file
(
-- TODO: Assign AzureStorageAccount name, and the associated Container name.
-- Also, tweak the .xel file name at end, if you like.
SET filename =
'https://gmstorageaccountxevent.blob.core.windows.net/gmcontainerxevent/anyfilenamexel242b.xel'
)
WITH
(MAX_MEMORY = 10 MB,
MAX_DISPATCH_LATENCY = 3 SECONDS)
;
GO
------ Step 4. Start the event session. ----------------
------ Issue the SQL Update statements that will be traced.
------ Then stop the session.
------ Note: If the target fails to attach,
------ the session must be stopped and restarted.
ALTER
EVENT SESSION
gmeventsessionname240b
ON DATABASE
STATE = START;
GO
SELECT 'BEFORE_Updates', EmployeeKudosCount, * FROM gmTabEmployee;
UPDATE gmTabEmployee
SET EmployeeKudosCount = EmployeeKudosCount + 2
WHERE EmployeeDescr = 'Jane Doe';
UPDATE gmTabEmployee
SET EmployeeKudosCount = EmployeeKudosCount + 13
WHERE EmployeeDescr = 'Jane Doe';
SELECT 'AFTER__Updates', EmployeeKudosCount, * FROM gmTabEmployee;
GO
ALTER
EVENT SESSION
gmeventsessionname240b
ON DATABASE
STATE = STOP;
GO
-------------- Step 5. Select the results. ----------
SELECT
*, 'CLICK_NEXT_CELL_TO_BROWSE_ITS_RESULTS!' as [CLICK_NEXT_CELL_TO_BROWSE_ITS_RESULTS],
CAST(event_data AS XML) AS [event_data_XML] -- TODO: In ssms.exe results grid, double-click this cell!
FROM
sys.fn_xe_file_target_read_file
(
-- TODO: Fill in Storage Account name, and the associated Container name.
-- TODO: The name of the .xel file needs to be an exact match to the files in the storage account Container (You can use Storage Account explorer from the portal to find out the exact file names or you can retrieve the name using the following DMV-query: select target_data from sys.dm_xe_database_session_targets. The 3rd xml-node, "File name", contains the name of the file currently written to.)
'https://gmstorageaccountxevent.blob.core.windows.net/gmcontainerxevent/anyfilenamexel242b',
null, null, null
);
GO
-------------- Step 6. Clean up. ----------
DROP
EVENT SESSION
gmeventsessionname240b
ON DATABASE;
GO
DROP DATABASE SCOPED CREDENTIAL
-- TODO: Assign AzureStorageAccount name, and the associated Container name.
[https://gmstorageaccountxevent.blob.core.windows.net/gmcontainerxevent]
;
GO
DROP TABLE gmTabEmployee;
GO
PRINT 'Use PowerShell Remove-AzStorageAccount to delete your Azure Storage account!';
GO
If the target fails to attach when you run, you must stop and restart the event session:
ALTER EVENT SESSION gmeventsessionname240b
ON DATABASE STATE = STOP;
GO
ALTER EVENT SESSION gmeventsessionname240b
ON DATABASE STATE = START;
GO
Output
When the Transact-SQL script completes, select a cell under the event_data_XML column header. One <event> element is displayed which shows one UPDATE statement.
Here is one <event> element that was generated during testing:
<event name="sql_statement_starting" package="sqlserver" timestamp="2015-09-22T19:18:45.420Z">
<data name="state">
<value>0</value>
<text>Normal</text>
</data>
<data name="line_number">
<value>5</value>
</data>
<data name="offset">
<value>148</value>
</data>
<data name="offset_end">
<value>368</value>
</data>
<data name="statement">
<value>UPDATE gmTabEmployee
SET EmployeeKudosCount = EmployeeKudosCount + 2
WHERE EmployeeDescr = 'Jane Doe'</value>
</data>
<action name="sql_text" package="sqlserver">
<value>
SELECT 'BEFORE_Updates', EmployeeKudosCount, * FROM gmTabEmployee;
UPDATE gmTabEmployee
SET EmployeeKudosCount = EmployeeKudosCount + 2
WHERE EmployeeDescr = 'Jane Doe';
UPDATE gmTabEmployee
SET EmployeeKudosCount = EmployeeKudosCount + 13
WHERE EmployeeDescr = 'Jane Doe';
SELECT 'AFTER__Updates', EmployeeKudosCount, * FROM gmTabEmployee;
</value>
</action>
</event>
The preceding Transact-SQL script used the following system function to read the event_file:
An explanation of advanced options for the viewing of data from extended events is available at:
Converting the code sample to run on SQL Server
Suppose you wanted to run the preceding Transact-SQL sample on Microsoft SQL Server.
For simplicity, you would want to completely replace use of the Azure Storage container with a simple file such as
C:\myeventdata.xel
. The file would be written to the local hard drive of the computer that hosts SQL Server.You would not need any kind of Transact-SQL statements for CREATE MASTER KEY and CREATE CREDENTIAL.
In the CREATE EVENT SESSION statement, in its ADD TARGET clause, you would replace the Http value assigned made to filename= with a full path string like
C:\myfile.xel
.- An Azure Storage account is not needed.
Next steps
For more info about accounts and containers in the Azure Storage service, see:
Feedback
Submit and view feedback for