2008-10-23 79 views

回答

4

我正在为我们写的产品钻研类似的东西。我正在考虑使用PostSharp for Silverlight将客户端日志记录添加为一个方面。

我已经使用了大获成功的NLOG项目之前下足.NET Framework和Compact Framework的,所以我将最有可能利用现有的框架代码,并添加一些记录目标:

  • 标准体系。诊断目标以启用使用DebugView等进行捕获。
  • 异步Web服务目标类似于NLog中的目标。
  • 具有延迟传输到服务器语义的隔离存储目标。

我简单地看过Clog,它似乎有一个主要缺陷 - 它无法记录连接失败。因此,假设您的Web服务器始终处于联机状态,可以,但是当上游或服务器本身发生问题时,日志记录数据将全部丢失,甚至可能会导致应用程序崩溃。

+0

`系统。Diagnostics`和*** DebugView ***对于开发环境是好的(并且更好),不适用于生产环境(我无法访问生产和使用_DebugView_) – Kiquenet 2016-04-29 06:27:52

0

我已经结束了从头开始写一个新的日志框架,解决这个缺陷。我创建了一个本地队列,它将获取日志/跟踪消息,然后执行过滤并将它们发送到服务器。然后,队列将由独立存储提供支持,因此即使客户端在该会话中永久离线,消息也会在其恢复联机时发送。

6

如果您只是想将调试消息输出到控制台。您可以使用浏览器的console.log机制。我编写了一个扩展方法。你可以在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

我正在使用JavaScript窗口并在Silverlight中对其进行脚本编写。对于“生产”,我可以关闭此窗口,但仍将日志行保存到内存中,如果出现问题,请将其发送到服务器。这样我就可以得到两全其美的效果 - 在客户端上进行简单,实时的日志记录以进行调试,并记录用户可能遇到的远程验尸情况。

14

如果你愿意把你的宇航员头盔关闭一分钟,下面是我为Silverlight编写的一个轻量级记录器,用于客户端记录(主要用于WCF操作,但可能用于任何错误) 。

它最初用于iPhone应用程序的Monotouch,并且已被改编为IsolateStorage。如果需要,您可以使用Read方法在文本框中显示。经过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

`Read`方法在文本框中显示?使用IsolatedStorageFile的另一种选择? – Kiquenet 2016-05-03 09:25:24