一直感觉Web开发或者windows服务的日志跟踪调试不是很方便
特别是在生产环境服务器上面
目前一般的解决方案是通过各种日志工具把错误信息和调试信息写到数据库或者文件里面
特别是日志较多的时候很麻烦 过滤筛选也不方便
sql调试跟踪工具Sql Profile大家都用过,是不是感觉很方便
总结了3个优点
1、方便 可以异地跟踪 强大的筛选功能
2、高效 最少不使用的时候应该不会影响MSQLSERVER的性能
3、可以几个客户端同时跟踪一台服务器
受到启发写了这么一个小工具 主要思路
应用端 继承TraceListener 通过UDP协议广播日志消息
日志查看工具 监听局域网UDP广播日志消息,筛选过滤消息 通过控制台打印出来
用UDP主要是因为效率高 无连接状态 应用端只管发送消息 不用关心有没有收听的 有没有收到
1 public class UdpTraceListener : TraceListener
2 {
3 public TraceEventType EventType;
4 UdpClient Client;
5 int ServerPort;
6 public UdpTraceListener(int serverPort)
7 {
8 Client = new UdpClient();
9 Client.EnableBroadcast = true;
10 this.Filter = new UdpTraceFilter(this);
11 ServerPort = serverPort;
12 }
13
14 public override void Write(string message)
15 {
16
17 }
18
19 public override void WriteLine(string message)
20 {
21 var data = System.Text.Encoding.UTF8.GetBytes(EventType + "|" + message);
22 Client.Send(data, data.Length, new IPEndPoint(IPAddress.Broadcast, ServerPort));
23 }
24
25 public class UdpTraceFilter : TraceFilter
26 {
27 UdpTraceListener Listener;
28 public UdpTraceFilter(UdpTraceListener listener)
29 {
30 Listener = listener;
31 }
32
33 public override bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage, object[] args, object data1, object[] data)
34 {
35 Listener.EventType = eventType;
36 return true;
37 }
38 }
39
40 }
3 public TraceEventType EventType;
4 UdpClient Client;
5 int ServerPort;
6 public UdpTraceListener(int serverPort)
7 {
8 Client = new UdpClient();
9 Client.EnableBroadcast = true;
10 this.Filter = new UdpTraceFilter(this);
11 ServerPort = serverPort;
12 }
13
14 public override void Write(string message)
15 {
16
17 }
18
19 public override void WriteLine(string message)
20 {
21 var data = System.Text.Encoding.UTF8.GetBytes(EventType + "|" + message);
22 Client.Send(data, data.Length, new IPEndPoint(IPAddress.Broadcast, ServerPort));
23 }
24
25 public class UdpTraceFilter : TraceFilter
26 {
27 UdpTraceListener Listener;
28 public UdpTraceFilter(UdpTraceListener listener)
29 {
30 Listener = listener;
31 }
32
33 public override bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage, object[] args, object data1, object[] data)
34 {
35 Listener.EventType = eventType;
36 return true;
37 }
38 }
39
40 }
控制台小工具
1 static void Main(string[] args)
2 {
3 Console.WindowWidth = 100;
4 Console.Title = "UDP远程日志监视器";
5
6
7
8 var portStr = string.Empty;
9 int port = 0;
10 while (!int.TryParse(portStr, out port))
11 {
12 Console.WriteLine("请输入监听端口号:");
13 portStr = Console.ReadLine();
14 }
15
16
17 IPAddress ipAddress = IPAddress.Any;
18 UdpClient udpClient = new UdpClient(port);
19 udpClient.EnableBroadcast = true;
20 Console.WriteLine("开始监听...");
21 while (true)
22 {
23
24
25 IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
26 Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
27
28 var log = Encoding.UTF8.GetString(receiveBytes);
29 Console.ForegroundColor = ConsoleColor.White;
30 Console.WriteLine("{0} {1}", DateTime.Now, RemoteIpEndPoint);
31 TraceEventType result;
32
33 if (log.Contains("|"))
34 {
35 var type = log.Split('|')[0];
36 log = log.Substring(type.Length + 1);
37 if (System.Enum.TryParse<TraceEventType>(type, out result))
38 {
39 if (result == TraceEventType.Error)
40 Console.ForegroundColor = ConsoleColor.Red;
41 else if (result == TraceEventType.Warning)
42 Console.ForegroundColor = ConsoleColor.Yellow;
43 else if (result == TraceEventType.Information)
44 Console.ForegroundColor = ConsoleColor.Green;
45 }
46 }
47
48 Console.WriteLine(log);
49 Console.WriteLine("");
50 Console.ForegroundColor = ConsoleColor.White;
51 }
2 {
3 Console.WindowWidth = 100;
4 Console.Title = "UDP远程日志监视器";
5
6
7
8 var portStr = string.Empty;
9 int port = 0;
10 while (!int.TryParse(portStr, out port))
11 {
12 Console.WriteLine("请输入监听端口号:");
13 portStr = Console.ReadLine();
14 }
15
16
17 IPAddress ipAddress = IPAddress.Any;
18 UdpClient udpClient = new UdpClient(port);
19 udpClient.EnableBroadcast = true;
20 Console.WriteLine("开始监听...");
21 while (true)
22 {
23
24
25 IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
26 Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
27
28 var log = Encoding.UTF8.GetString(receiveBytes);
29 Console.ForegroundColor = ConsoleColor.White;
30 Console.WriteLine("{0} {1}", DateTime.Now, RemoteIpEndPoint);
31 TraceEventType result;
32
33 if (log.Contains("|"))
34 {
35 var type = log.Split('|')[0];
36 log = log.Substring(type.Length + 1);
37 if (System.Enum.TryParse<TraceEventType>(type, out result))
38 {
39 if (result == TraceEventType.Error)
40 Console.ForegroundColor = ConsoleColor.Red;
41 else if (result == TraceEventType.Warning)
42 Console.ForegroundColor = ConsoleColor.Yellow;
43 else if (result == TraceEventType.Information)
44 Console.ForegroundColor = ConsoleColor.Green;
45 }
46 }
47
48 Console.WriteLine(log);
49 Console.WriteLine("");
50 Console.ForegroundColor = ConsoleColor.White;
51 }
52 }
web.config
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add name="UdpTraceListener" type="UdpTraceListener" initializeData="8888"></add>
</listeners>
</trace>
<trace autoflush="true">
<listeners>
<add name="UdpTraceListener" type="UdpTraceListener" initializeData="8888"></add>
</listeners>
</trace>
</system.diagnostics>
如果需要记录全局的错误的话 需要配置Global 的Application_Error
Global
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// 在应用程序启动时运行的代码
Trace.TraceInformation("Application_Start");
}
void Application_End(object sender, EventArgs e)
{
Trace.TraceInformation("Application_End");
// 在应用程序关闭时运行的代码
}
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError().GetBaseException();
Trace.TraceError(string.Format("message:{0} targetClass:{1} stackTrace:{2} ", ex.Message, ex.TargetSite.DeclaringType.FullName,ex.StackTrace));
// 在出现未处理的错误时运行的代码
}
{
void Application_Start(object sender, EventArgs e)
{
// 在应用程序启动时运行的代码
Trace.TraceInformation("Application_Start");
}
void Application_End(object sender, EventArgs e)
{
Trace.TraceInformation("Application_End");
// 在应用程序关闭时运行的代码
}
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError().GetBaseException();
Trace.TraceError(string.Format("message:{0} targetClass:{1} stackTrace:{2} ", ex.Message, ex.TargetSite.DeclaringType.FullName,ex.StackTrace));
// 在出现未处理的错误时运行的代码
}
}
在其它任何需要调试的地方调用 以下方法即可
Trace.TraceWarning();
Trace.TraceInformation();
Trace.TraceError();
Windows Service WCF使用方法基本上差不多 在app.config里面做同样的配置
目前没有实现高级筛选功能