All our servers have the Log Analytics agent installed. The agent is configured to capture performance counters info. I can easily get an overview of CPU usage on all servers by firing this query:
Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize HourlyUsage = avg(CounterValue) by bin(TimeGenerated, 1h), Computer
| render timechart
I would like to create a graph showing the CPU usage of the top 10 heaviest loaded servers. I created a KQL query to get the top 10 of CPU using servers:
let TopCPUMaxServers = Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize Max_CPU = max(CounterValue) by Computer, CounterName
| top 10 by Max_CPU asc nulls last;
This query gives me the list of interesting servers. Now I would like to get the performance counters of this list. When I try this:
let TopCPUMaxServers = Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize Max_CPU = max(CounterValue) by Computer, CounterName
| top 10 by Max_CPU asc nulls last;
Perf | join (TopCPUMaxServers) on Computer
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize avg(CounterValue) by bin(TimeGenerated, 1h), Computer
| render timechart
I only get the measurements from the first query displayed on a time chart. (basically 10 values)
How can I get the performance counters for the servers obtained in the first query?
Regards,
Sven
The default join kind is "innerunique" which returns the first match. You can use a the "leftouter" kind but for this scenario the "in" operator will be simpler and will likely perform better:
let TopCPUMaxServers = Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize Max_CPU = max(CounterValue) by Computer, CounterName
| top 10 by Max_CPU asc nulls last
| project Computer;
Perf
| where Computer in (TopCPUMaxServers)
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize avg(CounterValue) by bin(TimeGenerated, 1h), Computer
| render timechart
You can use next variant using in() operator:
let TopCPUMaxServers = Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize Max_CPU = max(CounterValue) by Computer, CounterName
| top 10 by Max_CPU asc nulls last
| project Computer;
Perf
| where Computer in (TopCPUMaxServers)
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize avg(CounterValue) by bin(TimeGenerated, 1h), Computer
| render timechart
Related
I'm looking for a command in Windows (either cmd or powershell) which will allow me to get which exact type of bus interface my storage device have, not only the type, but also the revision (SATA3, SATA4, NVME2.0 and so on).
For example:
> wmic diskdrive get InterfaceRevision
InterfaceRevision
SATA3
SATA4
NVME2.0
This will get you the bus but not the version.
Function Get-MaxLength {
<#
.SYNOPSIS
Finds the length of the longest item in collection.
.DESCRIPTION
Use this Function to get the length of the longest item in a
collection for use in format strings or other places where
needed.
.PARAMETER TestObj
The qualified object to be tested. See example!
.Parameter MinLen
The minimum length of the item (if using for formatting) which
should be the Label (title) length. Note if the object item
being tested does not have a Length property you MUST specify
the label length!
.OUTPUTS
Returns a numerical value
.EXAMPLE
$NameLen = Get-MaxLength -TestObj $DotNet.PSChildName
$VerLen = Get-MaxLength -TestObj $DotNet.Version
$RNLen = Get-MaxLength -TestObj $DotNet.Release -MinLen 11
#--- .Net Information ---
$fmtDotNet =
#{Expression={$_.PSChildName};Label=".Net Type";Width=$NameLen},
#{Expression={$_.Version};Label="Version No:";Width=$VerLen},
#{Expression={$_.Release};Label="Release No:";Width=$RNLen}
$Dotnet | Format-Table $fmtDotNet
#>
Param(
[Parameter(Mandatory=$True)]
[object] $TestObj,
[Parameter(Mandatory=$False)]
[int] $MinLen = 0,
[Parameter(Mandatory=$False)]
[int] $MaxLen = 0
)
$ErrorActionPreference = "SilentlyContinue"
foreach ($x in $TestObj) {
If ($x.Trim().length -gt $MinLen) {
$MinLen = $x.Trim().length
}
}
If ($MaxLen -ne 0) {
If ($MinLen -gt $MaxLen) {
$MinLen = $MaxLen
}
}
$ErrorActionPreference = "Continue"
Return ,$MinLen
} #End Function ----------- Get-MaxLength -------------------
Function PhysicalDiskTab {
#Physical Drive Info
$PhyDiskInfo = Get-Disk | Where-Object {$_.size -gt 0 } |
Sort-Object -Property DiskNumber
$SSD = $False
$AMArgs = #{Type = 'NoteProperty'
Name = 'SSD'
Value = 'No'}
$PhyDiskInfo | Add-Member #AMArgs
$AMArgs = #{Type = 'NoteProperty'
Name = 'Speed'
Value = '0'}
$PhyDiskInfo | Add-Member #AMArgs
$GCIArgs = #{
NameSpace = "root\Microsoft\Windows\Storage"
Class = "MSFT_PhysicalDisk"
ErrorAction = "SilentlyContinue"
}
$RotateSpeed = Get-CimInstance #GCIArgs |
Select-Object -Property DeviceID,#{Name="Speed/RPMs";
Expression={(&{If($_.MediaType -eq 0) {[Int]0}
Else {$_.SpindleSpeed/600000 -f "#,###"}})}} |
Sort-Object DeviceID
ForEach ($x in $phydiskinfo) {
ForEach ($Device in $RotateSpeed) {
If ($x.number -eq $Device.DeviceID) {
If ($Device.'Speed/RPMs' -eq 0) {
$SSD = $True
$x.SSD = "Yes"
} #End If
Else {
$x.Speed = $([Int]$Device.'SPeed/RPMs') -f "#,###"
}
} #End If ($x.number...
} #End ForEach ($Device
} #End ForEach $x
$DNLen =
Get-MaxLength -TestObj $PhyDiskInfo.Model -MinLen 4
$SNLen =
Get-MaxLength -TestObj $PhyDiskInfo.SerialNumber -MinLen 13
$fmtPhyDisk1 =
#{Expression={ '{0:N0}' -f $_.Number};
Label="Drive`n No.";Width=5;Align='Center'},
#{Expression={$_.Model};Label="`nName";Width=$DNLen},
#{Expression={$_.SSD};Label="`nSSD";Width=3;Align='left'},
#{Expression={ '{0:#,000.00}' -f ($_.Size/1gb)};
Label="Disk Size`n / GB";Width=9;align='right'},
#{Expression={$_.NumberOfPartitions};
Label="Parti`ntions";Width=5},
#{Expression={$_.PartitionStyle};Label="GPT`nMBR";Width=3},
#{Expression={(&{If ($_.IsBoot) {"Yes"} else {""}})};
Label="`nBoot";Width=5;Align="Left"},
#{Expression={(&{If ($_.BusType.GetType().Name -eq 'UInt16'){
(& {Switch ($_.BusType) {
0 {"Unknown"}
1 {"SCSI"}
2 {"ATAPI"}
3 {"ATA"}
4 {"1394"}
5 {"SSA"}
6 {"Fibre Channel"}
7 {"USB"}
8 {"RAID"}
9 {"iSCSI"}
10 {"SAS"}
11 {"SATA"}
12 {"SD"}
13 {"MMC"}
14 {"MAX"}
15 {"File Backed Virtual"}
16 {"Storage Spaces"}
17 {"NVMe"}
18 {"MS Reserved"}
Default {"Unknown"}}})}
Else{$_.BusType}})};Label="`nData Bus";Width=20}
$fmtPhyDisk2 =
#{Expression={ '{0:N0}' -f $_.Number};
Label="Drive`n No.";Width=5;Align='Center'},
#{Expression={$_.Model};Label="`nName";Width=$DNLen},
#{Expression={$_.SerialNumber.Trim()};
Label="`nSerial Number";Width=$SNLen;Align='left'},
#{Expression={
(&{If ($_.HealthStatus.GetType().Name -eq 'UInt16'){
(& {Switch ($_.HealthStatus) {
0 {"Healthy"}
1 {"Warning"}
2 {"Unhealthy"}
Default {"Unknown"}}})}
Else{$_.HealthStatus}})};Label="`nStatus";Width=7},
#{Expression={$_.Speed};
Label="Rotation`n RPMs ";Width=8;Align='Right'}
$PhyDiskInfo1 = $PhyDiskInfo |
Format-Table -Property $fmtPhyDisk1 -Wrap |
Out-String -Width $OStrWidth
$PhyDiskInfo2 = $PhyDiskInfo |
Format-Table -Property $fmtPhyDisk2 -Wrap |
Out-String -Width $OStrWidth
$PhyDiskTitle = "Physical Disk Information:" | Out-String
Return ,$($PhyDiskTitle + $PhyDiskInfo1 + $PhyDiskInfo2)
} #End Function ---------------- PhysicalDiskTab --------------
$OStrWidth = 79
PhysicalDiskTab
Output:
Physical Disk Information:
Drive Disk Size Parti GPT
No. Name SSD / GB tions MBR Boot Data Bus
----- ----- --- --------- ----- --- ----- ---------
0 Samsung SSD 960 Yes 232.89 4 GPT Yes NVMe
1 Samsung SSD 850 PRO 256GB Yes 238.47 2 GPT SATA
2 Samsung SSD 850 PRO 256GB Yes 238.47 1 GPT SATA
Drive Rotation
No. Name Serial Number Status RPMs
----- ----- -------------- ------- --------
0 Samsung SSD 960 0025_3853_81B0_B2EB. Healthy 0
1 Samsung SSD 850 PRO 256GB S39KNX0J687882W Healthy 0
2 Samsung SSD 850 PRO 256GB S39KNX0J688151N Healthy 0
This code was pulled from my CMsLocalPCInfoW10 program which can be downloaded from my shared OneDrive library.
I have installed PostgreSQL version 11 on Windows 10 PC two times. First time it was from official installer for Windows, second time it was a set of packages for cygwin.
The problem is, I can't get any database locale settings to work correctly. In any of the two above cases, the Postgres cluster was initialized with initdb command.
With cygwin install, the command has -E UTF8, --locale=uk_UA.utf8 and same for collation and ctypes. cygwin seemed to recognize the command, the cluster was created. Then I've created database with appropriate settings and some tables in it.
The output of simple query were plain wrong for my locale. It was $ sign instead of грн for monetary, . insteed of , for fraction and so on. The official installer gave the same results, with locale set up and displayed correctly.
Same initdb and create database are giving me correct results with linux OS.
initdb
initdb —pgdata=... \
—locale=uk_UA.utf8
—lc-collate=...
—lc-type=...
—lc-monetary=...
—lc-numeric=...
—lc-time=...
—encoding=UTF-8
Here, basically I’ve repeated the uk_UA.utf8 locale.
Also tried with “uk-x-icu” locale, as windows version compiled with icu library as it seems.
The queries
create database db
template = template0
encoding = 'UTF8'
lc_collate = 'uk_UA.utf8'
... = 'uk_UA.utf8'
lc_ctype = 'uk_UA.utf8'
connection_limit = -1
is_template = false
;
create table c_types (
id serial,
c_date date,
c_text text,
c_time time,
c_timestamp timestamp,
c_money money,
c_float float
);
insert into c_types(c_date,c_text,c_time,c_timestamp,c_money,c_float) values
('2019-09-01', 'text0', '00:00:01', timestamp '2019-09-01 20:00:00', 1000.0001, 1000.0001),
('2019-09-01', 'text1', '00:00:02', timestamp '2019-09-01 21:00:00', 2000.0001, 2000.0001)
;
select * from c_types;
Correct output(Linux)
# id | c_date | c_text | c_time | c_timestamp | c_money | c_float
#----+------------+--------+----------+---------------------+---------------+-----------
# 1 | 2019-09-01 | text0 | 00:00:01 | 2019-09-01 20:00:00 | 1 000,00грн. | 1000.0001
# 2 | 2019-09-01 | text1 | 00:00:02 | 2019-09-01 21:00:00 | 2 000,00грн. | 2000.0001
This post shows that lc_numeric does not do influence separator in numerics as is
https://stackoverflow.com/a/41759744/8339821
Influenced functions are to_number, to_char etc
https://stackoverflow.com/a/8935028/8339821
The question is, how can I set up Postgres for my locale?
A C++ version (How can I get an HMONITOR handle from a display device name?) has no solution provided (at least in my circumstances that require non-OOP code such as in AutoIt).
I'm adapting an AutoIt script that uses WinAPI functions to support multi-monitor Windows 7+ systems. I can provide either monitor/device Name or it's Index, but some functions require an HMONITOR handle instead.
I cannot get the HMONITOR by Window or by pixel or point, which would be quite easy. No, I need to get the handle from name or index only, and I need a non-OOP solution (ideally AutoIt & WinAPI calls but non-OOP pseudo-code would be fine).
The function below returns an array of the following structure:
| hMonitor | xPosMonitor | yPosMonitor | widthMonitor | heightMonitor |
| 0x00010001 | 0 | 0 | 1366 | 768 |
| 0x0001024 | 1366 | -236 | 1920 | 1080 |
Code:
#include-once
#include <Array.au3>
#include <WinAPIGdi.au3>
Func _getMonitorInfos()
Local $aPosition, $aMonitorData = _WinAPI_EnumDisplayMonitors()
If IsArray($aMonitorData) Then
ReDim $aMonitorData[$aMonitorData[0][0] + 1][5]
For $i = 1 To $aMonitorData[0][0] Step 1
$aPosition = _WinAPI_GetPosFromRect($aMonitorData[$i][1])
For $j = 0 To 3 Step 1
$aMonitorData[$i][$j + 1] = $aPosition[$j]
Next
Next
Return $aMonitorData
EndIf
EndFunc
Global $aMonitorData = _getMonitorInfos()
_ArrayDisplay($aMonitorData)
hMonitor value is contained by the array $aMonitorData[1][1].
I have troubles with the output of this simple query:
select
pid,
state
from pg_stat_activity
where datname = 'My_DB_name'
while running it different ways:
In IDE
Via running psql in terminal
In bash script:
QUERY="copy (select pid, state from pg_stat_activity where datname = 'My_DB_name') to stdout with csv"
psql -h host -U user -d database -t -c "$QUERY" >> result
1 and 2 return results as I need them:
1:
pid state
------ -----------------------------
23126 idle
25573 active
2642 active
20420 idle
23391 idle
5339 idle
7710 idle
1558 idle
12506 idle
2862 active
716 active
9834 idle in transaction (aborted)
2:
pid | state
-------+-------------------------------
23126 | idle
25573 | idle
2642 | active
20420 | idle
23391 | idle
5339 | active
7710 | idle
1558 | idle
12506 | idle
2211 | active
716 | active
9834 | idle in transaction (aborted)
3 is weird - it doesnt give me any state name except 'active'
23126,
25573,
2642,
20420,
23391,
5339,
7710,
1558,
12506,
1660,active
716,active
1927,active
9834,
What am I missing? How to get all the state names via bash script?
pg_stat_activity is a catalog view that will show different content depending on whether you're logged in as a superuser, or as a non-privileged user.
From your output, it looks like you're logged in as superuser in #1 and #2, but as a normal user in #3.
I made a powershell script where the program is being killed if the cpu load goes over 40%.
This is the code:
$procname = 'vlc'
$cpu_usage=40
$logfile = 'C:\HighCPU.log'
Get-WmiObject Win32_PerfFormattedData_PerfProc_Process -Filter "Name like'$procname%' and PercentProcessorTime > $cpu_usage" |
% {
"{0} - killing process {1} ID {2} cpu usage: {3}" -f (Get-Date), $procname,$_.IDProcess, $_.PercentProcessorTime | Out-File -Append $logfile
kill $_.idprocess
}
I want to make this code loop until the CPU load for this certain procname is below 40. Than the script needs to exit. The interval of the check can be dynamic/adjustable. Say 5 seconds.
Also if possible I was wondering how i can make it check more than one procname.
The logfile is there to log the situation but actually is obsolite.