巧用CurrentThread.Name来统一标识日志记录(续)
Posted buguge
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了巧用CurrentThread.Name来统一标识日志记录(续)相关的知识,希望对你有一定的参考价值。
开篇不提前文。本文通过模拟场景来抛出问题。
我在web站点程序里新建一个tmp1.ashx文件。其类代码如下:
using System; using System.IO; using System.Threading; using System.Web; namespace PaymentPlatform.Test { /// <summary> /// tmp1 的摘要说明 /// </summary> public class tmp1 : IHttpHandler { public tmp1() { Thread.CurrentThread.Name = string.Format("[{0}]", Guid.NewGuid().ToString().Replace("-", "").ToUpper()); WriteLog("========="); } public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; WriteLog("ProcessRequest"); context.Response.Write("1"); } private static void WriteLog(string log) { string logFileName = string.Format("{0:yyyyMMdd}-{1}.txt", DateTime.Now, "Info"); logFileName = Path.Combine(System.Configuration.ConfigurationManager.AppSettings["logPath"], logFileName); log = (System.Threading.Thread.CurrentThread.Name ?? "null") + log; using (StreamWriter sw = new StreamWriter(logFileName, true)) { sw.WriteLine(log); sw.Close(); } } public bool IsReusable { get {return false; } } } }
注意,我在tmp1的构造方法里给当前线程的Name属性赋值。在后续包括ProcessRequest方法里记日志时,会获取当前线程Name并打印出来。
我做了如下几种测试:
- ie里访问tmp1.ashx,包括频繁刷新,所记录的日志都可以获取到当前线程Name。
- 构造Method为Get的HttpWebRequest请求,并发测试,所记录的日志都可以获取到当前线程Name。
- 构造Method为Post的HttpWebRequest请求,在不传递参数(ContentLength=0)的情况下,并发测试,发现所记录的日志都可以获取到当前线程Name。
- 构造Method为Post的HttpWebRequest请求,在传递参数的情况下,并发测试,发现所记录的日志都无法获取到当前线程Name。
测试用例代码如下:
1 using CommonUtils; 2 using Microsoft.VisualStudio.TestTools.UnitTesting; 3 using System.Collections.Generic; 4 using System.IO; 5 using System.Linq; 6 using System.Net; 7 using System.Text; 8 using System.Threading; 9 10 namespace Test.TechArt 11 { 12 [TestClass] 13 public class HttpPostTest 14 { 15 [TestMethod] 16 public void ConcurrentTest() 17 { 18 for (int j = 0; j < 10; j++) 19 { 20 CallASHXAPI(); 21 } 22 23 List<Thread> list = new List<Thread>(); 24 for (int i = 0; i < 500; i++) 25 { 26 list.Add(new Thread(() => 27 { 28 for (int j = 0; j < 50; j++) 29 { 30 CallASHXAPI(); 31 } 32 })); 33 } 34 list.AsParallel().ForAll(t => t.Start()); 35 Thread.Sleep(15000); 36 } 37 38 [TestMethod] 39 public void CallASHXAPI() 40 { 41 42 string requestUrl = "http://localhost:8076/Test/tmp1.ashx"; 43 44 string ret = RequestUrlPost(requestUrl); 45 LogHelper.Write("响应报文:" + ret); 46 47 } 48 49 private string RequestUrlGet(string requestUrl) 50 { 51 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl); 52 using (var reader = new StreamReader(request.GetResponse().GetResponseStream(), Encoding.UTF8)) 53 { 54 return reader.ReadToEnd(); 55 } 56 } 57 private string RequestUrlPost(string requestUrl) 58 { 59 /* 60 有参和无参,会导致两种结果 61 */ 62 //无参,在tmp1.ashx的ProcessRequest的方法里记录的日志可以获取到当前线程的Name 63 //string requestMsg = ""; 64 //有参,在tmp1.ashx的ProcessRequest的方法里记录的日志都获取不到当前线程的Name 65 string requestMsg = "1"; 66 67 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl); 68 request.Method = "POST"; 69 70 byte[] aryBuf = Encoding.UTF8.GetBytes(requestMsg); 71 request.ContentLength = aryBuf.Length; 72 73 using (Stream writer = request.GetRequestStream()) 74 { 75 writer.Write(aryBuf, 0, aryBuf.Length); 76 writer.Close(); 77 writer.Dispose(); 78 } 79 using (var reader = new StreamReader(request.GetResponse().GetResponseStream(), Encoding.UTF8)) 80 { 81 return reader.ReadToEnd(); 82 } 83 } 84 } 85 }
由此,问题来了,Http流请求传参和不传参这两种情况有什么区别呢?
以上是关于巧用CurrentThread.Name来统一标识日志记录(续)的主要内容,如果未能解决你的问题,请参考以下文章
巧用CurrentThread.Name来统一标识日志记录(java-logback篇)