如何在单个文件中记录服务响应

时间:2014-03-01 17:49:22

标签: c# wcf

我有一个WCF服务。我有这个操作记录任何进入该服务的请求。我在这里遇到的问题是它将每个请求记录在一个单独的文件中。如何在一个文件中记录所有内容,用一行分隔每个日志?

出于性能原因,我想将其记录在一个文件中。

      public byte sendMessage(string strMsgId, string strMessage)
        {
        byte result = 1;
        try
        {
            if (strMsgId == "02") 
            {
                // Logging---------------------------------------------------------------------------------
                // Build timestamp string
                var currentDateTime = DateTime.Now;
                string timeStampString = currentDateTime.ToString("yyyy-MM-dd hhmmssfff");

                // Build filename for Inbound messages, concat timestamp and .txt extension.
                string debugFileName = "C:\\Inboundmessage" + " " + timeStampString + ".txt";
                var inboundMessageLog = new StreamWriter(debugFileName, false, System.Text.Encoding.Default);
                // Write to the file:
                inboundMessageLog.WriteLine(DateTime.Now);
                inboundMessageLog.WriteLine("Time = {0}", currentDateTime.ToString("yyyy-MM-dd hh:mm:ss:fff tt"));
                inboundMessageLog.WriteLine("{0}{1}{2}", "Inbound Message:", Environment.NewLine, strMessage.Substring(1016, 26));
                inboundMessageLog.Close();

                // -------------------------------------------------------------------------------------------
                result = 0;
            }

        }
        catch
        {
            //Failed
            result = 1;
        }
        return result;  

4 个答案:

答案 0 :(得分:0)

按照@Sudhakar和Joel的说法,并在StreamWriter contruct中包裹using

 using (var inboundMessageLog = new StreamWriter(debugFileName, false, System.Text.Encoding.Default)) {  
    // Write to the file:  
    inboundMessageLog.WriteLine(DateTime.Now);  
    inboundMessageLog.WriteLine("Time = {0}", currentDateTime.ToString("yyyy-MM-dd hh:mm:ss:fff tt"));  
    inboundMessageLog.WriteLine("{0}{1}{2}", "Inbound Message:", Environment.NewLine, strMessage.Substring(1016, 26));  
 }  

答案 1 :(得分:0)

从以下位置更改此行:

 string debugFileName = "C:\\Inboundmessage" + " " + timeStampString + ".txt";
 var inboundMessageLog = new StreamWriter(debugFileName, false, System.Text.Encoding.Default);

为:

 string debugFileName = "C:\\Inboundmessage.txt";
 var inboundMessageLog = new StreamWriter(debugFileName, true, System.Text.Encoding.Default);

请参阅MSDN

public StreamWriter(
    string path,
    bool append,
    Encoding encoding
)
  

append类型:System.Boolean如果要将数据附加到文件,则为true;假的   覆盖文件。如果指定的文件不存在,则为此   参数无效,构造函数创建一个新文件。

答案 2 :(得分:0)

问题:

在当前代码中,您将使用每个日志条目的最新时间戳更改文件名。

StreamWriter()方法首先检查给定文件是否存在,如果文件不存在则创建新文件。

在您的情况下,因为您要更改每个日志条目的文件名,无法找到它并且每次都会创建新文件。

解决方案1:

您可以创建一个变量,将文件(debugFileName)的路径存储在具有固定文件名的函数上方(例如:myLog.txt)作为类变量,并在sendMessage()中使用相同的内容函数并将StreamWriter()构造函数的append属性更改为true以附加内容,而不是为每个日志条目覆盖文件的旧内容。

来自MSDN:StreamWriter Constructor (String, Boolean, Encoding)

  

为指定的内容初始化StreamWriter类的新实例   使用指定的编码和默认缓冲区大小的文件。如果   文件存在,可以覆盖或附加到。如果是文件   如果不存在,此构造函数将创建一个新文件。

建议:您正在使用实现StremWriter接口的IDisposable,因此您可以将其声明包含在using {}块中以确保其(对象)处置离开使用区后。

注意:如果您使用{}阻止,则无需在StreamWriter对象上调用Close()函数,因为它将由using{}阻止。

试试这个:

 string debugFileName = "C:\\myLog.txt";//declare this as class variable
 public byte sendMessage(string strMsgId, string strMessage)
    {
    byte result = 1;
    try
    {
        if (strMsgId == "02") 
        {                
           // Build timestamp string
           var currentDateTime = DateTime.Now;
           string timeStampString = currentDateTime.ToString("yyyy-MM-dd hhmmssfff");
           using(var inboundMessageLog = new StreamWriter(debugFileName, true, System.Text.Encoding.Default))
          {
            // Write to the file:
            inboundMessageLog.WriteLine(DateTime.Now);
            inboundMessageLog.WriteLine("Time = {0}", currentDateTime.ToString("yyyy-MM-dd hh:mm:ss:fff tt"));
            inboundMessageLog.WriteLine("{0}{1}{2}", "Inbound Message:", Environment.NewLine, strMessage.Substring(1016, 26));


            // -------------------------------------------------------------------------------------------
            result = 0;
          }
        }
    }
    catch
    {
        //Failed
        result = 1;
    }
    return result;  
   }

解决方案2:如果您不想处理对象处理问题,可以使用Static类System.IO.File类来编写文件内容。

 string debugFileName = "C:\\myLog.txt";  //declare this as class variable
 public byte sendMessage(string strMsgId, string strMessage)
    {
    StringBuilder strLines=new StringBuilder();
    byte result = 1;
    try
    {
        if (strMsgId == "02") 
        {                
            // Build timestamp string
            var currentDateTime = DateTime.Now;
            string timeStampString = currentDateTime.ToString("yyyy-MM-dd hhmmssfff");

            // Write to the file:
            strLines.Append(DateTime.Now+Environment.NewLine);
            strLines.Append("Time = {0}"+Environment.NewLine, currentDateTime.ToString("yyyy-MM-dd hh:mm:ss:fff tt"));
            strLines.Append("{0}{1}{2}"+Environment.NewLine, "Inbound Message:", Environment.NewLine, strMessage.Substring(1016, 26));                

            File.WriteAllText(debugFileName , str.ToString());
            result = 0;
          }

    }
    catch
    {
        //Failed
        result = 1;
    }
    return result;  
   }

答案 3 :(得分:0)

以上回复可以解决您的问题。从长远来看,你会遇到的另一个问题是因为你违反了 单一责任原则

WCF服务应该只为请求提供服务。记录是一种不同的功能。

如果我一直在和你合作,我会建议将所有日志记录到一个不同的类中,并在服务中留下抽象。

public interface ILogger
{
    bool LogMessage(string message, SeverityEnum severity..etc);
}

public class Service: IService
{
     ILogger logger;
     public Service(ILogger logger)
     {
            //check if logger is not null
            this.logger = logger;
     }
}

使用WCF的扩展插入记录器依赖项并从WCF中取出loggin功能。

您需要服务主机工厂和Dependeny Injection提供以实现其余功能。

但是,一旦您完全控制了日志记录的工作方式。

一切顺利

齐亚