14 abr 2011

Scripting People: Reciclado de logs

En general, los que nos dedicamos a los sistemas somos bastante perezosos a la hora de programar, aunque en principio hay un abismo entre programadores o picateclas e IT Pros o pelacables, existe una zona “oscura” para ambos mundos, que son los scripts.

¿Los tendrían que hacer los programadores sin conocimientos profundos de los sistemas o los IT Pros sin conocimientos profundos de programación?


En mi opinión, los IT Pros tenemos que ponernos las pilas y meterle caña al scripting,es muuuuy sencillo el crear un script para automatizar tareas repetitivas o complejas y no requiere grandes conocimientos de programación. Por esto mismo he decidido crear unas series “Scripting People” de ejemplos útiles en nuestra vida para resolver las tareas repetitivas, aburridas o complejas que voy encontrando en mi camino.


Esta vez os dejaré algo facilillo… Un script de reciclado de logs. ¿No os habéis encontrado con sistemas con un disco duro algo escaso y que generan tal cantidad de logs (o archivos) que nos llenan el disco duro y nos tenemos que pelar un montón de horas para solucionar el problema? Pues ahí va mi humilde solución…


Por cierto, no esperéis scripts con un alto nivel de complejidad de código, los explicaré todo lo que considere oportuno y seguro que hay una mejor forma de hacerlos, pero esta es la mía.


****************************************************************** 
' Scripting People - Reciclado de Logs
' by Oscar Marin
'(como habreis observado evito usar tildes y
' simbolos extranyos para que no hayan problemas
' de compatibilidad con nada)
' Definimos el Directorio de busqueda
path = "C:\programa_pesado\logs"

' Definimos la fecha de borrado de los ficheros
killdate = date() - 90

' La fecha seria, la actual menos 90 dias, es decir,
' borraremos los ficheros mas antiguos de 3 meses
' Definimos un patron de busqueda, por si hay logs
' con diferente nombre, en este caso borraremos los
' access-log-fecha.log (basta con definir un trozo
' unico en la cadena de busqueda)
patron = "access-"

' Inicializamos un array (un contenedor para meter objetos)
' que usaremos mas tarde
arFiles = Array()

' Creamos el objeto "Script"
' necesario en los scripts WSH(Windows Scripting Host)
set fso = CreateObject("Scripting.FileSystemObject")
 
' Primero tendremos que organizar los objetos (los ficheros del
' directorio) en un array y luego trabajar (borrar) con ellos,
' ya que es posible que el objeto FSO no nos los devuelva con el
' orden que esperamos

' Llamamos a la funcion "SelectFiles" que seleccionará los ficheros
' a borrar, es decir, los ficheros del path que hemos seleccionado
' que sean más antiguos de la fecha que hemos puesto y los metemos
' en un array.
' Mas abajo podreis ver concretamente que hace la funcion SelectFiles 
SelectFiles path, killdate, arFiles, false

' Inicializamos a 0 la variable que controla el numero de
' ficheros borrados
nDeleted = 0

' Y hacemos el bucle de borrado, desde 0, hasta el total de elementos
' que tenemos en el array (contenedor de ficheros a borrar)
for n = 0 to ubound(arFiles)

  '=================================================
  ' WARNING: Es importante saber que los  ficheros
' borrados con FSO (arFiles(n).delete) no van a la
' papelera de reciclaje, se eliminan directamente
  '=================================================

' Si hubiera un error, paso de el y me voy al siguiente elemento
' a procesar. Si no ponemos esta linea y hubiera un error, el
' script se detendria 
on error resume next

' Borramos cada fichero del array (no va a la papelera de reciclaje) 
arFiles(n).delete true

' Si hay un error de borrado, es decir, el codigo que devuelve
' es diferente de 0 (si es un 0 no hay error) 
if err.number <> 0 then

'Escribe en pantalla que no se puede borrar el fichero 
    wscript.echo "Unable to delete: " & arFiles(n).path

' si no
  else

' Aumentamos en 1 el contador de ficheros borrados
    nDeleted = nDeleted + 1
  end if
next

' Escribimos en pantalla el numero de ficheros eliminados 
wscript.echo nDeleted & " of " & ubound(arFiles)+1 _
  & " eligible files were deleted"
 
  '=================================================
  ' Enviamos el resultado por correo electronico:
  '=================================================

