Usando Log4Net, una manera rapida

En algunas situaciones, necesitamos implementar rapidamente un mecanismo de trazabilidad o instrumentacion que escriba en un archivo, en otras palabras un log, en mi caso uso bastante Log4Net y varias personas de tiempo en tiempo me preguntan como usarlo en proyectos we. Aunque hay varios ejemplos, articulos y codigo en internet para tal fin, muchos de ellos dan muchas vueltas sobre el tema antes de mostrarlo concretamente, es mi objetivo en este post mostrar como habilitar log4net en unos sencillos pasos a seguir:

Pasos a seguir

1. Descarga Log4Net, preferiblemente usando Nuget

2. Modificar el archivo web.config, agregando las secciones que muestro en las siguientes capturas de pantalla, he utilizado dos capturas en un archivo bastante lago, para que al ver la captura sepan donde insertalas.

Log4Net-1

En la segunda captura de pantalla que muestro a continuacion, he señalado dos puntos importantes de la configuracion. El primero es el nivel de trazabilidad que se requiere, esto se refiere a cuanta informacion queremos obtener en el log, hare un post separado para este tema y el segundo es el nombre del archivo de log que se generara.

Log4Net-2

3. Para utilizar Log4Net, yo utilizo una variacion mas elaborada de esta clase (Logger). La funcion de esta clase es dar acceso a metodos de Log4Net, formateando previamente el texto y tambien instanciar de manera simple el logger.

public static class Logger
    {
        #region Fields

        private static readonly ILog mLog = LogManager.GetLogger(typeof(Logger));

        #endregion Fields

        #region Constructor

        static Logger()
        {
            Debug.WriteLine("Server Logger initializing...");

            log4net.Config.XmlConfigurator.Configure();

            if (mLog != null)
            {
                Debug.WriteLine("Server Logger initialized");
                Debug.WriteLine(string.Format("Debug: {0}, Error: {1}, Info: {2}, Warning {3}", 
mLog.IsDebugEnabled, mLog.IsErrorEnabled, mLog.IsInfoEnabled, mLog.IsWarnEnabled));
            }
            else
            {
                Debug.WriteLine("Failed initializing Server Logger");
            }

        }

        #endregion Constructor

        #region Public Methods

        public static void PublishException(Exception exception)
        {
            if (mLog != null)
                mLog.Error("Exception", exception);
        }

        public static void WriteVerbose(string category, string message)
        {
            if (mLog != null)
                mLog.Debug(FormatMessage(category, message));
        }

        public static void WriteInfo(string category, string message)
        {
            if (mLog != null)
                mLog.Info(FormatMessage(category, message));
        }

        public static void WriteWarning(string category, string message)
        {
            if (mLog != null)
                mLog.Warn(FormatMessage(category, message));
        }

        public static void TraceError(string category, string message)
        {
            if (mLog != null)
                mLog.Error(FormatMessage(category, message));
        }

        public static void Write(TraceLevel level, string category, string message)
        {
            switch (level)
            {
                case TraceLevel.Verbose:
                    WriteVerbose(category, message);
                    break;
                case TraceLevel.Info:
                    WriteInfo(category, message);
                    break;
                case TraceLevel.Warning:
                    WriteWarning(category, message);
                    break;
                case TraceLevel.Error:
                    TraceError(category, message);
                    break;
            }
        }

        #endregion Public Methods

        #region Private Methods

        private const string MessageFormat = "{0} | {1}";
        private const int MaxCategoryNameLength = 25;

        private static string FormatMessage(string category, string message)
        {
            string output = string.Format(MessageFormat, FormatName(category, 
MaxCategoryNameLength), message);
            return output;
        }

        private static string FormatName(string name, int minLength)
        {
            string result;
            string trimName = name != null ? name.Trim() : string.Empty;
            if (trimName.Length >= minLength)
                result = trimName;
            else
                result = trimName.PadRight(minLength);
            return result;
        }
        #endregion Private Methods
    }

4. Finalmente para utilizar la clase, simplemente realizamos invocaciones a los metodos estaticos de la clase Logger, por ejemplo:

