Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

Боз давом додани мавзуи тартиб додан Zero Touch PROD дар зери RDS. DBA-ҳои оянда наметавонанд мустақиман ба серверҳои PROD пайваст шаванд, аммо метавонанд истифода баранд Ҷенкинс ҷойҳои корӣ барои маҷмӯи маҳдуди амалиёт. DBA корро оғоз мекунад ва пас аз чанд вақт мактубе мегирад, ки дар бораи анҷоми ин амалиёт гузориш медиҳад. Биёед роҳҳои пешниҳоди ин натиҷаҳоро ба корбар дида бароем.

Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

Матни оддӣ

Биёед бо чизи ночизтарин оғоз кунем. Усули аввал он қадар содда аст, ки воқеан чизе барои сӯҳбат кардан нест (муаллиф минбаъд аз ҷойҳои FreeStyle истифода мебарад):

Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

sqlcmd коре мекунад ва мо онро ба корбар пешкаш мекунем. Идеалӣ барои, масалан, корҳои эҳтиётӣ:

Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

Дар омади гап, фаромӯш накунед, ки дар зери нусхабардорӣ/барқарорсозии RDS асинхронӣ аст, бинобар ин шумо бояд онро интизор шавед:

declare @rds table
  (id int, task_type varchar(128), database_name sysname, pct int, duration int, 
   lifecycle varchar(128), taskinfo varchar(max) null, 
   upd datetime, cre datetime,
   s3 varchar(256), ovr int, KMS varchar(256) null)
waitfor delay '00:00:20' 
insert into @rds exec msdb.dbo.rds_task_status @db_name='{db}'
select @xid=max(id) from @rds

again:
waitfor delay '00:00:02'
delete from @rds
insert into @rds exec msdb.dbo.rds_task_status @db_name='{db}' 
# {db} substituted with db name by powershell
select @stat=lifecycle,@info=taskinfo from @rds where id=@xid
if @stat not in ('ERROR','SUCCESS','CANCELLED') goto again

Усули дуюм, CSV

Дар ин ҷо ҳама чиз хеле содда аст:

Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

Аммо, ин усул танҳо дар сурате кор мекунад, ки маълумоти дар CSV баргардонидашуда "оддӣ" бошад. Агар шумо кӯшиш кунед, ки масалан, рӯйхати дархостҳои пуршиддати TOP N CPU-ро бо ин роҳ баргардонед, CSV аз сабаби он, ки матни дархост метавонад ҳама гуна аломатҳоро дар бар гирад - вергул, нохунак ва ҳатто танаффусҳои сатр. Бинобар ин, ба мо чизи мураккабтар лозим аст.

Аломатҳои зебо дар HTML

Ман дарҳол ба шумо як пораи код медиҳам

$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@
  
$Result = invoke-Sqlcmd -ConnectionString $jstr -Query "select * from DbInv" `
  | Select-Object -Property * -ExcludeProperty "ItemArray", "RowError", "RowState", "Table", "HasErrors"
if ($Result -eq $null) { $cnt = 0; }
elseif ($Result.getType().FullName -eq "System.Management.Automation.PSCustomObject") { $cnt = 1; }
else { $cnt = $Result.Rows.Count; } 
if ($cnt -gt 0) {
  $body = "<h2>My table</h2>"
  $Result | ConvertTo-HTML -Title "Rows" -Head $header -body $body `
    | Out-File "res.log" -Append -Encoding UTF8
  } else {
    "<h3>No data</h3>" | Out-File "res.log" -Append -Encoding UTF8
  }

Дар омади гап, ба хати бо System.Management.Automation.PSCustomObject диққат диҳед, он ҷодугар аст, агар дар шабака маҳз як сатр мавҷуд бошад, пас баъзе мушкилот ба миён омад. Ҳалли он аз Интернет гирифта шудааст, бе фаҳмиши зиёд. Дар натиҷа, шумо чунин форматро ба даст меоред:

Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

Тартиб додани графикҳо

Огоҳӣ: Рамзи дар поён овардашуда!
Дар сервери SQL дархости хандоваре мавҷуд аст, ки CPU-ро дар N дақиқаҳои охир нишон медиҳад - маълум мешавад, ки рафик майор ҳама чизро дар хотир дорад! Ин викторинаро санҷед:

DECLARE @ts_now bigint = (SELECT cpu_ticks/(cpu_ticks/ms_ticks) 
  FROM sys.dm_os_sys_info WITH (NOLOCK)); 
SELECT TOP(256) 
  DATEADD(ms, -1 * (@ts_now - [timestamp]), GETDATE()) AS [EventTime],
  SQLProcessUtilization AS [SQLCPU], 
  100 - SystemIdle - SQLProcessUtilization AS [OtherCPU]
FROM (SELECT record.value('(./Record/@id)[1]', 'int') AS record_id, 
  record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') 
    AS [SystemIdle], 
  record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') 
    AS [SQLProcessUtilization], [timestamp] 
  FROM (SELECT [timestamp], CONVERT(xml, record) AS [record] 
  FROM sys.dm_os_ring_buffers WITH (NOLOCK)
  WHERE ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR' 
    AND record LIKE N'%<SystemHealth>%') AS x) AS y 
ORDER BY 1 DESC OPTION (RECOMPILE);

Ҳоло, бо истифода аз ин форматкунӣ (тағйирёбандаи $ Fragment)

<table style="width: 100%"><tbody><tr style="background-color: white; height: 2pt;">
  <td style="width: SQLCPU%; background-color: green;"></td>
  <td style="width: OtherCPU%; background-color: blue;"></td>
  <td style="width: REST%; background-color: #C0C0C0;"></td></tr></tbody>
</table>

Мо метавонем матни мактубро созем:

$Result = invoke-Sqlcmd -ConnectionString $connstr -Query $Query `
  | Select-Object -Property * -ExcludeProperty `
  "ItemArray", "RowError", "RowState", "Table", "HasErrors"