' Definimos el esquema necesario para el envio de correo  
sch = "http://schemas.microsoft.com/cdo/configuration/"

' Y creamos el objeto de la configuracion del envio de correo 
Set MsgConfig = CreateObject("CDO.Configuration")

' Configuramos los campos necesarios para el envio de correo 
With MsgConfig.Fields

' Podemos enviar el mensaje (cdoSendUsingPickup = 1) utilizando
' el SMTP local con el directorio de "pickup", o bien
' enviar el mensaje utilizando un SMTP externo (cdoSendUsingPort = 2)           
  .Item(sch & "sendusing") = 2  ' cdoSendUsingPort

' Definimos el servidor SMTP a utilizar
  .Item(sch & "smtpserver") = "smtp.contoso.com"

' Y grabamos las opciones 
  .update 
End With

' Creamos el objeto mensaje
Set Msg = CreateObject("CDO.Message")
 
With Msg

' Le aplicamos la configuracion anterior
     Set .Configuration = MsgConfig
' Y definimos los campos del mensaje en si 
       ' Campo Para
.To = "oscarintherocks@gmail.com"

' Campo De
       .From = "oscarintherocks@gmail.com"

' Campo asunto
       .Subject = "Hoy he borrado " & nDeleted & " logs"

' Y el cuerpo del mensaje
   .TextBody = "He borrado " & nDeleted & " de " & ubound(arFiles)+1 _
   & " ficheros susceptibles de borrado.  Estos ficheros son anteriores _
a la fecha " & vbCrLf & Killdate & vbCrLf & vbCrLf _
& "Los ficheros se han borrado de la siguiente carpeta: " _
& vbCrLf & path

' Por ultimo enviamos el mensaje 
.Send
        
End With

' ==================================
' Funciones... A continuacion vienen las funciones que utilizamos
' en el script mas arriba
' ==================================

' Funcion para seleccionar que ficheros borraremos y añadirlos al array
sub SelectFiles(sPath,vKillDate,arFilesToKill,bIncludeSubFolders)

' Como veis entre parentesis, le hemos pasado 4 parametros que
' utilizaremos dentro de la funcion

' Definimos el directorio con el Path que le hemos pasado a la funcion 
Set folder = fso.GetFolder(sPath)

' Definimos una variable con todos los ficheros del directorio
  Set files = folder.files

' Y para cada fichero
  for each file in files

' Buscamos el patron para hacer una primera seleccion de los ficheros 
if InStr(file, patron) Then

' Si contiene el patron
' Inicializamos la variable de la fecha de modificacion 
dtlastmodified = null

' Si se produce algun error seguiremos con el siguiente fichero
    on error resume Next

' Obtenemos la fecha de modificacion del fichero para pasarle el filtro
' de fecha
    dtlastmodified = file.datelastmodified
' Controlamos que no haya un error en la fecha y nos pete el script
    if not isnull(dtlastmodified) Then

' Si la fecha de modificacion es anterior a la fecha a partir
' de la cual queremos borrar ficheros
      if dtlastmodified < vKillDate then

' Anyadimos 1 al contador de ficheros a borrar
        count = ubound(arFilesToKill) + 1

' Ampliamos el array en 1 para meter el fichero que queremos borrar
        redim preserve arFilesToKill(count)

' Y metemos el fichero en el array, para despues borrar
' los ficheros del array completo
        set arFilesToKill(count) = file
      end if
    end if
   end if
  next

' Si en la funcion le hemos pasado un "true" en el cuarto parametro
' lo que haremos sera incluir los subdirectorios
if bIncludeSubFolders then

' por lo tanto para cada subdirectorio
    for each fldr in folder.subfolders

' Volvemos a llamar a la funcion que eliminara los ficheros a
' borrar recursivamente
      SelectFiles fldr.path,vKillDate,arFilesToKill,true
    next
  end if
end sub

******************************************************************


Pues esto es todo, con este script podreis hacer un reciclado de logs automático simplemente ejecutándolo diariamente en las tareas programadas. Por supuesto se puede adaptar a nuestras necesidades y mejorar todo lo que querais.

Espero que os sea útil.

No hay comentarios: