Jenkins இல் SQL சேவையகத்தின் ஆட்டோமேஷன்: முடிவை அழகாகத் தருகிறது

மீண்டும் ஏற்பாட்டின் கருப்பொருளைத் தொடர்கிறது ஜீரோ டச் PROD RDS இன் கீழ். எதிர்கால DBAகள் நேரடியாக PROD சேவையகங்களுடன் இணைக்க முடியாது, ஆனால் பயன்படுத்த முடியும் ஜென்கின்ஸ் வரையறுக்கப்பட்ட செயல்பாடுகளுக்கான வேலைகள். DBA வேலையைத் தொடங்குகிறது மற்றும் சிறிது நேரத்திற்குப் பிறகு இந்த செயல்பாட்டை முடித்ததற்கான அறிக்கையுடன் ஒரு கடிதத்தைப் பெறுகிறது. இந்த முடிவுகளை பயனருக்கு வழங்குவதற்கான வழிகளைப் பார்ப்போம்.

Jenkins இல் SQL சேவையகத்தின் ஆட்டோமேஷன்: முடிவை அழகாகத் தருகிறது

சாதாரண எழுத்து

மிகவும் அற்பமானவற்றுடன் ஆரம்பிக்கலாம். முதல் முறை மிகவும் எளிமையானது, அதைப் பற்றி பேச எதுவும் இல்லை (ஆசிரியர் இனி ஃப்ரீஸ்டைல் ​​வேலைகளைப் பயன்படுத்துகிறார்):

Jenkins இல் SQL சேவையகத்தின் ஆட்டோமேஷன்: முடிவை அழகாகத் தருகிறது

sqlcmd ஏதாவது செய்கிறது மற்றும் அதை பயனருக்கு வழங்குகிறோம். எடுத்துக்காட்டாக, காப்புப் பிரதி வேலைகளுக்கு ஏற்றது:

Jenkins இல் 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

இங்கே எல்லாம் மிகவும் எளிமையானது:

Jenkins இல் 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 உடன் வரிக்கு கவனம் செலுத்துங்கள், அது மாயமானது; கட்டத்தில் சரியாக ஒரு வரி இருந்தால், சில சிக்கல்கள் எழுந்தன. தீர்வு அதிகம் புரியாமல் இணையத்தில் இருந்து எடுக்கப்பட்டது. இதன் விளைவாக, இது போன்ற வடிவிலான வெளியீட்டைப் பெறுவீர்கள்:

Jenkins இல் SQL சேவையகத்தின் ஆட்டோமேஷன்: முடிவை அழகாகத் தருகிறது

வரைபடங்கள் வரைதல்

எச்சரிக்கை: கீழே கிங்கி குறியீடு!
SQL சர்வரில் ஒரு வேடிக்கையான வினவல் உள்ளது, இது கடைசி N நிமிடங்களுக்கு CPU ஐக் காட்டுகிறது - தோழர் மேஜர் எல்லாவற்றையும் நினைவில் வைத்திருப்பதாக மாறிவிடும்! இந்த வினாடி வினாவை முயற்சிக்கவும்:

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
    }

எது இப்படி இருக்கும்:

Jenkins இல் SQL சேவையகத்தின் ஆட்டோமேஷன்: முடிவை அழகாகத் தருகிறது

ஆம், மான்சியருக்கு வக்கிரங்கள் பற்றி நிறைய தெரியும்! இந்த குறியீட்டில் இருப்பது சுவாரஸ்யமானது: பவர்ஷெல் (அதில் எழுதப்பட்டுள்ளது), SQL, Xquery, HTML. எங்களால் ஜாவாஸ்கிரிப்டை HTML இல் சேர்க்க முடியவில்லை என்பது ஒரு பரிதாபம் (எழுதுவதற்காக இருப்பதால்), ஆனால் பைதான் குறியீட்டை மெருகூட்டுவது (இது SQL இல் பயன்படுத்தப்படலாம்) அனைவரின் கடமை!

SQL விவரக்குறிப்பு டிரேஸ் வெளியீடு

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 ஆல் அணுகக்கூடிய சேவையகத்தில், ஒரு வெற்று டெம்ப்ளேட்டுடன் ஒரு ட்ரேஸ் தரவுத்தளம் உள்ளது, மாடல் பிளேட், குறிப்பிட்ட அனைத்து நெடுவரிசைகளையும் ஏற்கத் தயாராக உள்ளது. இந்த மாதிரியை ஒரு தனித்துவமான பெயருடன் புதிய அட்டவணைக்கு நகலெடுக்கிறோம்:

$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 

இப்போது நாம் அதை பயன்படுத்தி நமது சுவடு எழுத முடியும் தரவு.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+)

அட்டவணையில், கவனம் தேவைப்படும் செல்களை நீங்கள் அடிக்கடி முன்னிலைப்படுத்த விரும்புகிறீர்கள். எடுத்துக்காட்டாக, FAILS, உயர் நிலை துண்டாடுதல் போன்றவை. நிச்சயமாக, இது வெறும் SQL இல் செய்யப்படலாம், PRINT ஐப் பயன்படுத்தி HTML ஐ உருவாக்கலாம் மற்றும் ஜென்கின்ஸ் இல் கோப்பு வகையை 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>'

நான் ஏன் அத்தகைய குறியீட்டை எழுதினேன்?

Jenkins இல் 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 ஐப் பெற்ற பிறகு, தலைப்பிலிருந்து போலி நெடுவரிசையை அகற்றுவோம், மேலும் தரவின் உடலில் உள்ள மதிப்பை நெடுவரிசையிலிருந்து பாணிக்கு மாற்றுவோம். இது இரண்டு மாற்றீடுகளுடன் செய்யப்படுகிறது:

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

முடிவு:
Jenkins இல் SQL சேவையகத்தின் ஆட்டோமேஷன்: முடிவை அழகாகத் தருகிறது

அது நேர்த்தியாக இல்லையா? இல்லை என்றாலும், இந்த வண்ணம் எனக்கு ஒன்றை நினைவூட்டுகிறது
Jenkins இல் SQL சேவையகத்தின் ஆட்டோமேஷன்: முடிவை அழகாகத் தருகிறது

ஆதாரம்: www.habr.com

கருத்தைச் சேர்