Outils pour utilisateurs

Outils du site


comptabiliser_le_temps_d_activite_du_systeme

Introduction

Cet article présente un outil de calcul automatique des périodes d'activité (ou “uptime” en anglais) et d'inactivité d'un ordinateur sur une période de temps de longueur quelconque caractérisée par une date initiale donnée.

Le système est dit actif dès qu'il est démarré, on doit donc mémoriser chaque date de démarrage (ou “boot”), et réciproquement l'activité se termine quand on arrête le système.

Le script Python présenté est donc utilisable à 3 niveaux :

  • automatiquement au moment du boot pour mémoriser le démarrage de l'activité,
  • automatiquement à l'arrêt pour mémoriser la fin de l'activité,
  • à la demande par tout utilisateur pour s'informer des valeurs courantes des compteurs.

Exemple de listage obtenu :

Date courante         : 09/08/2006 19:15:07
Date du boot courant  : 09/08/2006 19:12:33
Date initiale         : 07/08/2006 17:13:52
Nombre total de boots : 11
Duree totale          : 180076 secondes, soit 2 jours, 2 heures, 1 minute et 16 secondes
Duree active courante : 155 secondes, soit 2 minutes et 35 secondes
Duree active moyenne  : 3087 secondes, soit 51 minutes et 27 secondes
Duree active maximale : 4851 secondes, soit 1 heure, 20 minutes et 51 secondes
Duree active cumulee  : 33955 secondes, soit 9 heures, 25 minutes et 55 secondes, ou 18.86% de la duree totale
Duree inactive        : 146121 secondes, soit 1 jour, 16 heures, 35 minutes et 21 secondes, ou 81.14% de la duree totale

En fin d'article on présentera aussi un script Bash permettant de créer un service système qui consiste à lancer l'outil automatiquement au boot et à l'arrêt du système.

Article rédigé par Jeanmm 8-)
Version initiale : 8/8/2006.

Le script Python

Voici le script, et pour les explications voir les commentaires inclus et le paragraphe qui suit le script. On conseille d'en enregistrer une version exécutable qu'on nommera uptime2, par exemple dans /usr/local/bin (uptime existe déjà dans /usr/bin).

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
"""
Ce module est un outil de calcul de temps d'activité (uptime) d'un système.
En principe on fait en sort de démarrer la phase d'activité au boot, et
d'en marque la fin à l'arrêt du système.
 
L'outil s'appuie sur 3 petits fichiers textes, dont les noms exacts sont
modifiables dans ce script :
 - dateBoot     : contient la date courante à chaque boot
 - dateInitiale : contient la date initiale de référence, en principe fixée
                  une fois pour toutes.
 - uptimeCumule : contient la somme des durées d'activité, en secondes;
                  à chaque arrêt du système on y ajoute la durée de la
                  période d'activité courante qui se termine.
 
Arguments possibles :
  start  : Appel lors du boot
  stop   : Appel lors de l'arrêt du système
  sinon on liste simplement les compteurs courants.
 
Les appels start et stop peuvent être effectués par root, avec des fichiers
protégés en écriture mais lisibles de tous, ce qui fait que l'appel sans
paramètres pourra se faire à tout moment sans être root.
 
Version initiale : 08/08/2006
Auteur  : Jeanmm
Licence : GPL
Lien    : www.root66.net
"""
 
import sys, os, shutil, time, string
 
# Parametres du programme (les 3 noms de fichiers) :
# - dateBoot     : écrit à chaque boot, sinon créé à la date courante
# - dateInitiale : doit exister, sinon copie de dateBoot
# - uptimeCumule : doit exister, sinon créé à zéro
# Si le dossier du fichier dateBoot n'existe pas on tentera de le créer
 
dateBoot     = '/usr/local/uptime2/dateBoot.txt'
dateInitiale = '/usr/local/uptime2/dateInitiale.txt'
uptimeCumule = '/usr/local/uptime2/uptimeCumule.txt'
 
# Conversion d'une duree de secondes en 'années, mois, jours...'
 
def zDuree(x):
    if x >= 31536000:
        (q, r) = divmod(x, 31536000)
        if q > 1:
            z = "%.0f" %(q) + " ans, "
        else:
            z = "1 an, "
        x = x - q * 31536000
    else:
        z = ""
 
    if x >= 86400:
        (q, r) = divmod(x, 86400)
        if q > 1:
            z = z + "%.0f" %(q) + " jours, "
        else:
            z = z + "1 jour, "
        x = x - q * 86400
 
    if x >= 3600:
        (q, r) = divmod(x, 3600)
        if q > 1:
            z = z + "%.0f" %(q) + " heures, "
        else:
            z = z + "1 heure, "
        x = x - q * 3600
 
    if x >= 60:
        (q, r) = divmod(x, 60)
        if q > 1:
            z = z + "%.0f" %(q) + " minutes et "
        else:
            z = z + "1 minute et "
        x = x - q * 60
 
    if x > 1:
        z = z + "%.0f" %(x) + " secondes"
    else:
        z = z + "%.0f" %(x) + " seconde"
 
    return z
 
