Skip to content

Commit 9ea5534

Browse files
committed
Add proc import do power alerts v1
1 parent f2f8b6a commit 9ea5534

File tree

1 file changed

+364
-0
lines changed

1 file changed

+364
-0
lines changed
Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
/*#info
2+
3+
# Autor
4+
Rodrigo Ribeiro Gomes
5+
6+
# Detalhes
7+
Essa é uma proc que criei para o Power Alerts.
8+
Pelo menos, uma das primeiras versoes... Serve pra improtar xevents de pouco em pouco para uma tabela.
9+
Ja nao atualizo ela tem tempo e a versão atual do power alerts tem melhorias.
10+
Mas, de qualquer maneira, resolvi deixar aqui (com autorização da Power Tuning).
11+
Recomendo que use o power alerts, se quiser uma solução completa pro seu banco: https://poweralerts.com.br
12+
*/
13+
ALTER PROCEDURE
14+
stpPowerAlert_ImportXEvent(
15+
@XeSession nvarchar(1000)
16+
,@DestinationTable nvarchar(100)
17+
,@Columns XML
18+
,@Debug bit = 0
19+
,@EventNameCol nvarchar(200) = 'Nm_Event'
20+
,@EventTsCol nvarchar(200) = 'Dt_Event'
21+
,@IncludeEventData bit = 0
22+
,@AutomaticDestTable bit = 1 -- If table have 1 AutoCol, then create tables from xml.
23+
-- If table dont have auto col, then use data types from table...
24+
,@StopStart bit = 0
25+
,@topEvents int = 10000
26+
)
27+
AS
28+
SET NOCOUNT ON;
29+
IF OBJECT_ID('tempdb..#PowerAlert_Debug') IS NOT NULL
30+
SET @Debug = 1
31+
32+
DECLARE
33+
@filenamePattern nvarchar(1000)
34+
,@metaPattern nvarchar(1000)
35+
,@CurrentFile nvarchar(1000)
36+
,@CurrentOffset int
37+
,@DirName nvarchar(1000)
38+
,@StartTime datetime
39+
,@EndTime datetime
40+
,@FileImportStartTime datetime
41+
,@FileImportEndTime datetime
42+
,@TotalTime int
43+
,@InsertColList nvarchar(max)
44+
,@AutomaticTableMode varchar(100)
45+
,@spsql nvarchar(max)
46+
,@sql nvarchar(max)
47+
,@XeCol nvarchar(max)
48+
,@evtDataColTEmplate nvarchar(1000) = 'e.XeEventData.value(''#XPATH'',''#TYPE'')'
49+
,@evtDataXmlTemplate nvarchar(1000) = 'e.XeEventData.query(''#XPATH'')'
50+
,@BaseFileName nvarchar(1000)
51+
;
52+
53+
SELECT
54+
@filenamePattern = REPLACE(CONVERT(nvarchar(1000),value),'.xel','_0_*.xel')
55+
,@BaseFileName = RIGHT(@filenamePattern, CHARINDEX('\', REVERSE(@filenamePattern) ) - 1)
56+
FROM
57+
sys.server_event_sessions AS [session]
58+
JOIN sys.server_event_session_targets AS [target]
59+
ON [session].event_session_id = [target].event_session_id
60+
JOIN sys.server_event_session_fields AS field
61+
ON field.event_session_id = [target].event_session_id
62+
AND field.object_id = [target].target_id
63+
WHERE
64+
field.name = 'filename'
65+
and [session].name= @XeSession
66+
67+
IF @@ROWCOUNT = 0
68+
RETURN 1;
69+
70+
IF @Debug = 1 RAISERROR(' Base Dir: %s, BAseName: %s',0,1,@filenamePattern,@BaseFileName) WITH NOWAIT;
71+
72+
73+
SET @DirName = LEFT(@filenamePattern,LEN(@filenamePattern)-CHARINDEX('\',REVERSE(@filenamePattern)))
74+
75+
IF OBJECT_ID('tempdb..#EventData') IS NOT NULL DROP TABLE #EventData;
76+
CREATE TABLE #EventData(XeEventData XML, SrcFile nvarchar(1000))
77+
78+
79+
IF OBJECT_ID('tempdb..#FileList') IS NOT NULL DROP TABLE #FileList;
80+
CREATE TABLE #FileList(Id int not null identity primary key,FilePath nvarchar(2000), depth int, IsFile int)
81+
82+
INSERT INTO #FileList(FilePath,depth,IsFile)
83+
EXEC master.sys.xp_dirtree @DirName,1,1
84+
85+
DELETE FROM #FileList WHERE FilePath NOT LIKE '%'+@BaseFileName+'_0_%.xel'
86+
87+
declare @Id int = -1;
88+
89+
IF @StopStart = 1
90+
BEGIN
91+
SET @sql = 'ALTER EVENT SESSION '+QUOTENAME(@XeSession)+' ON SERVER STATE = STOP';
92+
93+
94+
95+
IF EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name = @XeSession)
96+
BEGIN
97+
IF @Debug = 1 RAISERROR(' Stopping event session: %s',0,1,@sql) WITH NOWAIT;
98+
EXEC(@sql);
99+
END
100+
END
101+
102+
103+
IF @Debug = 1
104+
RAISERROR(' All data imported in %d ms',0,1, @TotalTime) WITH NOWAIT;
105+
106+
-- Load list of colmns....
107+
DECLARE @XeCols TABLE(
108+
ColId int identity
109+
,ColName nvarchar(300) UNIQUE
110+
,MainExpr nvarchar(2000)
111+
,ExprType nvarchar(500)
112+
,AlternateExpr XML
113+
,DestCol nvarchar(300) UNIQUE
114+
)
115+
116+
DECLARE @DestTableColumnTypes TABLE(ColName sysname, ColType nvarchar(300));
117+
DECLARE
118+
@DestTableDb sysname
119+
,@DestTableName sysname
120+
121+
122+
IF LEFT(@DestinationTable,1) = '#'
123+
SELECT @DestTableDb = 'tempdb', @DestTableName = @DestinationTable
124+
ELSE
125+
SELECT @DestTableDb = PARSENAME(@DestinationTable,3), @DestTableName = ISNULL(quotename(PARSENAME(@DestinationTable,2)),'.')+quotename(PARSENAME(@DestinationTable,1))
126+
127+
set @spsql = @DestTableDb+'..sp_executesql';
128+
129+
IF @AutomaticDestTable = 1
130+
BEGIN
131+
set @sql = 'SELECT
132+
C.name
133+
,T.name+CASE
134+
WHEN T.name LIKE ''%char%'' THEN ''(''+ISNULL(CONVERT(varchar(10),NULLIF(C.max_length,-1)),''max'')+'')''
135+
WHEN T.name IN (''numeric'',''decimal'') THEN ''(''+CONVERT(varchar(10),C.precision)+'',''+CONVERT(varchar(10),C.scale)+'')''
136+
ELSE ''''
137+
END
138+
FROM sys.columns C
139+
INNER JOIN
140+
sys.types T
141+
ON T.system_type_id = C.system_type_id
142+
WHERE object_id = OBJECT_ID(@TableName)'
143+
144+
insert into @DestTableColumnTypes
145+
exec @spsql @sql,N'@TableName nvarchar(500)',@DestTableName
146+
END
147+
148+
insert into @XeCols(ColName,AlternateExpr,ExprType,DestCol) values('EventTs','''<x>(event/@timestamp)[1]</x>''','datetime','Dt_Event')
149+
insert into @XeCols(ColName,AlternateExpr,ExprType,DestCol) values('EventName','<x>(event/@name)[1]</x>','nvarchar(30)','Nm_Event')
150+
151+
IF @IncludeEventData = 1
152+
insert into @XeCols(ColName,AlternateExpr,ExprType,DestCol) values('EventXML','<x>.</x>','XML','EventXML')
153+
154+
155+
IF @Debug = 1 RAISERROR(' Mergin columnst list...',0,1) WITH NOWAIT;
156+
157+
MERGE
158+
@XeCols D
159+
USING (
160+
SELECT
161+
ColName = C.x.value('@name','nvarchar(300)')
162+
,MainExpr = C.x.value('@x','nvarchar(2000)')
163+
,ExprType = COALESCE(C.x.value('@type','nvarchar(500)'),CT.ColType)
164+
,AlternateExpr = C.x.query('./x')
165+
,DestCol = ISNULL(C.x.value('@dest','nvarchar(500)'),C.x.value('@name','nvarchar(300)'))
166+
FROM
167+
@Columns.nodes('col') C(x)
168+
LEFT JOIN
169+
@DestTableColumnTypes CT
170+
ON CT.ColName = ISNULL(C.x.value('@dest','nvarchar(500)'),C.x.value('@name','nvarchar(300)')) COLLATE DATABASE_DEFAULT
171+
) S
172+
ON S.ColName = D.ColName
173+
WHEN NOT MATCHED THEN
174+
INSERT(ColName,MainExpr,ExprType,AlternateExpr,DestCol)
175+
VALUES(S.ColName,S.MainExpr,S.ExprType,S.AlternateExpr,S.DestCol)
176+
WHEN MATCHED THEN
177+
UPDATE SET DestCol = S.DestCol
178+
;
179+
180+
-- null type columns...
181+
DECLARE @NullCols nvarchar(max);
182+
183+
SET @NullCols = STUFF((SELECT ','+ColName FROM @XeCols WHERE ExprType IS NULL FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,1,'')
184+
185+
IF @NullCols IS NOT NULL
186+
BEGIN
187+
RAISERROR('Columns %s dont have a defined data type. Check if mapping names ir correct or use automatic table.',16,1, @NullCols);
188+
RETURN;
189+
END
190+
191+
IF @AutomaticDestTable = 1 AND EXISTS(SELECT * FROM @DestTableColumnTypes HAVING COUNT(*) = 1 AND COUNT(CASE WHEN ColName = '_auto_' THEN ColName END) = 1)
192+
SET @AutomaticTableMode = 'RecreateTable'
193+
194+
IF @AutomaticTableMode = 'RecreateTable'
195+
BEGIN
196+
SET @sql = 'ALTER TABLE '+@DestTableName+' ADD '+STUFF((
197+
SELECT ','+quotename(DestCol)+' '+ExprType
198+
FROM @XeCols
199+
ORDER BY ColId
200+
FOR XML PATH(''),TYPE
201+
).value('.','nvarchar(1000)'),1,1,'')
202+
+' ALTER TABLE '+@DestTableName+' DROP COLUMN _auto_;'
203+
204+
SET XACT_ABORT ON;
205+
BEGIN TRAN;
206+
EXEC @spsql @sql;
207+
COMMIT;
208+
END
209+
210+
211+
IF @Debug = 1
212+
SELECT * FROM @XeCols
213+
214+
215+
216+
217+
IF @Debug = 1 RAISERROR(' Building xe event cols...',0,1) WITH NOWAIT;
218+
219+
SET @XeCol = STUFF((
220+
SELECT
221+
','+QUOTENAME(ISNULL(DestCol,ColName))+' = '+ISNULL(REPLACE(
222+
' COALESCE(
223+
NULL
224+
'+AlternateXPaths+'
225+
)'
226+
227+
,'#TYPE',ExprType),'NULL')
228+
FROM
229+
@XeCols c
230+
OUTER APPLY (
231+
SELECT
232+
AlternateXPaths = T.sx.value('.','nvarchar(max)')
233+
FROM (
234+
select
235+
','+CASE
236+
WHEN UPPER(ExprType) = 'XML' THEN REPLACE(@evtDataXmlTemplate,'#XPATH',ExprPath)
237+
ELSE REPLACE(@evtDataColTEmplate,'#XPATH',ExprPath)
238+
END
239+
from (
240+
SELECT
241+
ExprPath = NULLIF(x.p.value('data(.)','nvarchar(1000)'),'')
242+
,ExprOrder = NULLIF(x.p.value('@order','int'),'')
243+
FROM c.AlternateExpr.nodes('x') x(p)
244+
) XP
245+
WHERE
246+
XP.ExprPath IS NOT NULL
247+
ORDER BY
248+
ExprOrder
249+
FOR XML PATH(''),TYPE
250+
) T(sx)
251+
) S
252+
ORDER BY
253+
c.ColId
254+
FOR XML PATH(''),TYPE
255+
).value('.','nvarchar(max)'),1,1,'')
256+
257+
258+
IF @Debug = 1 RAISERROR(' Building insert col list...',0,1) WITH NOWAIT;
259+
260+
SET @InsertColList = STUFF((
261+
SELECT
262+
','+DestCol
263+
FROM
264+
@XeCols
265+
ORDER BY
266+
ColId
267+
FOR XML PATH(''),TYPE
268+
).value('.','nvarchar(max)'),1,1,'')
269+
270+
271+
IF @Debug = 1
272+
BEGIN
273+
RAISERROR('PowerAlertImportXeEvent: InsertColList: %s',0,1,@InsertColList) WITH NOWAIT;
274+
END
275+
276+
SET @sql = '
277+
278+
'+ISNULL('INSERT '+@DestinationTable+'('+@InsertColList+')','')+'
279+
280+
SELECT
281+
'+@XeCol+'
282+
FROM
283+
#EventData e
284+
285+
'
286+
287+
IF @Debug = 1
288+
BEGIN
289+
RAISERROR(' IMPORT SQL: %s',0,1,@sql) WITH NOWAIT;
290+
END
291+
292+
DECLARE @RunError int,@RunRows int, @ErrorMsg nvarchar(1000)
293+
294+
295+
296+
WHILE 1 = 1
297+
BEGIN
298+
SELECT TOP 1
299+
@CurrentFile = @DirName+'\'+FilePath
300+
,@Id = Id
301+
FROM
302+
#FileList
303+
WHERE
304+
Id > @Id
305+
ORDER BY
306+
Id
307+
308+
IF @@ROWCOUNT = 0 BREAK;
309+
310+
SET @metaPattern = REPLACE(@CurrentFile,'.xel','.xem');
311+
SET @metaPattern = @DirName+'\*.xem'
312+
IF @Debug = 1 RAISERROR(' Importing File %s (top %d events)',0,1, @CurrentFile, @topEvents) WITH NOWAIT;
313+
SET @FileImportStartTime = GETDATE()
314+
INSERT INTO
315+
#EventData
316+
SELECT top(@topEvents)
317+
F.event_data
318+
,F.file_name
319+
FROM
320+
sys.fn_xe_file_target_read_file ( @CurrentFile,@metaPattern, null, null) as F
321+
SET @FileImportEndTime = GETDATE()
322+
SET @TotalTime = DATEDIFF(MS,@FileImportStartTime,@FileImportEndTime);
323+
324+
IF @Debug = 1 RAISERROR(' File %s, imported in %d ms',0,1,@CurrentFile, @TotalTime) WITH NOWAIT;
325+
326+
327+
IF @Debug = 1 RAISERROR(' Running import sql...',0,1) WITH NOWAIT;
328+
BEGIN TRY
329+
SET @StartTime = GETDATE();
330+
EXEC sp_executesql @sql
331+
SET @EndTime = GETDATE();
332+
END TRY
333+
BEGIN CATCH
334+
set @RunError = ERROR_NUMBER();
335+
set @ErrorMsg = ERROR_MESSAGE();
336+
337+
IF @RunError = 2389
338+
RAISERROR('Error 2398 when running dynamic sql... Review the xpath expressions or data type choosen is correct. USe @Debug = 1 to inspect output sql... Original msg: %s',16,1,@ErrorMsg)
339+
ELSE
340+
RAISERROR(@ErrorMsg,16,1);
341+
342+
return;
343+
END CATCH
344+
345+
SET @TotalTime = DATEDIFF(MS,@StartTime,@EndTime);
346+
IF @Debug = 1 RAISERROR(' Running Done! Total time: %d ms',0,1,@TotalTime) WITH NOWAIT;
347+
348+
END
349+
350+
IF @StopStart = 1
351+
BEGIN
352+
SET @sql = 'ALTER EVENT SESSION '+QUOTENAME(@XeSession)+' ON SERVER STATE = START';
353+
354+
IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name = @XeSession)
355+
BEGIN
356+
IF @Debug = 1 RAISERROR(' Starting event session: %s',0,1,@sql) WITH NOWAIT;
357+
EXEC(@sql);
358+
END
359+
END
360+
361+
362+
RETURN 0;
363+
364+

0 commit comments

Comments
 (0)