none
Manejar Escritura en Archivo Log RRS feed

  • Pregunta

  • Estimados,

      Saludos a todos, espero que estén bien, les escribo porque estoy buscando la mejor solución para un problema que se me presento en producción, tengo un WebService en la capa de negocio, que por motivo de trabajo genera un Log de forma diaria de los llamados que recibe y sus procesos, hasta acá todo bien, el primer problema se nos presento hace un tiempo cuando aumento la cantidad de usuarios, nos reportaron inconvenientes en momentos de mucha demanda, cual fue nuestra sorpresa cuando encontramos que el error era precisamente este Log, que en algún momento estaba ocupado por una instancia y no estaba controlado, para salvar la situación incluimos el mágico Try Catch y nos soluciono el problema, pero ahora quiero hacerlo bien, jejejeje, es decir, busco la forma as óptima  para no perder la trazabilidad que nos brinda ese log, alguna forma de encolar la escritura del archivo, no se, que me recomiendan para manejar ene llamados de escritura al mismo archivo?

    miércoles, 22 de abril de 2020 15:58

Respuestas

  • Presumo que no es una granja de servidores grabando un mismo archivo, sino que el servicio web rueda en un único servidor. Si es así, puedes evitar que varios hilos entren en conflicto al grabar el log usando un sencillo lock sobre una variable estática:

    static object lockObject = new object();
    
    public void GrabarLog(string texto)
    {
        lock(lockObject)
        {
            // Esto es solo un ejemplo, no quiere decir que el log haya que gabarlo así
            using (StreamWriter sw = new StraemWriter(ficheroLog, append: true))
            {
                 sw.WriteLine(texto);
            }
        }
    }


    miércoles, 22 de abril de 2020 17:13
    Moderador
  • 1) Sí, la variable estática declarada en un WebService (que no sea Web Farm o Web Garden) utiliza el mismo espacio de memoria para todos los hilos y workers. Nótese, sin embargo, que la sentencia lock no accede a dicho espacio de memoria. Solo lo usa como referencia para llamar a un Mutex y poder distinguir ese Mutex de otros Mutexes que pudieras tener en el programa.

    Y no, no es lo mismo que si levantaras dos aplicaciones de Windows. Esas dos aplicaciones utilizarían dos AppDomains distintos y cada AppDomain tiene su propia copia de las variables estáticas, así que en ese caso NO utilizarían el mismo espacio de memoria. En cambio, todos los hilos del WebService sí que ruedan en el mismo AppDomain y por eso comparten la variable estática.

    2) Sí, el lock implica un posible tiempo de espera en caso de que otro hilo se encuentre dentro del lock. Si un hilo está grabando en el Log, mientras dure esa grabación cualquier otro hilo que intente grabar se queda parado (en espera) hasta que el primero haya terminado de grabar. Esto implica que si esa sentencia de grabación tarda, por ejemplo, 10 milisegundos, y justo 3 milisegundos después de haber empezado a grabar llega otro hilo y quiere también grabar, entonces este segundo hilo se quedaría esperando durante 7 milisegundos hasta que el primero termine de grabar.

    • Marcado como respuesta Tazz_CL jueves, 23 de abril de 2020 13:37
    jueves, 23 de abril de 2020 6:33
    Moderador

Todas las respuestas

  • Hola, 

      

    Gracias por levantar tu consulta en los foros de MSDN. Entendimos su pregunta y vamos a darle seguimiento para buscar la mejor repuesta pertinente al caso.  

    Cualquier duda referente a productos Microsoft, puedes consultarnos. Es un gusto informarte. 

    Gracias por usar los foros de MSDN.   

    Eric Ruiz

     ____________________________ 

      

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.  

    Microsoft ofrece este servicio de forma gratuita, con la finalidad de ayudar a los usuarios y la ampliación de la base de datos de conocimientos relacionados con los productos y tecnologías de Microsoft.   

    Este contenido es proporcionado "tal cual" y no implica ninguna responsabilidad de parte de Microsoft. 

    miércoles, 22 de abril de 2020 16:30
    Moderador
  • Presumo que no es una granja de servidores grabando un mismo archivo, sino que el servicio web rueda en un único servidor. Si es así, puedes evitar que varios hilos entren en conflicto al grabar el log usando un sencillo lock sobre una variable estática:

    static object lockObject = new object();
    
    public void GrabarLog(string texto)
    {
        lock(lockObject)
        {
            // Esto es solo un ejemplo, no quiere decir que el log haya que gabarlo así
            using (StreamWriter sw = new StraemWriter(ficheroLog, append: true))
            {
                 sw.WriteLine(texto);
            }
        }
    }


    miércoles, 22 de abril de 2020 17:13
    Moderador
  • Presumo que no es una granja de servidores grabando un mismo archivo, sino que el servicio web rueda en un único servidor. Si es así, puedes evitar que varios hilos entren en conflicto al grabar el log usando un sencillo lock sobre una variable estática:

    static object lockObject = new object();
    
    public void GrabarLog(string texto)
    {
        lock(lockObject)
        {
            // Esto es solo un ejemplo, no quiere decir que el log haya que gabarlo así
            using (StreamWriter sw = new StraemWriter(ficheroLog, append: true))
            {
                 sw.WriteLine(texto);
            }
        }
    }


    Alberto,

      Muchas gracias por tu ayuda, solo tengo un par de dudas (soy algo cabeza dura):

    1) Una variable estática, declarada a nivel de WebService utiliza el mismo espacio de memoria independiente de los hilos y número de worker con que este configurado?, es como si yo levantará 2 app windows como prueba de concepto me debería funcionar?

    2) En el caso de SI, a mi primera consulta, el lock detiene la ejecución hasta que la variable no este bloqueada?esto tiene algún tiempo de espera? 

     

    miércoles, 22 de abril de 2020 20:07
  • 1) Sí, la variable estática declarada en un WebService (que no sea Web Farm o Web Garden) utiliza el mismo espacio de memoria para todos los hilos y workers. Nótese, sin embargo, que la sentencia lock no accede a dicho espacio de memoria. Solo lo usa como referencia para llamar a un Mutex y poder distinguir ese Mutex de otros Mutexes que pudieras tener en el programa.

    Y no, no es lo mismo que si levantaras dos aplicaciones de Windows. Esas dos aplicaciones utilizarían dos AppDomains distintos y cada AppDomain tiene su propia copia de las variables estáticas, así que en ese caso NO utilizarían el mismo espacio de memoria. En cambio, todos los hilos del WebService sí que ruedan en el mismo AppDomain y por eso comparten la variable estática.

    2) Sí, el lock implica un posible tiempo de espera en caso de que otro hilo se encuentre dentro del lock. Si un hilo está grabando en el Log, mientras dure esa grabación cualquier otro hilo que intente grabar se queda parado (en espera) hasta que el primero haya terminado de grabar. Esto implica que si esa sentencia de grabación tarda, por ejemplo, 10 milisegundos, y justo 3 milisegundos después de haber empezado a grabar llega otro hilo y quiere también grabar, entonces este segundo hilo se quedaría esperando durante 7 milisegundos hasta que el primero termine de grabar.

    • Marcado como respuesta Tazz_CL jueves, 23 de abril de 2020 13:37
    jueves, 23 de abril de 2020 6:33
    Moderador
  • Perfectamente entendido, te pasaste, muchas gracias!!
    jueves, 23 de abril de 2020 13:37