# Programme principal
# -------------------
 
if __name__=='__main__':
 
    # Parametres d'appel
    N = len(sys.argv)
    start = 0 # 1 si appel lors du boot
    stop  = 0 # 1 si appel lors de l'arrêt du système
    if N > 0:
        for i in range(N):
            # Appel lors du boot
            if sys.argv[i] == 'start':
                start = 1
            # Appel lors de l'arrêt du système
            elif sys.argv[i] == 'stop':
                stop = 1
            # Help
            elif sys.argv[i] == '-h' or sys.argv[i] == 'help' or sys.argv[i] == '--help':
                print "Cet outil calcule la duree d'activite (uptime) du systeme"
                print "Arguments possibles :"
                print "  start  : Appel lors du boot,"
                print "  stop   : Appel lors de l'arret du systeme,"
                print "  sinon listage des compteurs courants."
                print "Auteur : Jeanmm - www.root66.net"
                print "Licence : GPL"
                sys.exit(0)
 
    # date courante
    x = time.localtime() # tuple
    t = time.time()      # float
    # idem sous forme de chaîne
    xx = time.strftime('%d/%m/%Y %H:%M:%S')
 
    # Test si le fichier de boot existe, sinon on tente de le créer
    if not os.path.isfile(dateBoot):
        # si le dossier n'existe pas on tente de le créer
        if not os.path.isdir(os.path.dirname(dateBoot)):
            try: os.makedirs(os.path.dirname(dateBoot))
            except: pass
        try:
            fb = open(dateBoot, 'w')
            fb.write(xx + '\n')
            fb.close()
            print "Le fichier '" + dateBoot + "' a ete initialise !"
        except:
            print "Erreur : le fichier '" + dateBoot + "' ne peut pas etre ecrit !"
            sys.exit(1)
 
    # Test si le fichier initial existe
    if not os.path.isfile(dateInitiale):
        try:
            shutil.copy(dateBoot, dateInitiale)
            if not stop:
                print "Le fichier '" + dateInitiale + "' a ete initialise !"
        except:
            print "Erreur : le fichier '" + dateInitiale + "' ne peut pas etre cree,"
            print "         et/ou bien le fichier '" + dateBoot + "' n'existe pas !"
            sys.exit(1)
 
    # Cas de l'appel au boot
    # On écrit la date courante dans dateBoot
    if start:
        try:
            fb = open(dateBoot, 'w')
            fb.write(xx + '\n')
            fb.close()
        except:
            print "Erreur : le fichier '" + dateBoot + "' ne peut pas etre ecrit !"
            sys.exit(1)
        print "Le fichier '" + dateBoot + "' a ete ecrit : %s" %(xx)
 
    if not stop:
        print "Date courante         : %02d/%02d/%04d %02d:%02d:%02d" %(x[2], x[1], x[0], x[3], x[4], x[5])
 
    # Lecture du fichier de boot
    # qui contient une date 'jj/mm/aaaa hh:mm:ss'
    try:
        fb = open(dateBoot, 'r')
        zb = fb.read()
        fb.close()
    except:
        print "Erreur : le fichier '" + dateBoot + "' ne peut pas etre lu !"
        sys.exit(1)
 
    if zb[-1] == '\n':
        zb = zb[0:-1]
    tb = time.strptime(zb, '%d/%m/%Y %H:%M:%S')
    if not stop:
        print "Date du boot courant  : " + zb
 
    # Lecture du fichier de cumul
    # qui contient un nombre flottant en secondes
    try:
        fc = open(uptimeCumule, 'r')
        zc = fc.read()
        fc.close()
    except:
        fc = open(uptimeCumule, 'w')
        fc.write('0.0 0 0.0\n')
        fc.close()
        print "Le fichier '" + uptimeCumule + "' a ete initialise !"
        zc = '0.0'
 
    # Le fichier contient le cumul, ou de plus le nombre de sessions et l'uptime max
    v = string.split(zc)
    tc = float(v[0])
    if len(v) > 1:
        ns = int(v[1])
    else:
        ns = 0
    if len(v) > 2:
        um = float(v[2])
    else:
        um = 0.0
 
    # Lecture du fichier initial
    # qui contient une date 'jj/mm/aaaa hh:mm:ss'
    try:
        fi = open(dateInitiale, 'r')
        zi = fi.read()
        fi.close()
    except:
        print "Erreur : le fichier '" + dateInitiale + "' ne peut pas etre lu !"
        sys.exit(1)
 
    if zi[-1] == '\n':
        zi = zi[0:-1]
    ti = time.strptime(zi, '%d/%m/%Y %H:%M:%S')
    if not stop:
        print "Date initiale         : " + zi
 
    # durées totale, cumulée, nombre de sessions (ou boots) et durée max
    t = time.time()
    dureeTotale = t  - time.mktime(ti)
    cumulDuree = tc + (t  - time.mktime(tb))
    ns += 1
    if (t  - time.mktime(tb)) > um:
        um = (t  - time.mktime(tb))
 
    # listage des valeurs courantes
    if not stop:
        print "Nombre total de boots : %i" %(ns)
        print "Duree totale          : %.0f secondes, soit %s" %(dureeTotale, zDuree(dureeTotale))
        print "Duree active courante : %.0f secondes, soit %s" %(t  - time.mktime(tb), zDuree(t  - time.mktime(tb)))
        m = cumulDuree / ns
        print "Duree active moyenne  : %.0f secondes, soit %s" %(m, zDuree(m))
        print "Duree active maximale : %.0f secondes, soit %s" %(um, zDuree(um))
        p = 100.0 * cumulDuree / dureeTotale
        print "Duree active cumulee  : %.0f secondes, soit %s, ou %.2f" %(cumulDuree, zDuree(cumulDuree), p) + "% de la duree totale"
        dif = dureeTotale - cumulDuree
        p = 100.0 * dif / dureeTotale
        print "Duree inactive        : %.0f secondes, soit %s, ou %.2f" %(dif, zDuree(dif), p) + "% de la duree totale"
 
    if stop:
        # mise-à-jour du fichier de cumul
        fc = open(uptimeCumule, 'w')
        fc.write(str(cumulDuree) + ' ' + str(ns) + ' ' + str(um) + '\n')
        fc.close()
 
    sys.exit(0)

