El blog de Pelin
Rinconcito del FLOSS
lunes, 2 de marzo de 2009
Ni ellos se quieren!
Ellos mismos bloquean los mails provenientes de Microsoft jajajajaja.
son geniales!
martes, 25 de noviembre de 2008
Usando Trpr (TRace Plot Real-time)
martes, 11 de noviembre de 2008
Acelerando el Booteo
La herramienta en cuestion es bootchart
El proceso de instalacion en ubuntu no fue mas que:
pelin@valkyria:~$ sudo apt-get install bootchart
Una vez instalado reinicio la pc. Genera los graficos y los guarda en /var/log/bootchart con la fecha y hora.
En el siguiente intento, depues de dar de baja algunas cosas que no utilizaba mejoro un poco y obtuve el grafico siguiente:
Mejora sustancial, decido una vez bajar algunas otras cosas y obtengo:
Listado de servicios que di de baja:
- apache2 (cuando necesite el web server lo levanto)
- nvidia-kernel (no se que hace instalado si no tengo esa placa de video...pero es parte del kernel :( )
- vboxdrv (virtualbox)
- apparmor
- cupsys (cuando quiera imprimir lo arranco y listo)
- avahi-daemon (solo tengo dos pc's en mi casa, no lo necesito)
- clamav-freshclam (actualizacion de la base de datos de clamav)
- vmware (cuando necesite levantar las maquinas virtuales lo arranco)
- motion
- winbind
- y le saque la opcion splash del grub
2. Run boot processes in parallel
This will make upstart to run the boot processes in parallel and speed up the boot process.
sudo kate /etc/init.d/rc
Find and change the line:
CONCURRENCY=none
to:
CONCURRENCY=shell
6. Swappiness
The default value for vm.swappiness is 60 in Ubuntu Feisty whic is a good default value but if you want to tweak the performance a little bit more you can change this value to a lower value to reduce the load of the swap. If you run the follwing command:
sysctl -q vm.swappiness
You will se that the value is set to 60. And by running:
sudo sysctl vm.swappiness=10
You will change the value from 60 to 10 which will make your system write to swap a lot less and I would recommend this to everyone that has 512 mb of memory or more. If you find that you have very little use of swap set the value to 0. This will not disable the swap but it will make your system write to the swap as little as possible and keep as much as possible in memory. This makes a huge improvment when switching between applications since they are now likley to be in physical ram instead of on the swap partition.
To set your value permanent you need to change the sysctl.conf file:
sudo kate /etc/sysctl.conf
Add the line
vm.swappiness=10
To the end of the file. This way it will be set upon boot.
I’ve found that the value of 5 works very good for my use and I have 1 GB of memory.
En mi caso esa entrada no existia, asi que la agregue y setee el valor a 5.Por ahi encontre que la herramienta sysv-rc-conf ayudaria, pero solo es una interfaz ncurses para dar de baja demonios que arrancan con el sistema.
Para probarlo basta con
sudo apt-get install sysv-rc-conf
sudo sysv-rc-conf
Reinicio la pc y obtuve una leve mejora con la cual me quedo tranquilo.
Pero ojo!, hasta que obtengo mi escritorio totalmente cargado pasan casi 85 segundos.
Cuando ya se ha encontrado la configuracion optima se puede deshabilitar el bootchart con el comando:
sudo update-rc -f stop-bootchart remove
lunes, 10 de noviembre de 2008
Auditoria en PostgreSQL
Estrictamente hablando son una serie de triggers, que al ejecutarse un cambio sobre un registro almacena el valor anterior del registro, el nuevo valor, la hora a la que se realizo el cambio y el usuario de la base de datos. en mi caso tenemos un sistema web y la captura del usuario de la aplicacion es bastante engorroso.
La solucion encontrada fue generar una tabla de transacciones en la cual se almacena un numero de transaccion, el nombre de usuario y la tabla sobre la cual se realizo la transaccion. En cada tabla a ser auditada se la agrega un campo al final llamado nro_transaccion. Cuando se va a realizar un cambio en algun registro primero se escribe en la tabla transaccion, luego en la tabla propiamente dicha y finalmente el trigger escribe en la tabla de auditoria.
Los siguentes scripts son una mezcla partiendo del script que figura en la documentacion de PostgreSQL, agregados mios y finalmente mi amigo Luis Escobar creo las funciones para automatizar el proceso de agregar tablas a auditar.
1) Crear la base de datos de prueba:
postgres=# CREATE DATABASE "pruebaAudit" postgres-# WITH ENCODING='SQL_ASCII'; CREATE DATABASE postgres=# COMMENT ON DATABASE "pruebaAudit" IS 'Base de datos de prueba para auditoria'; COMMENT
2) Crear el esquema:
postgres=# \c pruebaAudit
You are now connected to database "pruebaAudit".
pruebaAudit=# create schema auditoria;
CREATE SCHEMA
3) Crear las tablas
Tabla personal:
pruebaAudit=# CREATE TABLE personal
pruebaAudit-# (
pruebaAudit(# idper bigserial NOT NULL,
pruebaAudit(# perdom character varying(100) NOT NULL,
pruebaAudit(# percuil character varying(11) NOT NULL,
pruebaAudit(# persex character varying(1) NOT NULL,
perdocnro character varying(10) NOT NULL,
pertelcel character varying(50) NOT NULL,
pruebaAudit(# perfchnac date,
pruebaAudit(# perdoctip character varying(4) NOT NULL,
pruebaAudit(# perdocnro character varying(10) NOT NULL,
pruebaAudit(# pertelcel character varying(50) NOT NULL,
pruebaAudit(# peremail character varying(50) NOT NULL,
pruebaAudit(# perape character varying(40) NOT NULL,
pruebaAudit(# pernom character varying(40) NOT NULL,
pruebaAudit(# eliminado smallint,
pruebaAudit(# CONSTRAINT personal_pkey PRIMARY KEY (idper)
pruebaAudit(# )
pruebaAudit-# WITH (OIDS=FALSE);
NOTICE: CREATE TABLE creará una secuencia implícita «personal_idper_seq» para la columna serial «personal.idper»
NOTICE: CREATE TABLE / PRIMARY KEY creará el índice implícito «personal_pkey» para la tabla «personal»
CREATE TABLE
Tabla usuario
pruebaAudit=# CREATE TABLE usuario
pruebaAudit-# (
pruebaAudit(# idusu smallint NOT NULL,
pruebaAudit(# nomusu character varying(20) NOT NULL,
pruebaAudit(# passusu character varying(50) NOT NULL,
pruebaAudit(# idper bigint NOT NULL,
pruebaAudit(# eliminado smallint,
pruebaAudit(# codusu character varying(20) NOT NULL,
pruebaAudit(# CONSTRAINT codusu_pkey PRIMARY KEY (codusu),
pruebaAudit(# CONSTRAINT usuario_idper_fkey FOREIGN KEY (idper)
pruebaAudit(# REFERENCES personal (idper) MATCH SIMPLE
pruebaAudit(# ON UPDATE NO ACTION ON DELETE NO ACTION
pruebaAudit(# )
pruebaAudit-# WITH (OIDS=FALSE);
NOTICE: CREATE TABLE / PRIMARY KEY creará el índice implícito «codusu_pkey» para la tabla «usuario»
CREATE TABLE
4) Creacion de las tablas necesarias para la auditoria
pruebaAudit=# CREATE TABLE "auditoria".infseg (
pruebaAudit(# nombtabla varchar(150) NOT NULL,
pruebaAudit(# esquema varchar(60) NOT NULL,
pruebaAudit(# activar boolean DEFAULT false,
pruebaAudit(# version smallint DEFAULT 1,
pruebaAudit(# fechageneracion timestamp WITHOUT TIME ZONE DEFAULT now(),
pruebaAudit(# fechaactivacion timestamp WITHOUT TIME ZONE,
pruebaAudit(# hastrigg boolean,
pruebaAudit(# /* Keys */
pruebaAudit(# -- CONSTRAINT infseg_pkey
pruebaAudit(# PRIMARY KEY (nombtabla)
pruebaAudit(# ) WITH (
pruebaAudit(# OIDS = FALSE
pruebaAudit(# );
NOTICE: CREATE TABLE / PRIMARY KEY creará el índice implícito «infseg_pkey» para la tabla «infseg»
CREATE TABLE
Insertamos datos:
busca las tablas que estan en el esquema public y las inserta en la tabla infoseg.
pruebaAudit=# INSERT INTO "auditoria".infseg
pruebaAudit-# (nombtabla
pruebaAudit(# , esquema
pruebaAudit(# , version
pruebaAudit(# , hastrigg)
pruebaAudit-# select pgtb.tablename
pruebaAudit-# , pgtb.schemaname
pruebaAudit-# , 1
pruebaAudit-# , pgtb.hastriggers
pruebaAudit-# from pg_tables pgtb
pruebaAudit-# where pgtb.schemaname like 'public'
pruebaAudit-# ;
INSERT 0 2
5) Crear las funciones:
esta funcion la creo desde la herramienta de SQL del PgAdmin
CREATE OR REPLACE FUNCTION public.CrearTrigger
(
nombretabla text,
esquema text,
db text
)
RETURNS text AS
$$
DECLARE QQ text;
BEGIN
QQ := 'CREATE OR REPLACE FUNCTION ' || nombretabla || '_trigAUTO()
RETURNS trigger AS
$BODY$
DECLARE rows_affected INTEGER;
BEGIN IF TG_OP =''INSERT'' THEN
INSERT INTO "auditoria".' || nombretabla || ' (accion, newmovimiento,consulta)
SELECT TG_OP , NEW , current_query
FROM pg_stat_activity
WHERE datname=''' || db ||''' AND current_query <> ''
ELSIF TG_OP =''UPDATE'' THEN
INSERT INTO "auditoria".' || nombretabla || ' (accion, oldmovimiento,
SELECT TG_OP ,OLD ,NEW , current_query
FROM pg_stat_activity
WHERE datname='''|| db ||''' AND current_query <> ''
ELSIF TG_OP =''DELETE'' THEN
INSERT INTO "auditoria".' || nombretabla || ' (accion,oldmovimiento ,consulta)
SELECT TG_OP ,OLD , current_query
FROM pg_stat_activity
WHERE datname=''' || db ||''' AND current_query <> ''
RAISE EXCEPTION ''TG_OP % es uno de INSERT, UPDATE or DELETE.'', TG_OP;
GET DIAGNOSTICS rows_affected = ROW_COUNT;
IF rows_affected = 1 THEN
IF TG_OP IN (''INSERT'',''UPDATE'') THEN
RETURN NEW;
ELSE
RETURN OLD;
END IF;
ELSE RAISE EXCEPTION ''Fallo el insert en auditoria.|| nombretabla ||'';
END;
$BODY$
LANGUAGE ''plpgsql'' VOLATILE STRICT;
CREATE TRIGGER tg_' || esquema || '_' || nombretabla || '
AFTER INSERT OR UPDATE OR DELETE ON '|| nombretabla || '
FOR EACH ROW EXECUTE PROCEDURE public.' || nombretabla || '_trigauto();'
;
RETURN QQ;
$$
LANGUAGE 'plpgsql'
VOLATILE
RETURNS NULL ON NULL INPUT
CREATE OR REPLACE FUNCTION createTablesSeguimiento
( nombtabla text,
esquema text,
db text
)
RETURNS VOID AS
$body$
DECLARE QQ text;
BEGIN
QQ:= 'DROP TABLE IF EXISTS "auditoria". ' || nombtabla || ';
CREATE TABLE "auditoria".' || nombtabla || ' (
idmovimiento serial NOT NULL,
usuariodb text NOT NULL DEFAULT "current_user"(),
accion text NOT NULL,
acciontimestamp timestamp WITH TIME ZONE NOT NULL DEFAULT now(),
oldmovimiento ' || esquema ||'.' || nombtabla || ',
newmovimiento ' || esquema ||'.' || nombtabla || ',
consulta varchar
/* Keys */
CONSTRAINT ' || nombtabla || '_pkey
PRIMARY KEY (idmovimiento),
/* Checks */
CONSTRAINT ' || nombtabla || '_check CHECK (accion = ANY (ARRAY[''INSERT''::text, ''UPDATE''::text, ''DELETE''::text]))
) ;
ALTER TABLE "auditoria".' || nombtabla || '
OWNER TO postgres;';
EXECUTE QQ;
execute public.CrearTrigger(nombtabla,esquema,db);
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
;
6) Ahora vemos como quedo todo:
Esto funciona de la siguiente manera:
a) Desde el PgAdmin se hace click con el boton derecho sobre la tabla infoseg -> Ver datos -> Ver todas las filas lo cual me muestra todas las tablas del esquema public.
b) El campo Activar esta seteado a FALSE, se hace doble click sobre el de manera que se abre un checkbox; se lo tilda de manera que quede en TRUE y se guardan los cambios.
c) Posteriomente se ejecuta el siguiente script
SELECT sinf.nombtabla ,sinf.esquema ,createTablesSeguimiento(sinf.nombtabla,sinf.esquema,'pruebaAudit')
FROM "auditoria".infseg sinf WHERE sinf.activar
El mismo crea las tablas en el esquema auditoria y los triggers en el esquema public.
Vemos como ha quedado:
Ahora solo quedan insertar algunos valores en las tablas usuario y personal y ver como se almacenan en las tablas correspondientes en el esquema auditoria.
Bueno, a cargar datos!
Cargo dos registros en la tabla personal
pruebaAudit=# INSERT INTO personal (idper, perdom, percuil, persex, perfchnac, perdoctip, perdocnro, pertelcel, peremail, perape, pernom, eliminado) VALUES (18, 'mi panza', '5634', 'M', '1976-07-20', 'DNI', '34563', '453', 'sdfgq@adfv.vom', 'Espinosa ', 'Agustin', 0); INSERT 0 1
pruebaAudit=# INSERT INTO personal (idper, perdom, percuil, persex, perfchnac, perdoctip, perdocnro, pertelcel, peremail, perape, pernom, eliminado) VALUES (31, 'adgasdgf', '252525253', 'M', '1972-02-07', 'DNI', '1315351321', '3456456', '3456356356@cksdf.com', 'yo ', 'dfgsdgf', 0);
INSERT 0 1
pruebaAudit=# select * from personal; idper | perdom | percuil | persex | perfchnac | perdoctip | perdocnro | pertelcel | peremail | perape | pernom | eliminado
-------+----------+-----------+--------+------------+-----------+------------+-----------+----------------------+-------------------------------+---------+-----------
18 | mi panza | 5634 | M | 20/07/1976 | DNI | 34563 | 453 | sdfgq@adfv.vom | Espinosa | Agustin | 0
31 | adgasdgf | 252525253 | M | 07/02/1972 | DNI | 1315351321 | 3456456 | 3456356356@cksdf.com | yo | dfgsdgf | 0
(2 rows)
Ahora verifico en la tabla personal del esquema auditoria.
pruebaAudit=# select * from auditoria.personal; idmovimiento | usuariodb | accion | acciontimestamp | oldmovimiento | newmovimiento | consulta --------------+-----------+--------+-----------------------------+---------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1 | postgres | INSERT | 10/11/2008 17:09:47 GMT | | (18,"mi panza",5634,M,20/07/1976,DNI,34563,453,sdfgq@adfv.vom,"Espinosa ",Agustin,0) | INSERT INTO personal (idper, perdom, percuil, persex, perfchnac, perdoctip, perdocnro, pertelcel, peremail, perape, pernom, eliminado) VALUES (18, 'mi panza', '5634', 'M', '1976-07-20', 'DNI', '34563', '453', 'sdfgq@adfv.vom', 'Espinosa ', 'Agustin', 0); 2 | postgres | INSERT | 10/11/2008 17:10:38.171 GMT | | (31,adgasdgf,252525253,M,07/02/1972,DNI,1315351321,3456456,3456356356@cksdf.com,"yo ",dfgsdgf,0) | INSERT INTO personal (idper, perdom, percuil, persex, perfchnac, perdoctip, perdocnro, pertelcel, peremail, perape, pernom, eliminado) VALUES (31, 'adgasdgf', '252525253', 'M', '1972-02-07', 'DNI', '1315351321', '3456456', '3456356356@cksdf.com', 'yo ', 'dfgsdgf', 0); (2 rows)
o mejor visto desde el PgAdmin:
con esto esta demostrado que funciona.
Esto tiene algunos inconvenientes...nada es perfecto!!:
1) Si se quieren agregar mas tablas a auditar se debe ejecutar por cada tabla:
select createtablesseguimiento('nombre-tabla','public','pruebaAudit');
2) Si no se controlan bien las tablas a auditar se agrega mucha carga al servidor
3) Para poder sacar informacion util se debe trabajar con expresiones regulares y demas cosas bellas :)
domingo, 2 de noviembre de 2008
Stallman en Asuncion 08
Ellos fueron a un hotel mientras yo me quede en la Embajada Argentina, donde tenia alojamiento..pero al final dormi en el hotel :p. En la Embajada Argentina me encontre con Matias y el jueves llego Josi.
La conferencia se llevo a cabo en el Salon de Conferencias del Banco del Paraguay en un auditorio enorme, aun asi se ocuparon todos los asientos, los pasillos y habilitaron un salon adjunto en el que instalaron pantallas gigantes para seguir la conferencia....pero la verdad no se si alguien haya ido alli ya que no tiene gracia ir a "verlo" a Stallaman a traves de una pantalla, cuando podes escucharlo a el a 15 metros.
Como dije hubo muchisima gente, muchos de los cuales solo fueron porque les habran pedido...pero bueno.
Me sorprendio que varias personas tenian en su poder OLPC's, cuando les pregunte me dijeron que eran del Ministerio de Educacion, que se estaban capacitando en su uso para poder capacitar despues a los docentes...buenisimo!.
Al terminar su conferencia se dio la posibilidad al publico que le haga preguntas; las primeras fueron or escrito, algunas habladas pero de esas muchas le dieron problemas a Stallman ya que se debe hablarle fuerte y claro, pero los hermanos paraguayos no pronuncian muy claramente las palabras al hablar. Alla nos encontramos con mi amigo Topo que fue con Lucho Beltran, el cual le hizo saber a Stallaman de la exitosa implementacion de SL en el Poder Judicial de Formosa.
Juanma, guillermo y agustin pudieron hacerle preguntas.
Despues del evento, fuimos a cenar en un bar que esta frente al Panteon de los Heroes. El viernes paseamos un rato por el centro de la ciudad y nos volvimos para Resistencia.
Aca esta en enlace con algunas fotos
http://picasaweb.google.com/pelin.01/RMSAsuncion08#