if ($Result.HasRows) {
  foreach($item in $Result) 
    { 
    $time = $itemEventTime 
    $sqlcpu = $item.SQLCPU
    $other = $itemOtherCPU
    $rest = 100 - $sqlcpu - $other
    $f = $fragment -replace "SQLCPU", $sqlcpu
    $f = $f -replace "OtherCPU", $other
    $f = $f -replace "REST", $rest
    $f | Out-File "res.log" -Append -Encoding UTF8
    }

Ки ин тавр хоҳад буд:

Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

Бале, муҳтарам дар бораи таҳрифҳо бисёр чизро медонад! Ҷолиб он аст, ки ин код дорои: Powershell (дар он навишта шудааст), SQL, Xquery, HTML. Афсӯс, ки мо наметавонем Javascript-ро ба HTML илова кунем (зеро он барои навиштан аст), аммо сайқал додани рамзи Python (ки онро дар SQL истифода бурдан мумкин аст) вазифаи ҳама аст!

Натиҷаи пайгирии SQL profiler

Маълум аст, ки пайгирӣ аз сабаби майдони TextData ба CSV мувофиқат намекунад. Аммо нишон додани шабакаи пайгирӣ дар ҳарф низ аҷиб аст - ҳам аз рӯи ҳаҷм ва ҳам азбаски ин маълумот аксар вақт барои таҳлили минбаъда истифода мешавад. Бинобар ин, мо чунин корҳоро мекунем: мо тавассути invoke-SqlCmd як скрипти муайяне, ки дар умқи он анҷом дода мешавад

select 
  SPID,EventClass,TextData,
  Duration,Reads,Writes,CPU,
  StartTime,EndTime,DatabaseName,HostName,
  ApplicationName,LoginName
   from ::fn_trace_gettable ( @filename , default )  

Минбаъд, дар дустон Дар сервере, ки аз ҷониби DBA дастрас аст, пойгоҳи додаҳои Traces бо қолаби холӣ, лавҳаи намунавӣ мавҷуд аст, ки барои қабули ҳамаи сутунҳои зикршуда омода аст. Мо ин моделро ба ҷадвали нав бо номи беназир нусхабардорӣ мекунем:

$dt = Get-Date -format "yyyyMMdd"
$tm = Get-Date -format "hhmmss"
$tableName = $srv + "_" + $dt + "_" + $tm
$copytab = "select * into " + $tableName + " from Model"
invoke-SqlCmd -ConnectionString $tstr -Query $copytab 

Ва ҳоло мо метавонем бо истифода аз он пайгирии худро нависед Data.SqlClient.SqlBulkCopy — Ман дар боло дар ин бора мисол овардам. Бале, инчунин хуб мебуд, ки константаҳоро дар TextData ниқоб кунед:

# mask data
foreach ($Row in $Result)
{ 
  $v = $Row["TextData"]
  $v = $v -replace "'([^']{2,})'", "'str'" -replace "[0-9][0-9]+", '999'
  $Row["TextData"] = $v
}

Мо рақамҳои зиёда аз як аломатро бо 999 иваз мекунем ва сатрҳои аз як аломат дарозтарро бо 'str' иваз мекунем. Рақамҳои аз 0 то 9 аксар вақт ҳамчун парчам истифода мешаванд ва мо ба онҳо даст намерасонем, инчунин дар байни онҳо сатрҳои холӣ ва якҳарфа — 'Y', 'N' ва гайра аксар вақт вомехӯранд.

Биёед ба ҳаёти худ каме ранг илова кунем (қатъиян 18+)

Дар ҷадвалҳо шумо аксар вақт мехоҳед ячейкаҳоеро қайд кунед, ки таваҷҷӯҳро талаб мекунанд. Масалан, ФАЙЛ, сатҳи баланди парокандагӣ ва ғайра. Албатта, ин мумкин аст дар SQL луч анҷом дода мешавад, тавлиди HTML бо истифода аз PRINT ва муқаррар кардани навъи файл ба HTML дар Ҷенкинс:

declare @body varchar(max), @chunk varchar(max)
set @body='<font face="Lucida Console" size="3">'
set @body=@body+'<b>Server name: '+@@servername+'</b><br>'
set @body=@body+'<br><br>'
set @body=@body+'<table><tr><th>Job</th><th>Last Run</th><th>Avg Duration, sec</th><th>Last Run, Sec</th><th>Last Status</th></tr>'
print @body

DECLARE tab CURSOR FOR SELECT '<tr><td>'+name+'</td><td>'+
  LastRun+'</td><td>'+
  convert(varchar,AvgDuration)+'</td><td>'+
  convert(varchar,LastDuration)+'</td><td>'+
    case when LastStatus<>'Succeeded' then '<font color="red">' else '' end+
      LastStatus+
      case when LastStatus<>'Succeeded' then '</font>' else '' end+
     +'</td><td>'
  from #j2
OPEN tab;  
FETCH NEXT FROM tab into @chunk
WHILE @@FETCH_STATUS = 0  
BEGIN
  print @chunk
  FETCH NEXT FROM tab into @chunk;  
END  
CLOSE tab;  
DEALLOCATE tab;
print '</table>'

Чаро ман чунин код навиштам?

Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

Аммо роҳи ҳалли зеботаре вуҷуд дорад. Табдил додан ба HTML ба мо имкон намедиҳад, ки ҳуҷайраҳоро ранг кунем, аммо мо онро пас аз он карда метавонем. Масалан, мо мехоҳем чашмакҳоро бо сатҳи тақсимшавӣ аз 80 ва зиёда аз 90 интихоб кунем. Биёед услубҳоро илова кунем:

<style>
.SQLmarkup-red { color: red; background-color: yellow; }
.SQLmarkup-yellow { color: black; background-color: #FFFFE0; }
.SQLmarkup-default { color: black; background-color: white; }
</style>

Дар худи пурсиш мо сутуни мукаммалро илова мекунем фавран пеш сутунро ранг кардан мехоҳем. Сутун бояд даъват карда шавад SQLmarkup-чизе:

case  
  when ps.avg_fragmentation_in_percent>=90.0 then 'SQLmarkup-red'
  when ps.avg_fragmentation_in_percent>=80.0 then 'SQLmarkup-yellow'
  else 'SQLmarkup-default' 
  end as [SQLmarkup-1], 
ps.avg_fragmentation_in_percent, 

Ҳоло, HTML-и аз ҷониби Powershell тавлидшударо қабул карда, мо сутуни муҷаррадро аз сарлавҳа хориҷ мекунем ва дар бадани маълумот арзишро аз сутун ба услуб интиқол медиҳем. Ин танҳо бо ду ивазкунӣ анҷом дода мешавад:

$html = $html `
  -replace "<th>SQLmarkup[^<]*</th>", "" `
  -replace "<td>SQLmarkup-(.+?)</td><td>",'<td class="SQLmarkup-$1">'

Натиҷа:
Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

Оё он шево нест? Ҳарчанд не, ин ранг ба ман чизеро хотиррасон мекунад
Автоматикунонии сервери SQL дар Ҷенкинс: баргардонидани натиҷа зебо

Манбаъ: will.com

Илова Эзоҳ