Tag Archives: Free Disk Space

FreeBytes.exe (Disk Checker) Revisited

The library and application have been updated to be a little more flexible and take a parameter, so that the minimum free space does not have to be hard-coded into the program.

Here is VolLib, an F# library:

namespace Toa.volLib
open System
open System.Threading
open System.Collections.Generic
open System.Text
open System.IO
open Microsoft.Win32

type DiskFreeLevels =
           | DRIVE_OFF_LINE = -1L
           | GB1   = 1000000000L
           | GB5   = 5000000000L
           | GB10  = 10000000000L
           | GB20  = 20000000000L

[<AutoOpen>]
module volLib =
  let libInit = ref false

  let drive_list () =
    DriveInfo.GetDrives()

  // Takes a string representation of a drive, and pulls out its free space.
  let free_space drive =
      let di = DriveInfo(drive)
      if di.IsReady then
int64(di.AvailableFreeSpace)
      else
int64(-1)

      // Just convert bytes to gigabytes.
      let cvt_bytes_to_gb (in_bytes:int64) =
        int64(truncate((float(int64(in_bytes)) / float(1024L)
/ float(1024L)) / float(1024L)))

        let DRIVE_OFF_LINE = int64(-1)
        let GB1     = cvt_bytes_to_gb(int64(DiskFreeLevels.GB1))
        let GB5     = cvt_bytes_to_gb(int64(DiskFreeLevels.GB5))
        let GB10    = cvt_bytes_to_gb(int64(DiskFreeLevels.GB10))
        let GB20    = cvt_bytes_to_gb(int64(DiskFreeLevels.GB20))
// This is a pipeline function that takes a drive letter (string) and
// returns the free GB from a DriveInfo structure.
         let cvt_drive_to_free_gb drive =
             let fs = free_space drive
             if fs > DRIVE_OFF_LINE then
                free_space drive |> cvt_bytes_to_gb
             else
                int64(-1)

             let cvt_gb_arg_to_int (arg:string) =
                 let numeric_arg = arg.Substring(2, arg.Length - 4)
                 int64(numeric_arg)

and the main application


(*
A simple checker of Windows disks.
Charles M. Norton   11/01/2016
Will be greatly improved over time.

Modifications
Charles M. Norton   11/1/2016
Initial version.
*)

open System
open System.Text
open System.Net.Mail
open System.IO
open System.Threading
open Microsoft.VisualBasic.FileIO
open System.Collections.Generic

open Toa.volLib // local library

let send_email msg =
 use msg =
 new MailMessage ("dbadmin@somewhere.sometown.us",
@"dbadmin@town.arlington.ma.us", @"Disk Space Report\n",
   msg )
use client = new SmtpClient(@"webmail.somewhere.sometown.us")
client.DeliveryMethod <- SmtpDeliveryMethod.Network
  client.Credentials <-
new System.Net.NetworkCredential("dbadmin", "xxxxxx")
  client.Send msg

let match_head = "--"
let match_tail  = "GB"

let contains_match_constants (arg:string) =
    if arg.StartsWith match_head && arg.EndsWith match_tail then
       true
    else
       false

let parse_min_gb_arg arg =
    if contains_match_constants arg then
       cvt_gb_arg_to_int arg
    else
       volLib.GB1

let no_disk = int64(-1)

[<EntryPoint>]
let main argv =
    let min_gb =
    if argv.Length > 0 then
       parse_min_gb_arg argv.[0]
    else
       volLib.GB1

    let local_drive_list = drive_list ()

    let check_file = "free_bytes_check.txt"
    let system_name = System.Environment.MachineName
    let system_drive = Path.GetPathRoot(Environment.SystemDirectory)

    let display_info = new List<string>()
    display_info.Add("System name " + system_name + "\n")

    let drive_list_len = local_drive_list.Length

    for idx = 0 to (drive_list_len - 1) do
        let drive_name = (Seq.item idx local_drive_list).Name
        let free_gb = cvt_drive_to_free_gb drive_name
        let display_row = "Volume: " + drive_name + "\n" + "Free Space: " +
free_gb.ToString() + "GB\n"
        display_info.Add(display_row)

    let curr_time = DateTime.Now

    let gb_c = cvt_drive_to_free_gb system_drive
    let gb_d = cvt_drive_to_free_gb "D:\\"

    let gbs = display_info |> String.concat("\n")

    if not (File.Exists check_file) then
       use swH = new StreamWriter(check_file, true)
       swH.WriteLine(curr_time.ToString())
       send_email gbs
    else
       let fAccessDate = File.GetLastAccessTime(check_file)
       let update_stamp = curr_time.Subtract(fAccessDate).Duration() <
TimeSpan.FromDays(7.0)

    if not(update_stamp) then
       File.WriteAllText(check_file.ToString(), String.Empty)
       use swH = new StreamWriter(check_file, true)
           swH.WriteLine(curr_time.ToString())
       send_email gbs

    if gb_c < min_gb || ((gb_d > no_disk) && gb_d < volLib.GB20) then
       printfn "Disk free space is below thresholds; send out warning email."
       send_email gbs
    else
       printfn "Disk free space is at or above thresholds. "
printfn "All is well, at least for now."</pre>
<pre>    printfn "Sleeping 5 seconds to let you read."
    Thread.Sleep 5000 |> ignore
0 // return an integer exit code

Advertisements

Leave a comment

Filed under F#

F# Free Disk Space

So, here is a small, F# program to report on disk usage. This is from a real example on our Munis server.


(*
A simple checker of Windows disks.
Charles M. Norton   11/01/2016
Will be greatly improved over time.

Modifications
Charles M. Norton   11/1/2016
Initial version.
*)

open System
open System.Text
open System.Net.Mail
open System.IO
open System.Threading

open Toa.volLib // local library

let SendEmail msg =
use msg =
new MailMessage (
"dbadmin@town.arlington.ma.us", @"itadmin@town.arlington.ma.us", @"Munis Server Disk Space Report\n",
msg )

use client = new SmtpClient(@"webmail.town.arlington.ma.us")
client.DeliveryMethod client.Credentials client.Send msg

let main argv =
let localDriveList = driveList ()
let dn = (Seq.head(localDriveList)).Name

let drive_c = (Seq.head(localDriveList)).Name
let data_drive = (Seq.nth(1) localDriveList).Name

let fs_c = freeSpace drive_c
let fs_d = freeSpace data_drive

let gb_c = cvtBytesToGB fs_c
let gb_d = cvtBytesToGB fs_d

let system_name = System.Environment.MachineName

let strings = ["System name: "; system_name; "Volume "; drive_c; gb_c.ToString(); "GB\n"; "Volume"; data_drive; gb_d.ToString(); "GB\n"]
let gbs = String.concat " " strings
printfn "System name: %A: Drive C %f -- Data Drive %f" system_name gb_c gb_d

if gb_c < volLib.GB5 || gb_d < volLib.GB5 then printfn "Disk free space is below thresholds; send out warning email." SendEmail gbs else printfn "Disk free space is at or above thresholds. All is well, at least for now." printfn "Sleeping 5 seconds to let you read." Thread.Sleep 5000 |> ignore
0 // return an integer exit code

Leave a comment

Filed under F#