2008-10-23 6 views
25

Ahora que Silverlight 2 ya se ha enviado. Me pregunto si alguien ha armado un framework de registro para él, tal vez algo como enterprise library logging o log4net? Me interesa algo que pueda realizar el seguimiento del cliente y también registrar mensajes en el servidor.Marco de trabajo y/o mejores prácticas de Silverlight

Hasta ahora, el único proyecto que he encontrado es Clog en CodeProject. Alguien ha usado esto? ¿Cuáles fueron tus pensamientos sobre eso?

Respuesta

4

Estoy a punto de profundizar en algo similar para un producto que hemos escrito. Estoy considerando usar PostSharp para Silverlight para agregar el registro del lado del cliente como un aspecto.

he utilizado el proyecto Nlog con gran éxito antes bajo el .NET Framework completo y el Compact Framework, así que lo más probable es tomar el código marco existente y añadir algunos objetivos de registro:

  • un sistema estándar .Diagnóstico objetivo para permitir la captura utilizando DebugView, etc.
  • Un destino de servicio web asincrónico similar al de NLog.
  • Un objetivo de almacenamiento aislado con transferencia diferida a la semántica del servidor.

He examinado brevemente Clog y parece sufrir de una falla importante: no se puede registrar un error de conexión. Por lo tanto, suponiendo que su servidor web esté en línea todo el tiempo, sí, funcionará, pero cuando surgen problemas en el servidor o en el servidor, los datos de registro se pierden e incluso pueden bloquear su aplicación.

+0

'Sistema.Diagnóstico y *** DebugView *** es bueno (y mejor) para el entorno de desarrollo, no para el entorno de producción (no puedo acceder a la producción y uso _DebugView_) – Kiquenet

0

He terminado escribiendo un nuevo marco de trabajo desde cero que soluciona este problema. Creé una cola local que obtendrá los mensajes de registro/seguimiento y luego los filtraré y los enviaré al servidor. Luego, la cola estará respaldada por Almacenamiento aislado, por lo que incluso si el cliente se desconecta de forma permanente para esa sesión, los mensajes se enviarán cuando vuelva a estar en línea.

6

si solo desea enviar mensajes de depuración a la consola. Puede usar el mecanismo console.log del navegador. Codifiqué un método de extensión para eso. Puede encontrarlo en my blog.

// http://kodierer.blogspot.com.es/2009/05/silverlight-logging-extension-method.html 
    public static string Log(string message) 
    { 
     var msgLog = ""; 
     try 
     { 

      HtmlWindow window = HtmlPage.Window; 

      //only log if a console is available 
      var isConsoleAvailable = (bool)window.Eval("typeof(console) != 'undefined' && typeof(console.log) != 'undefined'"); 

      if (!isConsoleAvailable) return "isConsoleAvailable " + isConsoleAvailable; 

      var createLogFunction = (bool)window.Eval("typeof(ssplog) == 'undefined'"); 
      if (createLogFunction) 
      { 
       // Load the logging function into global scope: 
       string logFunction = @"function ssplog(msg) { console.log(msg); }"; 
       string code = string.Format(@"if(window.execScript) {{ window.execScript('{0}'); }} else {{ eval.call(null, '{0}'); }}", logFunction); 
       window.Eval(code); 
      } 

      // Prepare the message 
      DateTime dateTime = DateTime.Now; 
      string output = string.Format("{0} - {1} - {2}", dateTime.ToString("u"), "DEBUG", message); 

      // Invoke the logging function: 
      var logger = window.Eval("ssplog") as ScriptObject; 
      logger.InvokeSelf(output); 
     } 
     catch (Exception ex) 
     { 
      msgLog = "Error Log " + ex.Message; 
     } 
     return msgLog; 

    } 
0

Estoy usando una ventana de JavaScript y haciendo que se pueda escribir en Silverlight. Para "producción", puedo desactivar esta ventana, pero todavía guardo las líneas de registro en la memoria, luego, si algo sale mal, envíe eso al servidor. De esa forma obtengo lo mejor de ambos mundos: registro simple y en tiempo real en el cliente para la depuración y registros de situaciones remotas post-mortem que los usuarios pueden encontrar.

14

Si está dispuesto a quitarse el casco de su astronauta por un minuto, a continuación encontrará un registrador liviano que he escrito para Silverlight, para el registro del lado del cliente (para uso principalmente con operaciones WCF pero podría ser por cualquier error) .

