ICMP/Ping with ObjectScript
Is it possible to "Ping" a remote host in IRIS for Health using ObjectScript? We host hundreds of TCP connections over hundreds of VPNs. I'm working on a project that would make it nice to have way to ping remove clients over the VPN to monitor connectivity and keep the tunnels alive.
Another thought/method would be to make an OS system call (AWS Linux), but I don't see a way to do that either.
Comments
You OTHER thought is supported by CPIPE
see Execute Server Commands from Caché / Ensemble / IRIS
You may want to consider using something like SNMP.
Four short lines of Objectscript code
ClassMethod Ping(host)
{
set cmd="ping "_host
open cmd:"QR":10for {use cmd read ans quit:$zeofuse0write ans,!}
close cmd
}
// some testdo##class(your.class).Ping("google.com")
Pinging google.com [142.250.185.110] with 32 bytes of data:
Reply from 142.250.185.110: bytes=32 time=25ms TTL=114
Reply from 142.250.185.110: bytes=32 time=26ms TTL=114
Reply from 142.250.185.110: bytes=32 time=19ms TTL=114
Reply from 142.250.185.110: bytes=32 time=19ms TTL=114
Ping statistics for142.250.185.110:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 19ms, Maximum = 26ms, Average = 22ms
Some remarks:
// on Linux, it's a good idea to limit the ping countset cmnd="ping -c 3 "_host
// if $zeof isn't alway on, as on my systems the case is// we need two more linesset cmd="..."set old=$system.Process.SetZEOF(1) // turn $ZEOF onopen cmd...
...
close cmd
do$system.Process.SetZEOF(old) // reset to old statemuch better than CPIPE
Awesome - Works like a charm!! I'm new here - please let me know if there is something I should do to mark this "Resolved"
Nice, the first part of the problem (or project, if you wish) is solved. What about a "side project", not pinging all but the active VPNs only? Use the netstat command to get all the established connections
/// Execute an arbitrary OS command and return the command outputClassMethod OSCmd(cmd, ByRef ans)
{
kill ans
open cmd:"QR":10set old=$system.Process.SetZEOF(1), ans=0if$test {
use cmd
for {read line quit:$zeofset ans($increment(ans))=line}
close cmd
}
quit ans
}
Of course, you have to take into account OS specific differences and access rights
do##class(your.classname).OSCmd("ping google.com", .ans) zw ans
ans=11
ans(1)=""
ans(2)="Pinging google.com [142.250.185.174] with 32 bytes of data:"
ans(3)="Reply from 142.250.185.174: bytes=32 time=21ms TTL=114"
ans(4)="Reply from 142.250.185.174: bytes=32 time=27ms TTL=114"
ans(5)="Reply from 142.250.185.174: bytes=32 time=19ms TTL=114"
ans(6)="Reply from 142.250.185.174: bytes=32 time=18ms TTL=114"
ans(7)=""
ans(8)="Ping statistics for 142.250.185.174:"
ans(9)=" Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),"
ans(10)="Approximate round trip times in milli-seconds:"
ans(11)=""do##class(your.classname).OSCmd("netstat -ano | findstr ""ESTABLISHED""", .ans) zw ans
ans=6
ans(1)=" TCP 127.0.0.1:23 127.0.0.1:50814 ESTABLISHED 8272"
ans(2)=" TCP 127.0.0.1:23 127.0.0.1:60874 ESTABLISHED 2872"
ans(3)=" TCP 127.0.0.1:23 127.0.0.1:63199 ESTABLISHED 8272"
ans(4)=" TCP 127.0.0.1:1972 127.0.0.1:49436 ESTABLISHED 2404"
ans(5)=" TCP 127.0.0.1:1972 127.0.0.1:51840 ESTABLISHED 2404"
ans(6)=" TCP 127.0.0.1:1972 127.0.0.1:54330 ESTABLISHED 2404"Now you can analyse and process the command output...
Also, see this post too.
Use CheckAddressExist:
w##class(%SYSTEM.INetInfo).CheckAddressExist(ip)💡 This question is considered a Key Question. More details here.