Logger.WriteInfo (“Categoria”,”Mensaje…..”);

 

Consideraciones

  • El Log del ejemplo que les presento, se escribira en la carpeta raiz de la aplicacion web, no es la mejor practica, lo mas recomendable es crear una carpeta especial para guardar los logs.
  • La carpeta donde se escriban estos logs, deben tener los permisos adecuados para el usuario sobre el que corre el proceso de IIS, en caso de Windows 2008, podria ser “Network Services”, pero puede variar dependiendo de su sistema operativo, es comun tener muchos problemas por este punto.
  • Esta forma de escribir el log es adecuada para una aplicacion aislada pero para aplicaciones distribuidas puede llegar a convertirse en un dolor de cabeza recolectar cientos de archivos dispersos en varias ubicaciones, lo ideal es guardar esta informacion centralizadamente, probablemente en una base de datos, ultimamente estoy experimentando (en un proyecto fuera de la oficina) con MongoDB y es bastante rapido, obviamente lanzo el log en un proceso asincronico que no bloquea la aplicacion, este tambien es tema de una futura entrada.

Espero que esto les haya sido de utilidad.

Usando JSONP con Ajax, de una manera rapida

Aquellos que nos hemos enfrentado varias veces al mensaje de “XMLHttpRequest cannot load http://192.168.1.109/settings/get. Origin http://localhost:8888 is not allowed by Access-Control-Allow-Origin”, pueden reconocer inmediatamente el problema relacionado al Cross-Domain. El problema en terminos simples se relaciona a que un sitio en un dominio X, por razones de seguridad, no puede acceder mediante ajax o incluso sockets a otro dominio Y. En nuestro caso el sitio X es http://localhost:8888 y el sitio Y que contiene el servicio es http://192.168.1.109/settings/get, este es un problema bastante comun y Eduard Tomas lo explica magistralmente en una reciente entrada

Eduard muestra la solucion utilizada en .NET haciendo uso de los MediaTypeFormatters, este mecanismo explicado hace practicamente transparente el procesamiento de las peticiones con jsonp, considero que es una solucion elegante y tambien muestra en el mismo articulo la solucion mas apropiada, que es la utilizacion de CORS.

Entonces que hago yo ‘escribiendo’ sobre JSONP?, pues es solo exponer mi experiencia y un workaround que utilice en algun momento antes de la aparicion de CORS y de decirle adios definitivamente a JSONP, bueno no tan definitivamente :). Empecemos.

Lado del Servidor

El ‘secreto’ de usar JSONP y Ajax, es el famoso callback en el que se encierra los datos retornados por el servidor.

En .NET la idea es tener un metodo en el controlador que devuelva lo siguiente:

image

En NodeJs, se tiene un similar metodo usando Express, debo advertir que con NodeJs se requiere un poco mas de configuracion, me refiero al codigo que anda por alrededor del app.get y seria lo siguiente:

image

Lado del Cliente

Hasta aqui tenemos la mitad del camino recorrido, la otra mitad se encuentra en el cliente/browser, donde se invoca al servicio REST, de la siguiente manera:

image

La url no es un tema muy relevante, porque depende del servicio al que se invoque, los elementos importantes son el datatype, que especifica el parametro jsonp y finalmente el otro atributo llamado jsonpCallback, que debe contener el nombre exacto de la funcion en la que se envolvio el resultante json.

Consideraciones

Este workaround solamente funciona en proyectos MVC y no en MVC WebApi, los proyectos WebApi justamente usan el mecanismo explicado por Eduard ese o CORS.

Este es un mecanismo inseguro, por lo que solamente deben usarlo en caso de tener que necesiten hacer alguna prueba de concepto rapidamete, es util, luego es mejor usar CORS.

Agradecer a un amigo, Yecid que me ayudo a encontrar este mecanismo.

Saludos

Microsoft cuidado, los vientos de cambio ya estan aqui.

