Disk Space of Client machines

I would like to monitor the disk space for a variety of computers/servers on our network using Ignition. We have had disk space problems in the past causing a data acquisition system to fail on a server so I would like to monitor that server’s disk space (as well as other systems) and send an alert in the event its disk space becomes low. Any suggestions as to how to gather remote computers disk space?

I know I can use Windows WMIC facility to remotely get disk space from other computers. When I run it however I get the information on the client I’m running it on and not the remote system.

1 Like

Okay, here’s a start…

I thought about just sending an email when disk space gets low, but that wouldn’t really leverage Ignition very much. So, I figured I would collect the information in to a database instead. Attached at the bottom is a MySQL file that will work with this script.

Stick this in a Client Script.

#Get data for client session
ipAddress=system.tag.read("[System]Client/Network/IPAddress").value
hostName=system.tag.read("[System]Client/Network/Hostname").value
userName=system.tag.read("[System]Client/User/Username").value

#Get disk space information
from java.io import File
f=File("C:\\")
total = f.getTotalSpace()
free = f.getFreeSpace()

insertQuery="INSERT INTO monitor.disk_space (t_stamp, ipaddress, hostname, username, totalspace, freespace) VALUES (now(), '%s', '%s', '%s', %d, %d)"
updateQuery="UPDATE monitor.disk_space SET t_stamp=now(),ipaddress='%s', username='%s', totalspace=%d, freespace=%d WHERE hostname='%s'"
selectQuery="SELECT count(*) FROM monitor.disk_space WHERE hostname='%s'"

#Check to see if hostname already exists in the table
record=system.db.runScalarQuery(selectQuery % hostName)

#If record doesn't exist, Insert a new record, else update the existing one.
if record == 0:
  system.db.runUpdateQuery(insertQuery % (ipAddress, hostName, userName, total, free))
  print "Inserted info for ", hostName
else:
  system.db.runUpdateQuery(updateQuery % (ipAddress, userName, total, free, hostName))
  print "Updated info for ", hostName

MonitorDiskSpace.sql (2.3 KB)

1 Like

I was hoping for something that would run on the Gateway (script) that would query selected machines for their space and report in local tags…
From what I read, your script would need to run on every machine. What if that machine is not running Ignition? I’ve tried WMIC but not successful as yet.

1 Like

I was going say that it wasn't what you said, but I think my interpretation of your opening statement was different:

Gimme a bit. :smiley:

1 Like

Had better luck with PSTools

Here’s my initial script using psinfo

from subprocess import Popen, PIPE, STDOUT, call
import csv, StringIO

pclist="HCHUTL02, HCHUTL03, HCHENG01, plantdata"

proc=Popen('C:\\psinfo -d -c "c:" \\\\HCHUTL02,HCHUTL03', shell=True, stdout=PIPE,)
f=proc.communicate()[0]
reader=csv.reader(f.split('\r\n'), delimiter=',')
l=list(reader)
for row in l:
  if len(row)>0:
    name = row[0]
    c=row.index('C:')
    total=row[c+4]
    free=row[c+5]
    percentage=row[c+6]
    print name, total, free, percentage

Same thing with WMIC:

from subprocess import Popen, PIPE, STDOUT, call
import csv, StringIO

pclist=['HCHUTL02', 'HCHUTL03', 'HCHENG01', 'plantdata']

command='wmic /failfast:on /node:'+'"'+'","'.join(pclist)+'"' +' logicaldisk get size,freespace,caption /format:csv'
proc=Popen(command, shell=True, stdout=PIPE,)
f=proc.communicate()[0]
reader=csv.reader(f.split('\r\n'), delimiter=',')
l=list(reader)
for row in l:
  if len(row)>0:
    name = row[0]
    try:
      c=row.index('C:')
      total=row[c+1]
      free=row[c+2]
      print name, total, free
    except:
      pass

All right. Here’s the same functionality as my first post. This will log results into a DB table, can be modified to go to separate tags. Or both :wink: . Next up, sending out the results. Can try going a couple of ways with this. Are you looking to use a roster, or we can use a hard-coded list of recipients. Be happy to help, either way.

from subprocess import Popen, PIPE, STDOUT, call
import csv, StringIO

pclist=['HCHUTL02', 'HCHUTL03', 'HCHENG01', 'plantdata']

insertQuery="INSERT INTO monitor.disk_space (t_stamp, hostname, totalspace, freespace) VALUES (now(), '%s', %d, %d)"
updateQuery="UPDATE monitor.disk_space SET t_stamp=now(), totalspace=%d, freespace=%d WHERE hostname='%s'"
selectQuery="SELECT count(*) FROM monitor.disk_space WHERE hostname='%s'"

for pc in pclist:
  command='wmic /failfast:on /node:"'+pc+'" logicaldisk get size,freespace,caption /format:csv'
#  print command
  proc=Popen(command, shell=True, stdout=PIPE,)
  f=proc.communicate()[0]
#  print f
  reader=csv.reader(f.split('\r\n'), delimiter=',')
  l=list(reader)
  for row in l:
    if len(row)>0:
      foundC=0
      try:
        hostName = row[0]
        c=row.index('C:')
        total=int(row[c+1])
        free=int(row[c+2])
        foundC=1
        #print foundC, hostName, total, free
      except:
        pass
        #print foundC
      if foundC==1:
        #Check to see if hostname already exists in the table
        record=system.db.runScalarQuery(selectQuery % hostName)
      
        #If record doesn't exist, Insert a new record, else update the existing one.
        if record == 0:
          system.db.runUpdateQuery(insertQuery % (hostName, total, free))
          print "Inserted info for ", hostName
        else:
          system.db.runUpdateQuery(updateQuery % (total, free, hostName))
          print "Updated info for ", hostName
1 Like

Finally looking here…

awesome, thanks. I started using the PsInfo technique and maybe put the data in a memory tags, then set up a transaction group to write the data to a database. I can then report on that data… or even alarms.

Excellent!

Jordan, I am looking for something similar, but ALL that I want to do is log C, D and E drive on the Gateway server to the DB. I’m stuck at the beginning of your script. “from subprocess”. If this script is the easiest way of getting all drives TOTAL, USED and FREE space on an Ignition server, can you explain how to use this? If not, what is the best way? I would use psutil, but that is not applicable with Ignition 8’s Jython.

Thanks in advance!

1 Like

No need to run an external process. Java’s File object can deliver total and free bytes for the partition of a given path. (It can also distinguish free space from usable space.)

from java.io import File

def getPartitionSpace(target):
    f = File(target)
    return f.totalSpace, f.freeSpace, f.usableSpace
3 Likes

The scripts I posted later in the thread were for getting information from remote hosts as well as the local one. Take a look at the one I used at the second post, which uses java.io.File to get local information.

2 Likes

I can get this to return data for the local machine name, but when I try to put a remote machine name in, it doesn't return anything. Does root folder sharing need to be enabled on the remote machine or something in order for this to work?

Usually, that would be a permissions issue on the remote machine.

1 Like