Dîsa . DBA-yên pêşerojê dê nikaribin rasterast bi serverên PROD-ê ve girêbidin, lê dê bikaribin bikar bînin Jenkins karên ji bo komek sînorkirî ya operasyonan. DBA dest bi kar dike û piştî demekê nameyek bi raporek li ser temambûna vê operasyonê distîne. Ka em li awayên pêşkêşkirina van encaman ji bikarhêner re binihêrin.

Nivîsara Rast
Ka em bi ya herî kêm dest pê bikin. Rêbaza yekem ew qas hêsan e ku bi rastî tiştek tune ku meriv li ser biaxive (nivîskar ji vir şûnde karên FreeStyle bikar tîne):

sqlcmd tiştek dike û em pêşkêşî bikarhênerê dikin. Ji bo nimûne, karên paşvekêşanê îdeal e:

Ji bîr nekin, bi awayê, ku di bin hilanînê/vegerandina RDS de asynkron e, ji ber vê yekê hûn hewce ne ku li benda wê bisekinin:
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 againRêbaza duyemîn, CSV
Her tişt li vir jî pir hêsan e:

Lêbelê, ev rêbaz tenê kar dike heke daneyên ku di CSV-ê de têne vegerandin "hêsan" be. Ger hûn hewl bidin, mînakî, navnîşek pirsên TOP N CPU yên bi vî rengî vegerînin, CSV dê "xirab bibe" ji ber vê yekê ku metna pirsê dikare her karakteran bigire - commas, quotes, û tewra şikestinên rêzê. Ji ber vê yekê, em hewceyê tiştek tevlihevtir e.
Nîşanên xweşik di HTML-ê de
Ez ê tavilê kodek ji we re bidim
$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
}Bi awayê, bala xwe bidin rêza System.Management.Automation.PSCustomObject, ger di torê de tam yek rêz hebe, wê hingê hin pirsgirêk derketin. Çareserî bêyî têgihiştineke zêde ji Înternetê hate girtin. Wekî encamek, hûn ê encamek mîna vî rengî formatkirî bistînin:

Rakirina grafikan
Hişyarî: koda kinky li jêr!
Li ser servera SQL-ya ku CPU-yê N deqeyên paşîn nîşan dide pirsek dilşewat heye - derket holê ku Heval Major her tiştî bi bîr tîne! Vê quizê biceribînin:
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);Naha, vê formatkirinê bikar tîne (guherbar $ 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>Em dikarin laşê nameyê pêk bînin:
$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
}Ku dê bi vî rengî xuya bike:

Erê, Monsieur di derheqê perîşanan de pir tişt dizane! Balkêş e ku ev kod dihewîne: Powershell (di tê de hatî nivîsandin), SQL, Xquery, HTML. Heyf e ku em nikanin Javascriptê li HTML-ê zêde bikin (ji ber ku ew ji bo nivîsandinê ye), lê paqijkirina koda Python (ku di SQL-ê de tê bikar anîn) peywira her kesî ye!
Derketina şopa profîlek SQL
Eşkere ye ku ji ber qada TextData, şop dê di CSV-yê de nemîne. Lê xuyangkirina tora şopê di nameyekê de jî ecêb e - hem ji ber mezinahiyê û hem jî ji ber ku ev dane bi gelemperî ji bo analîzkirina bêtir têne bikar anîn. Ji ber vê yekê, em jêrîn dikin: em bi rêya bang dikin gazî-SqlCmd senaryoyek diyar, di kûrahiya wê de tê kirin
select
SPID,EventClass,TextData,
Duration,Reads,Writes,CPU,
StartTime,EndTime,DatabaseName,HostName,
ApplicationName,LoginName
from ::fn_trace_gettable ( @filename , default ) Piştre, li ser heval server, ku ji bo DBA-yê gihîştî ye, databaseke Traces bi şabloneke vala, tabloyeke Modelê heye, amade ye ku hemî stûnên diyarkirî qebûl bike. Em vê modelê li tabloyeke nû bi navekî bêhempa kopî dikin:
$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 Û naha em dikarin şopa xwe bi karanîna wê binivîsin Data.SqlClient.SqlBulkCopy - Min li jor jî mînakek vê yekê da. Erê, di heman demê de dê xweş be ku meriv domdar di TextData de mask bike:
# mask data
foreach ($Row in $Result)
{
$v = $Row["TextData"]
$v = $v -replace "'([^']{2,})'", "'str'" -replace "[0-9][0-9]+", '999'
$Row["TextData"] = $v
}
Em jimareyên ji yek tîpan dirêjtir bi 999, û em rêzikên ji yek tîpan dirêjtir bi 'str' diguherînin. Hejmarên ji 0 heta 9 gelek caran wek ala têne bikaranîn û em destê xwe nadin wan, her weha di nav wan de rêzikên vala û yek tîpî - 'Y', 'N' û hwd.
Werin em hinekî reng li jiyana xwe zêde bikin (bi hişkî 18+)
Di tabloyan de, hûn pir caran dixwazin şaneyên ku balê hewce dikin ronî bikin. Mînakî, FAILS, asta bilindbûna perçebûnê, hwd. Bê guman, ev dikare di SQL tazî de were kirin, HTML-ê bi karanîna PRINT-ê çêbike, û celebê pelê li HTML-ê di Jenkins de saz bike:
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>'
Min çima kodek weha nivîsand?

Lê çareseriyek xweştir heye. ConvertTo-HTML nahêle ku em şaneyan rengîn bikin, lê em dikarin piştî rastiyê bikin. Mînakî, em dixwazin şaneyên bi asta perçebûnê ji 80 û ji 90î zêdetir hilbijêrin. Werin em şêwazan lê zêde bikin:
<style>
.SQLmarkup-red { color: red; background-color: yellow; }
.SQLmarkup-yellow { color: black; background-color: #FFFFE0; }
.SQLmarkup-default { color: black; background-color: white; }
</style>Di pirsê bixwe de em ê stûnek dumî lê zêde bikin yekser berî stûna ku em dixwazin rengîn bikin. Stûn divê bê gotin SQLmarkup-tiştek:
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, Naha, piştî ku HTML-ya ku ji hêla Powershell ve hatî çêkirin wergirtiye, em ê stûna dumî ji sernivîsê derxînin, û di laşê daneyê de em ê nirxê ji stûnê veguherînin şêwazê. Ev bi tenê bi du cîgiran pêk tê:
$html = $html `
-replace "<th>SQLmarkup[^<]*</th>", "" `
-replace "<td>SQLmarkup-(.+?)</td><td>",'<td class="SQLmarkup-$1">'
Encam:

Ma ne elegant e? Her çend na, ev rengîn tiştek tîne bîra min

Source: www.habr.com
