Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/monitor.py
diff options
context:
space:
mode:
Diffstat (limited to 'monitor.py')
-rw-r--r--monitor.py261
1 files changed, 261 insertions, 0 deletions
diff --git a/monitor.py b/monitor.py
new file mode 100644
index 0000000..7ae1266
--- /dev/null
+++ b/monitor.py
@@ -0,0 +1,261 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Logger Script
+#
+# Copyright (c) 2011 - Sebastian Silva <sebastian@somosazucar.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#from sugar.datastore import datastore
+#from sugar import profile
+import sys,csv,os,shutil
+from time import localtime, strftime, time, ctime, altzone, mktime, sleep
+from datetime import datetime
+from subprocess import Popen,PIPE,STDOUT
+try:
+ from sqlite3 import dbapi2 as sqlite
+except:
+ try:
+ from pysqlite2 import dbapi2 as sqlite
+ except:
+ print "Advertencia: Imposible encontrar bilbiotecas pysqlite."
+
+#######################################################
+
+def wait(time_lapse):
+ sleep(time_lapse)
+
+#def wait(time_lapse):
+# """ Implementa un "sleep timer" compatible con GTK """
+# time_start = time()
+# time_end = (time_start + time_lapse)
+#
+# while time_end > time():
+# while gtk.events_pending():
+# gtk.main_iteration()
+
+def execute_cmd(cmd):
+ """ Ejecuta un comando de la terminal y retorna el
+ output del comando.
+ """
+ p = Popen(cmd, shell=True, bufsize=0,
+ stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
+ (child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
+
+ return child_stdout_and_stderr.read()
+
+def _read_file(path):
+ """
+ Esta función lee y retorna el contenido
+ de archivos de texto
+ """
+ if os.access(path, os.R_OK) == 0:
+ return "n/d"
+
+ fd = open(path, 'r')
+ value = fd.read()
+ fd.close()
+ if value:
+ value = value.strip('\n')
+ return value
+ else:
+ print "Error leyendo "+path
+ return None
+
+class Data_general:
+ """
+ Obtenemos y almacenamos datos para registrar
+ """
+ def __init__(self):
+ self.retrieved = False
+ self.events = {}
+
+ def event(self, hora, texto):
+ try:
+ if self.events[hora]:
+ self.events[hora+1] = [ctime(hora), texto ]
+ except KeyError:
+ self.events[hora] = [ctime(hora), texto ]
+
+ def collect_logs(self):
+ """
+ recolecta la info de los logs de los historiales.
+ """
+ log_dir = os.environ['HOME']+"/.sugar/default/logs"
+ if not os.path.exists(log_dir):
+ log_dir = "/home/olpc/.sugar/default/logs"
+ if not os.path.exists(log_dir):
+ return None
+
+ # Navegar recursivamente los directorios de logs
+ stack = [log_dir]
+ mtime = 0
+ while stack:
+ directory = stack.pop()
+ for base in os.listdir(directory):
+ name = os.path.join(directory, base)
+ if os.path.isdir(name):
+ if not os.path.islink(name):
+ stack.append(name)
+ else:
+ mtime = os.path.getmtime(name)
+ creation_time = os.path.getctime(name)
+ # nota: creation time no es correcto pq los logs han sido movidos a subcarpetas
+ this_dir = os.path.split(os.path.dirname(name))[1]
+ if this_dir == "logs": #estamos mirando la sesión recien comenzada
+ this_dir = ""
+ if base == "shell.log":
+ pass
+ elif base == "datastore.log":
+ pass
+ elif base == "presenceservice.log":
+ pass
+ else:
+ self.event(mtime, "LOG: Ultima actividad en " + name)
+ else: #estamos mirando una sesión anterior
+ if base == "datastore.log":
+ pass
+ elif base == "presenceservice.log":
+ self.event(mtime, "LOG: *** %s - probable inicio de sesión" % name )
+ elif base == "shell.log":
+ self.event(mtime, "LOG: Ultima actividad en log de shell, posible fin de sesión: " + name)
+
+ else:
+ self.event(mtime, "LOG: Ultima actividad en " + name)
+
+ # Ahora vamos a iterar por todos los historiales de Navegador / Wikipedia
+ isolation_dir = "/home/olpc/isolation/1/gid_to_data_dir"
+ if not os.path.exists(isolation_dir):
+ isolation_dir = "/home/olpc/.sugar/default"
+ if not os.path.exists(isolation_dir):
+ print "Imposible encontrar directorio de los registros del navegador."
+ return None
+ stack = [isolation_dir]
+ while stack:
+ directory = stack.pop()
+ try:
+ subdirs = os.listdir(directory)
+ except:
+ subdirs = []
+ for base in subdirs:
+ name = os.path.join(directory, base)
+ if os.path.isdir(name):
+ if not os.path.islink(name):
+ stack.append(name)
+ else:
+ if base == "places.db":
+ shutil.copy (name, "/tmp")
+ tmpname = os.path.join("/tmp", base)
+ con = sqlite.connect(tmpname)
+ cur = con.cursor()
+ results = cur.execute ("select last_visit, uri, title, visits from places")
+ for r in results:
+ #item_timestamp = float(str(r[0])[:10])
+ item_timestamp = mktime(
+ datetime.strptime(r[0], "%Y-%m-%d %H:%M:%S.%f").timetuple())
+ if r[1][:27] == 'http://localhost:8000/wiki/':
+ self.event(item_timestamp, "WEB: (" + r[1] + ") - Articulo Wikipedia: " + r[1][27:] + " (vez %s)" % r[3])
+ elif r[1][:31] == 'http://localhost:8000/search?q=':
+ self.event(item_timestamp, "WEB: (" + r[1] + ") - Se busca en Wikipedia: " + r[1][31:] + " (vez %s)" % r[3])
+ elif r[1][:29] == 'http://localhost:8000/static/':
+ self.event(item_timestamp, "WEB: (" + r[1] + ") - Inicio de Wikipedia." + " (vez %s)" % r[3])
+ else:
+ self.event(item_timestamp, "WEB: Navega a: (" + r[1] + ") (vez %s)" % r[3])
+ con.close()
+ os.unlink(tmpname)
+
+ return True
+
+ def install_logger(self):
+ #copiamos el ejecutable
+ logdir = "/home/olpc/.logger"
+
+ if not os.path.exists(logdir):
+ execute_cmd("mkdir -p "+logdir)
+
+ logprog = os.path.join(logdir, "logger.py")
+ shutil.copy (sys.argv[0], logprog)
+
+ #lo hacemos autoiniciar
+ already_installed = False
+ xsession = "/home/olpc/.xsession"
+ if os.path.exists(xsession):
+ contents = _read_file(xsession)
+ for line in contents.splitlines():
+ if line == "python /home/olpc/.logger/logger.py &":
+ already_installed = True
+
+ if not already_installed:
+ execute_cmd("echo 'python /home/olpc/.logger/logger.py &' >> " + xsession)
+
+ def update_logger(self):
+ if self.collect_logs():
+ logdir = "/home/olpc/.logger"
+ logfile = "historial.csv"
+
+ logpath = os.path.join(logdir, logfile)
+
+ if not os.path.exists(logpath):
+ execute_cmd("mkdir -p "+logdir)
+ mtime = 0
+ else:
+ #Obtenemos la fecha de la ultima entrada en el log
+ lastlog = execute_cmd("tail -n1 "+logpath)
+ lastlog = lastlog.strip('\n')
+ try:
+ mtime = float(lastlog[-11:-1])
+ except:
+ mtime = 0
+
+ size = os.path.getsize(logpath)
+ # poor mans logrotate
+ if size>262144: #limit 256k
+ if os.path.exists(logpath+"-3"):
+ execute_cmd("mv "+logpath+"-3 "+logpath+"-4")
+ if os.path.exists(logpath+"-2"):
+ execute_cmd("mv "+logpath+"-2 "+logpath+"-3")
+ if os.path.exists(logpath+"-1"):
+ execute_cmd("mv "+logpath+"-1 "+logpath+"-2")
+ execute_cmd("mv "+logpath+" "+logpath+"-1")
+
+ s = os.statvfs(logdir)
+ free_disk_in_mb = (s.f_bsize * s.f_bavail)/(1024*1024)
+
+ if free_disk_in_mb > 30:
+ fd = open(logpath,"a")
+ writer = csv.writer(fd, dialect='excel')
+ for ev in sorted(self.events):
+ if ev > mtime:
+ writer.writerow(self.events[ev])
+ #print self.events[ev]
+ writer.writerow([ctime(time()), "LOGGER: Se actualizó registro de seguimiento *** " + str(int(time()))])
+ #print ctime() + " updated " + str(int(time()))
+ #print ctime(mtime) + " :last log " + str(int(mtime))
+ fd.close()
+ else:
+ print "Imposible cargar logs."
+
+
+# Aquí comienza la ejecución
+if os.path.split(sys.argv[0])[-1:][0]=='logger.py':
+ # Somos el sistema de seguimiento
+ dg = Data_general()
+ wait(30)
+ dg.update_logger()
+elif os.path.split(sys.argv[0])[-1:][0]=='instalar.py':
+ print "Instalador."
+ dg = Data_general()
+ dg.install_logger()
+ dg.update_logger()
+ print "Se ha instalado el programa de seguimiento."