Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

Aftur áframhaldandi þemað fyrirkomulag Zero Touch PROD undir RDS. Framtíðar DBAs munu ekki geta tengst PROD netþjónum beint, en munu geta notað Jenkins störf fyrir takmarkaðan hóp starfsemi. DBA tekur til starfa og fær eftir nokkurn tíma bréf með skýrslu um lok þessarar aðgerðar. Við skulum skoða leiðir til að kynna þessar niðurstöður fyrir notandanum.

Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

Plain Text

Byrjum á því léttvægasta. Fyrsta aðferðin er svo einföld að það er í raun ekkert að tala um (höfundurinn notar hér eftir FreeStyle störf):

Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

sqlcmd gerir eitthvað og við kynnum það fyrir notandanum. Tilvalið fyrir td varavinnu:

Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

Ekki gleyma, við the vegur, að undir RDS öryggisafrit / endurheimt er ósamstilltur, svo þú þarft að bíða eftir því:

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

Önnur aðferð, CSV

Allt hér er líka mjög einfalt:

Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

Hins vegar virkar þessi aðferð aðeins ef gögnin sem skilað er í CSV eru „einföld“. Ef þú reynir að skila, til dæmis, lista yfir TOP N örgjörvafrekar fyrirspurnir á þennan hátt, mun CSV „tærast“ vegna þess að fyrirspurnartextinn getur innihaldið hvaða stafi sem er - kommur, gæsalappir og jafnvel línuskil. Þess vegna þurfum við eitthvað flóknara.

Falleg skilti í HTML

Ég gef þér kóðabút strax

$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
  }

Við the vegur, gaum að línunni með System.Management.Automation.PSCustomObject, hún er töfrandi; ef það er nákvæmlega ein lína í ristinni, þá komu upp vandamál. Lausnin var tekin af netinu án mikils skilnings. Fyrir vikið færðu úttak sniðið eitthvað á þessa leið:

Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

Teikna línurit

Viðvörun: kinky kóða fyrir neðan!
Það er skemmtileg fyrirspurn á SQL þjóninum sem sýnir örgjörvann síðustu N mínúturnar - það kemur í ljós að félagi Major man allt! Prófaðu þessa spurningakeppni:

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);

Notaðu nú þetta snið ($Fragment breytu)

<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>

Við getum myndað meginmál bréfsins:

$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
    }

Sem mun líta svona út:

Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

Já, Monsieur veit mikið um ranghugmyndir! Það er áhugavert að þessi kóði inniheldur: Powershell (skrifað í hann), SQL, Xquery, HTML. Það er leitt að við getum ekki bætt Javascript við HTML (þar sem það er til að skrifa), en að pússa Python kóða (sem hægt er að nota í SQL) er skylda allra!

SQL profiler rekja framleiðsla

Það er ljóst að ummerkin mun ekki passa inn í CSV vegna TextData reitsins. En það er líka undarlegt að birta rekjatöflu í bréfi - bæði vegna stærðarinnar og vegna þess að þessi gögn eru oft notuð til frekari greiningar. Þess vegna gerum við eftirfarandi: við hringjum í gegnum kalla fram-SqlCmd ákveðið handrit, í djúpum þess sem það er gert

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

Næst, á vinur Á þjóninum sem DBA hefur aðgang að er Traces gagnagrunnur með tómu sniðmáti, Model plate, tilbúinn til að taka við öllum tilgreindum dálkum. Við afritum þetta líkan í nýja töflu með einstöku nafni:

$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 

Og nú getum við skrifað ummerki okkar inn í það með því að nota Data.SqlClient.SqlBulkCopy - Ég hef þegar nefnt dæmi um þetta hér að ofan. Já, það væri líka gaman að fela fasta í TextData:

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

Við skiptum út tölum sem eru lengri en einn stafur fyrir 999 og við skiptum út strengjum sem eru lengri en einn stafur fyrir 'str'. Tölur frá 0 til 9 eru oft notaðar sem fánar, og við snertum þau ekki, svo og tómir og stakir strengir - 'Y', 'N' o.s.frv. finnast oft meðal þeirra.

Við skulum bæta smá lit á líf okkar (strend 18+)

Í töflum viltu oft auðkenna frumur sem krefjast athygli. Til dæmis, FAILS, mikil sundrungu o.s.frv. Auðvitað er hægt að gera þetta í berum SQL, búa til HTML með PRINT og stilla skráargerðina á HTML í Jenkins:

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>'

Af hverju skrifaði ég svona kóða?

Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

En það er til fallegri lausn. Umbreyta í HTML leyfir okkur ekki að lita frumurnar, en við getum gert það eftir á. Til dæmis viljum við velja frumur með sundurliðunarstigi meira en 80 og meira en 90. Við skulum bæta við stílum:

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

Í fyrirspurninni sjálfri munum við bæta við dummy dálki strax á undan dálk sem við viljum lita. Dálkurinn ætti að heita SQLmarkup-Eitthvað:

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, 

Nú, eftir að hafa fengið HTML búið til af Powershell, munum við fjarlægja dummy dálkinn úr hausnum og í meginmáli gagna munum við flytja gildið úr dálknum í stílinn. Þetta er gert með aðeins tveimur skiptingum:

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

Niðurstaða:
Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

Er það ekki glæsilegt? Þó nei, þessi litarefni minnir mig á eitthvað
Sjálfvirkni SQL netþjóns í Jenkins: skilar niðurstöðunni fallega

Heimild: www.habr.com

Bæta við athugasemd