Las personas que me conocen, pueden dar testimonio que mi carrera ha estado enmarcada por un apego inquebrantable hacia la filosofia de desarrollo .NET, practicamente todas las soluciones profesionales y personales en las que he participado tienen esa marca. Este post no pretende cambiar aquello ni mucho menos, tan solo son un conjunto de opiniones en un dia feriado en mi pais.

Hace algun tiempo me preguntaba cual era la razon de la popularidad creciente de dispositivos con el sistema operativo Android y no fue hasta que tuve recientemente, en mis manos uno de los buques insignia de google, el Nexus 10, que pude comprender la verdad (desde mi punto de vista). Ya se que habra algunos que estaran diciendo que mi primera eleccion deberia haber sido Surface o similares productos y no miento al decirles que en los primeros dias que tuve la Nexus 10, la tentacion fue grande para reemplazarla, pero no lo hice, pues uno de los objetivos de comprarla fue que planeo desarrollar una aplicacion para esta plataforma. Nuevamente muchos pueden comentar que porque para Android, que si deberia haberlo hecho para Windows 8 primero… etc, la respuesta corta, ya tengo una aplicacion para Windows Phone, tambien para Windows 8 y el siguiente mercado para ella es Android, solo cuestion de negocios.

image

El tema de este post no es cuan complicado o simple es migrar la aplicacion, o quiza las equivalencias en desarrollo entre ambas plataformas, esos temas los tocare en otras entradas, el tema central aqui es una cuestion mas ‘filosofica’, que tiene que ver con la experiencia y el porque de las cosas, comencemos.

imageLa Nexus 10, es de por lejos probablemente la mejor tablet Android, hasta el momento, esta bien….le quitaremos algunos defectos, que algunos le puede ver, no tiene ranura de expansion y el cargado de la bateria es un dolor de cabeza, pues carga leeeeeeeentamente, supongo que sera solucionado en futuras actualizaciones del firmware, espero. Aparte de ellos tiene un procesador A15 de doble nucleo, 2GB de RAM y ni que decir de la calidad de la pantalla, con una resolucion de 2560 x 1600, la calidad es inmejorable, por ahora. Estas caracteristicas la convierte en un hardware envidiable para casi todas las tablets con Windows 8 RT. Pero mas importante que el hardware es como se siente Android, pues es la primera vez que tengo un dispositivo con este sistema operativo y aunque he escuchado muchas opiniones y comentarios, que mejor que vivir la experiencia uno mismo.

image

El sistema operativo es el Android 4.2 Jeally Bean, la ultima version del mismo, no puedo opinar de versiones anteriores, esta es bastante ‘amigable’, no demore ni 5 minutos en entender todos los conceptos, pero ahora vienen las criticas, hasta el momento he tenido que reiniciar la tablet unas 4 o 5 veces en aproximadamente 2 semanas de uso regular, algunas aplicaciones se congelan misteriosamente y aunque el procesador es uno de los mas rapidos del mercado, la fluidez de varias aplicaciones dejan mucho que desear, se nota el odiado retardo al hacer flip o navegar, debo admitir que algunas aplicaciones propias de google son impresionantemente rapidas y fluidas a diferencia de las muchas. Existen todo tipo de aplicaciones, para todos los gustos, casi ninguna de ellas mantiene un estilo ‘look & feel’ uniforme, cada una pone las barras donde les parece, usan colores que les apetece, no existe una consistencia en el entorno y aunque no es complicado ‘descubrir’ como usar una aplicacion cada vez, aqui empiezo extra;ar Windows 8 o Windows Phone. Pero si hay tantos ‘reparos’ que un usuario Windows ve, porque Android es tan ampliamente aceptado?

  • Un punto fuerte es la estrategia de distribucion que Google ha adoptado, tiene cientos por no decir miles de socios que fabrican hardware de los mas distintos sabores/precios, en mi pais se puede encontrar una tablet con prestaciones decentes sino suficientes con Android 4.0 por 100 Dolares Americanos!
  • A la amplia aparicion de ‘novedades’ se suma el conformismo de millones de usuarios ante los problemas de congelamiento o reinicio. En las descripciones de muchas aplicaciones, se puede leer descaradas sugerencias como: ‘Si tiene problemas desinstale y vuelva a instalar, existen problemas desconocido ocacionados por las actualizaciones’. Que nos dice esto? que los usuarios de Android ya han aceptado esos problemas como algo ‘natural’
  • Sumemos a esto el descuido de los programadores al momento de pensar en la experiencia del usuario y la practicamente falta de control por parte de google al momento de permitir la subida de aplicaciones al Google Play. Un amigo que es desarrollador de Android y iOS comenta que uno puede subir practicamente lo que quiera al Google Play y nadie te dice nada, es decir las normas por las que Microsoft se ‘pelea’ con el desarrollador, no son obstaculo con Android, a tal punto que amigos ya me han sugerido aplicaciones que increiblemente estan en el GooglePlay y que permiten descargar aplicaciones comerciales pirateadas!!!! Esto demuestra el grado de libertad/libertinaje que existe en esta plataforma.