Intégration dans le système

Pour intégrer le script au niveau du boot et de l'arrêt du système on peut créer un script Système /etc/init.d/uptime2 contenant :

#!/bin/sh
#
# chkconfig: 2345 99 09
# description: uptime2 est un outil de mesure des durees d'activite du systeme
#
 
# Librairie de fonctions
. /etc/rc.d/init.d/functions
 
SYSCONF_FILE=/var/lock/subsys/uptime2
 
case $1 in
    start)
        /usr/bin/python /usr/local/bin/uptime2 start
        touch $SYSCONF_FILE
        ;;
    stop)
        if [ -f $SYSCONF_FILE ]
        then
            /usr/bin/python /usr/local/bin/uptime2 stop
            rm -f $SYSCONF_FILE
        else
            gprintf "uptime2 n'est pas en service\n"
            exit 1
        fi
        ;;
    status)
        if [ -f $SYSCONF_FILE ]
        then
            gprintf "uptime2 est en service\n"
        else
            gprintf "uptime2 n'est pas en service\n"
        fi
        ;;
    restart)
        $0 stop
        sleep 1
        $0 start
        ;;
    *)
        gprintf "Usage: %s\n" "$(basename $0) {start|stop|status|restart}"
        exit 1
        ;;
esac

On l'installe ensuite par la commande :

chkconfig --add uptime2

Ces manips vont lancer le script à chaque boot aux niveaux d'exécution 2 à 5 (5 est le plus courant pour les utilisateurs), et pour l'arrêt quand le système passe au niveau d'exécution 6. Uptime2 est ainsi vu comme un véritable service système; dans une Mandriva il apparaîtra par exemple dans la liste des services au niveau du CCM.

Remarque : Le dossier du fichier de boot (un des 3 fichiers nécessaires au fonctionnement d'uptime2), ici /usr/local/uptime2, est créé s'il n'existait pas. On a intérêt à déclarer les 3 fichiers de données nécessaires à l'outil dans ce même dossier, qui devra éventuellement être créé manuellement si la tentative de création automatique échouait.

Normalement au 1er reboot du système les 3 fichiers nécessaires à l'outil seront créés, la date initiale étant une fois pour toutes mise à la date de ce reboot. On peut aussi créer les 3 fichiers en lançant uptime2 une première fois en root. On pourra ensuite, de préférence après un reboot, lancer uptime2 en mode root ou utilisateur, sans paramètres, pour vérifier que ça fonctionne; on vérifiera notamment que le compteur de boot s'incrémente de 1 à chaque fois.

;-)

comptabiliser_le_temps_d_activite_du_systeme.txt · Dernière modification : 2025/02/17 09:52 de 127.0.0.1