Show the Ping Results on a Webpage

Outline

  1. File Output
  2. At Jobs
  3. Cron Jobs
  4. File Input
  5. WWW Server
  6. HTML IMG

File Output

  1. Consider the program we developed last week:
    from icmplib import ping
    
    hosts = ['family.cloudflare-dns.com', 'moodle.ncnu.edu.tw', 'sis.ncnu.edu.tw']
    for host in hosts:
        h = ping(host, privileged=False)
        print(f"{host} ({h.address}) is", end='\t')
        if h.is_alive:
            print('alive')
        else:
            print('unreachable')
  2. It displays the output on the screen. Although this is good for debugging (so that you can see the output immediately), it is inconvenient for "re-use". For example, if we want to run the program every hour, and see in which hours the connection is unstable (or the Round-Trip Time is higher), you must copy-and-paste the measurement result manually. Since this is a routine task, you should try to automate it.
  3. The first step is that, we should store the output in a file. In Linux shells, you can certainly do this by I/O Re-direction:
  4. However, you may also specify that in Python:
    from icmplib import ping
    
    hosts = ['family.cloudflare-dns.com', 'moodle.ncnu.edu.tw', 'sis.ncnu.edu.tw']
    f = open('icmp.output', 'w')
    for host in hosts:
        h = ping(host, privileged=False)
        print(f"{host} ({h.address}) is", end='\t', file=f)
        if h.is_alive:
            print('alive', file=f)
        else:
            print('unreachable', file=f)
    f.close()

At Jobs

  1. You may instruct your server to run a command at a specific time.
  2. Install the at command and start the service:
  3. If you are running a container, you should also modify /etc/pam.d/atd, replace "session required pam_loginuid.so" with "session optional pam_loginuid.so". Then restart the atd service by "service atd restart".
  4. Now you may type "at 0900" to run commands at 09:00 (Greenwich Mean Time). Type the commands which you want to run (e.g., "python icmp.py") and press ENTER at the end of each command. When you are done, press Ctrl+D.
  5. If there is only one line of command, a simpler alternative is "echo python icmp.py | at 0900".
  6. The at command allows you to specify the time with a flexible format. For example,
  7. Type "atq" to see the tasks in the waiting queue.
  8. If you forget what a job will do, type "at -c JOB_ID" to inspect the command it will execute.
  9. Type "atrm JOB_ID" to remove a job.

Cron Jobs

  1. Many administrative tasks have to been done regularly (e.g., every hour, or every 5 minutes).
  2. On Linux, we perform this by the cron services. (On Windows, we do this by Task Scheduler.)
  3. Install the cron service:
  4. If you are running a container, you should also modify /etc/pam.d/cron, replace "session required pam_loginuid.so" with "session optional pam_loginuid.so". Then start the cron service by "service cron start".
  5. Type "crontab -e" to edit your cron job list. Add a line "* * * * * /home/solomon/SNMP/bin/python /home/solomon/SNMP/Code/icmp.py".
  6. Keep the cron job running for a few minutes. You will observice that the "modified time" of "icmp.output" is updated every minute.
  7. However, the file "icmp.output" is stored in your home directory, so you may want to modify the open() statement in "icmp.py" and specify the full path of the file to be stored (e.g., "/home/solomon/SNMP/Code/icmp.output"). You don't need to restart cron after you modify "icmp.py". The new script will be executed when the next time it gets running.

Filename with Timestamp

  1. The above Python script overwrites the previous "icmp.output" result, so you will only see the most up-to-date result.
  2. However, sometimes you want to keep all measurements so that you can investigate whether in a specific period of time in a day, the network is often unstable. (This will be useful when students complain that dormintory network is unstable at night.)
  3. In Python, you can get the system clock time and generate a different filename accordingly:
    from datetime import datetime
    
    now = datetime.now()
    FN = '/home/solomon/SNMP/Code/icmp.' + now.strftime("icmp.%Y%m%d%H%M%S")
    print(FN)
  4. To specify the time for a cron job, there are 5 fields. You specify the values of minute (m), hour (h), day of month (dom), month (mon), and day of week (dow), or use '*' in these fields (for 'any').
  5. You may type "crontab -l" to list all cron jobs which are currently running.
  6. If you want to remove any of them, just delete the corresponding line with "crontab -e".

File Input

  1. Currently, the host names which you want to ping are written in a list in the Python script. This is not a good design. A better design is that we separate those "data" from the "code". Keep the code intact while we modify the configuration data.
  2. To read a file in Python, first you open the file in "read" mode, and read its contents with the following functions.
    1. read(): Read the whole file into a string.
      f = open('hosts.txt', 'r')
      s = f.read()
      print(s.upper(), end='')
      f.close()
    2. readline(): Read a single line (terminated by the newline character '\n'). This function is useful when the whole file is large. Processing a single line at a time occupies little memory.
      f = open('hosts.txt', 'r')
      line = f.readline()
      for c in line:
          print(f"{c:>3}", end='')
      for c in line:
          print(f"{ord(c):3}", end='')
      print()
      f.close()
    3. readlines(): If memory consumption is not an issue, we often read the whole file into a list, in which each element is a line, as what you get in readline(). Note that the terminating '\n' is included, if you want to get rid of it, use string slicing in Python.
      f = open('hosts.txt', 'r')
      lines = f.readlines()
      f.close()
      
      for i in range(len(lines)):
          print(i, lines[i][:-1])
  3. Because we often process one line at a time, there is a for-loop construct for it:
    f = open('hosts.txt', 'r')
    n = 0
    for line in f:
        print(n, line[:-1])
        n += 1
    f.close()
  4. Exercise: Modify your program and list the hosts which you want to ping in a file (e.g., "hosts.txt").

WWW Server

  1. If the server regularly generate output files, we can browse it with the browsers on our mobile phones, as long as a WWW server is enabled on the server.
  2. For simplicity, let's use Apache 2.4 in this exercise. (You may also use your own favorite WWW servers, such as Nginx.)
  3. Inspect /etc/apache2/sites-enabled/000-default.conf, you see the DocumentRoot is /var/www/html.
  4. ln -s /home/solomon/SNMP/Code /var/www/html
  5. Then you can browse the directory at http://YOURHOST/Code

HTML IMG

  1. Reading a plaintext file is not easy.
  2. Try to generate an HTML file (also a text file), as shown in http://solomon.ipv6.club.tw/AutoStatus/