Originalmente se usó en Monotouch para aplicaciones de iPhone y se ha adaptado para IsolateStorage. Puede usar el método Read para mostrar en un cuadro de texto si es necesario. Probado en SL4.

/// <summary> 
/// A lightweight logging class for Silverlight. 
/// </summary> 
public class Log 
{ 
    /// <summary> 
    /// The log file to write to. Defaults to "dd-mm-yyyy.log" e.g. "13-01-2010.log" 
    /// </summary> 
    public static string LogFilename { get; set; } 

    /// <summary> 
    /// Whether to appendthe calling method to the start of the log line. 
    /// </summary> 
    public static bool UseStackFrame { get; set; } 

    static Log() 
    { 
     LogFilename = string.Format("{0}.log", DateTime.Today.ToString("dd-MM-yyyy")); 
     UseStackFrame = false; 
    } 

    /// <summary> 
    /// Reads the entire log file, or returns an empty string if it doesn't exist yet. 
    /// </summary> 
    /// <returns></returns> 
    public static string ReadLog() 
    { 
     string result = ""; 
     IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForSite(); 

     if (storage.FileExists(LogFilename)) 
     { 
      try 
      { 
       using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(LogFilename,FileMode.OpenOrCreate,storage)) 
       { 
        using (StreamReader reader = new StreamReader(stream)) 
        { 
         result = reader.ReadToEnd(); 
        } 
       } 
      } 
      catch (IOException) 
      { 
       // Ignore 
      } 
     } 

     return result; 
    } 

    /// <summary> 
    /// Writes information (not errors) to the log file. 
    /// </summary> 
    /// <param name="format">A format string</param> 
    /// <param name="args">Any arguments for the format string.</param> 
    public static void Info(string format, params object[] args) 
    { 
     WriteLine(LoggingLevel.Info, format, args); 
    } 

    /// <summary> 
    /// Writes a warning (non critical error) to the log file 
    /// </summary> 
    /// <param name="format">A format string</param> 
    /// <param name="args">Any arguments for the format string.</param> 
    public static void Warn(string format, params object[] args) 
    { 
     WriteLine(LoggingLevel.Warn, format, args); 
    } 

    /// <summary> 
    /// Writes a critical or fatal error to the log file. 
    /// </summary> 
    /// <param name="format">A format string</param> 
    /// <param name="args">Any arguments for the format string.</param> 
    public static void Fatal(string format, params object[] args) 
    { 
     WriteLine(LoggingLevel.Fatal, format, args); 
    } 

    /// <summary> 
    /// Writes the args to the default logging output using the format provided. 
    /// </summary> 
    public static void WriteLine(LoggingLevel level, string format, params object[] args) 
    { 
     string message = string.Format(format, args); 

     // Optionally show the calling method 
     if (UseStackFrame) 
     { 
      var name = new StackFrame(2, false).GetMethod().Name; 

      string prefix = string.Format("[{0} - {1}] ", level, name); 
      message = string.Format(prefix + format, args); 
     } 

     Debug.WriteLine(message); 
     WriteToFile(message); 
    } 

    /// <summary> 
    /// Writes a line to the current log file. 
    /// </summary> 
    /// <param name="message"></param> 
    private static void WriteToFile(string message) 
    { 
     try 
     { 
      IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForSite(); 
      bool b = storage.FileExists(LogFilename); 

      using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(LogFilename,FileMode.Append,storage)) 
      { 
       using (StreamWriter writer = new StreamWriter(stream)) 
       { 
        writer.WriteLine("[{0}] {1}", DateTime.UtcNow.ToString(), message); 
       } 
      } 
     } 
     catch (IOException) 
     { 
      // throw new Catch22Exception(); 
     } 
    } 
} 

/// <summary> 
/// The type of error to log. 
/// </summary> 
public enum LoggingLevel 
{ 
    /// <summary> 
    /// A message containing information only. 
    /// </summary> 
    Info, 
    /// <summary> 
    /// A non-critical warning error message. 
    /// </summary> 
    Warn, 
    /// <summary> 
    /// A fatal error message. 
    /// </summary> 
    Fatal 
} 
+0

'Método de lectura' para mostrar en un cuadro de texto? otras alternativas usando IsolatedStorageFile? – Kiquenet