Este ultimo punto no les recuerda algo familiar? Pues a mi si, me recuerda a Windows y es que en Windows uno puede hacer practicamente lo que desee. No sabemos si es que es por voluntad propia o por la imposibilidad de ejercer un mayor control, Microsoft ha dejado prosperar su plataforma apoyado en este punto, sea cual sea la respuesta, Google ha tomado muestra y esta creciendo considerablemente sostenido por cientos de miles de programadores que hacen lo que quieren 🙂 (son palabras fuertes), nadie les dice que reglas deben seguir (bueno hay reglas muy minimas), nadie o practicamente nadie controla lo que subes siempre que subas aplicaciones, a nadie parece preocuparle la dichosa fragmentacion de mercado ni tantas cosas que Microsoft pregona como ventajas de sus plataformas Windows. Ojo no estoy diciendo que Microsoft debe dar rienda suelta a semejante libertinaje, pero algo tiene que hacerse, una idea que anda circulando por ahi es comprar el proyecto Mono e integrarlo como una herramienta mas, permitiendo que todos nosotros, otros tantos cientos de miles, podamos tambien programar en Android usando C#, quiza esta ‘cura’ puede ser peor que la enfermedad.

Lo cierto es que los vientos de cambio ya estan aqui y Microsoft debe cuidarse no solo las espaldas, sino los costados, arriba y abajo, tomar desiciones equivocadas puede ser desastrozo pero no tomarlas puede ser aun mas catastrofico, en un horizonte cercano divisamos un mayor crecimiento de Android, tambien asoma su cabeza Chrome OS y aunque oficialmente no hay relacion entre Android y Chrome OS, se imaginan un potencial competidor economico a Windows pero en entornos de escritorio?

image

Microsoft tiene asegurado por un buen tiempo (no sabemos cuanto) el nicho empresarial, donde aun pocos confian en una tablet Android para integrarla en sus soluciones y tambien debido a que la integracion es pobre. Pero os aseguro que Google empezo por las tablets, va por el escritorio y seguramente ya tiene planes para entornos corporativos, sus timidos intentos con Google Doc y Drive, muestran una estrategia inicial, no se cuanto les resultara, dudo que mucho por el momento, pero quien sabe a mediano plazo.

Los desarrolladores por nuestra parte no podemos quedarnos con los brazos cruzados, podemos y debemos tomar cartas en el asunto, como? Primero abrazando estandares abiertos, HTML5 y CSS3 pero por sobre todo empezando un aprendizaje formal y conciencudo de Javascript. Este lenguaje anteriormente menos-preciado, hoy se perfila como la piedra que cimentara muchas grandes aplicaciones. Tampoco debemos despegarle un ojo a iniciativas de Google como Dart, que aunque son timidos intentos de monopolizar el desarrollo, no dejan de ser intentos, que vienen nada menos que de Google.

En resumen manteneos atentos mis amigos, que el futuro nos depara grandes sorpresas y desafios, que Steve Ballmer y Cia. no se equivoquen en sus desiciones pues miren que muchos andamos abordo del barco que guian.