- /// <summary>
- /// 分布式消息树实现
- /// </summary>
- public class LoggerContextImpl
- {
- staticILogger logger =new EmptyLogger();
- #regionFields & Constsconst stringFormat_Msg_Before ="请求之前,地址:{0},方式:{1},时间:{2}";
- const stringFormat_Msg ="响应之后,地址:{0},状态码:{1},时间:{2}";
- /// <summary>
- /// HttpContext上存储的日志上下文
- /// </summary>
- const stringLOGGERCONTEXT ="LoggerContext";
- #endregion
- #regionPrivate Methods/// <summary>
- /// 从请求头中拿到当前的消息树对象
- /// client发布端:SetContextToServer
- /// server接收端:GetContextFromServer
- /// </summary>
- /// <returns></returns>
- static LoggerContext GetContextFromServer()
- {
- try
- {
- varresult = System.Web.HttpContext.Current.Request.Headers.GetValues(LOGGERCONTEXT);
- if(result !=null&& result.Length >0)
- {
- varcat = JsonConvert.DeserializeObject(result[0].ToString());
- return cat;
- }
- return null;
- }
- catch (Exception ex)
- {
- logger.Logger_Error(ex);
- return null;
- }
- }
- static LoggerContext GetContextFromServer(HttpClient http)
- {
- try
- {
- IList<string> result = http.DefaultRequestHeaders.GetValues(LOGGERCONTEXT)asIList<string>;
- if(result !=null&& result.Count >0)
- {
- varcat = JsonConvert.DeserializeObject(result[0].ToString());
- return cat;
- }
- return null;
- }
- catch (Exception ex)
- {
- logger.Logger_Error(ex);
- return null;
- }
- }
- /// <summary>
- /// 设置消息树到当前请求头
- /// </summary>
- /// <returns></returns>
- internal static void SetContextToRequestHeader(System.Web.HttpContext http, LoggerContext context)
- {
- try
- {
- if(http.Request.Headers.GetValues(LOGGERCONTEXT) !=null&& http.Request.Headers.GetValues(LOGGERCONTEXT).Length >0)
- {
- http.Request.Headers.Remove(LOGGERCONTEXT);
- }
- http.Request.Headers.Add(LOGGERCONTEXT, JsonConvert.SerializeObject(context));
- }
- catch (Exception ex)
- {
- logger.Logger_Error(ex);
- }
- }
- /// <summary>
- /// 设置消息树到当前请求头
- /// </summary>
- /// <param name="http"></param>
- /// <param name="context"></param>
- internal static void SetContextToRequestHeader(HttpClient http, LoggerContext context)
- {
- try
- {
- http.DefaultRequestHeaders.Remove(LOGGERCONTEXT);
- http.DefaultRequestHeaders.Add(LOGGERCONTEXT, JsonConvert.SerializeObject(context));
- }
- catch (Exception ex)
- {
- logger.Logger_Error(ex);
- }
- }
- /// <summary>
- /// 设置消息树到当前请求头
- /// </summary>
- /// <param name="http"></param>
- /// <param name="context"></param>
- internal static void SetContextToRequestHeader(System.Web.HttpContextBase http, LoggerContext context)
- {
- try
- {
- if(http.Request.Headers.GetValues(LOGGERCONTEXT) !=null&& http.Request.Headers.GetValues(LOGGERCONTEXT).Length >0)
- {
- http.Request.Headers.Remove(LOGGERCONTEXT);
- }
- http.Request.Headers.Add(LOGGERCONTEXT, JsonConvert.SerializeObject(context));
- }
- catch (Exception ex)
- {
- logger.Logger_Error(ex);
- }
- }
- /// <summary>
- /// 设置请求头,它来自某个响应头
- /// </summary>
- /// <param name="response"></param>
- internal static voidSetContextToRequestHeader(HttpResponseMessage response,stringcurrentUrl =null)
- {
- try
- {
- IEnumerable<string> context =newList<string>();
- if(response.Headers.TryGetValues(LOGGERCONTEXT,outcontext) || response.RequestMessage.Headers.TryGetValues(LOGGERCONTEXT,out context))
- {
- if(context !=null)
- {
- varcat = JsonConvert.DeserializeObject((context as string[])[0].ToString());
- SetContextToRequestHeader(System.Web.HttpContext.Current, cat);
- GetCurrentContext("响应结束", currentUrl);
- }
- }
- }
- catch (Exception ex)
- {
- logger.Logger_Error(ex);
- }
- }
- /// <summary>
- /// 设置LoggerContext到响应头
- /// </summary>
- /// <param name="response"></param>
- /// <param name="context"></param>
- internal static void SetContextToResponseHeader(HttpResponseBase response, LoggerContext context)
- {
- try
- {
- if(response.Headers.GetValues(LOGGERCONTEXT) !=null&& response.Headers.GetValues(LOGGERCONTEXT).Length >0)
- {
- response.Headers.Remove(LOGGERCONTEXT);
- }
- response.Headers.Add(LOGGERCONTEXT, JsonConvert.SerializeObject(context));
- }
- catch (Exception ex)
- {
- logger.Logger_Error(ex);
- }
- }
- /// <summary>
- /// 生产一个ROOTID
- /// </summary>
- /// <returns></returns>
- static string GenerateRootID()
- {
- returnDateTime.Now.ToString("yyyyMMddHHmmssfff") + Thread.CurrentThread.ManagedThreadId;
- }
- /// <summary>
- /// 递归树
- /// </summary>
- /// <param name="str"></param>
- /// <param name="id"></param>
- /// <param name="timer"></param>
- static voidMsgTree(StringBuilder str,stringid, List timer)
- {
- varlist = NoSql.MongodbManager.Instance.Find(i => i.ParentId == id).ToList();
- if(list !=null)
- {
- str.Append("<ul class='treeMsg'>");
- foreach(varitemin list)
- {
- timer.Add(item.AddTime);
- str.AppendFormat("<li><span style='color:red'>{0}</span><span style='color:green'>{1}</span><span>{2}</span></li>"
- , item.Url
- , item.MessageBody
- , item.AddTime);
- MsgTree(str, item.ChildId, timer);
- }
- str.Append("</ul>");
- }
- }
- #endregion
- #region分布式消息树的封装(仓储大叔)/// <summary>
- /// 建立一个上下文对象
- /// </summary>
- /// <param name="rootId">根ID</param>
- /// <param name="parentId">上一请求ID</param>
- /// <param name="url"></param>
- /// <returns></returns>
- public staticLoggerContext DoTransaction(stringrootId,stringparentId,string url)
- {
- if(GlobalConfig.ConfigManager.Config.Logger.IsHttpClientLog !=1)
- return new LoggerContext();
- //建立一个日志,返回rootid,parentid(第一个应该是空),currentid,其中currentid将做为下一次请求的parentid
- varfilter = Builders.Filter.Eq(i => i.RootId, rootId);
- varcontext = NoSql.MongodbManager.Instance.Find(filter).FirstOrDefault();
- if(!string.IsNullOrWhiteSpace(parentId))
- {
- filter = Builders.Filter.Eq(i => i.ParentId, parentId);
- context = NoSql.MongodbManager.Instance.Find(filter).FirstOrDefault();
- }
- if(context ==null)
- {
- context =new LoggerContext
- {
- RootId = GenerateRootID(),
- ParentId =null,
- ChildId = Domain.PrimaryKey.GenerateNewStringId(),
- MessageBody ="开启一个新的请求:"+ url,
- Url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri.Split(new char[] {'?'}, StringSplitOptions.RemoveEmptyEntries)[0],
- AddTime = DateTime.Now,
- };
- NoSql.MongodbManager.Instance.InsertOne(context);
- }
- context.MessageBody = HttpUtility.UrlEncode(context.MessageBody);
- return context;
- }
- /// <summary>
- /// 添加日志,它依赖于一个会话
- /// root->message->message1->message1.1->message1.1.1
- /// </summary>
- /// <param name="parentId">父会话ID</param>
- /// <param name="url"></param>
- /// <param name="message"></param>
- public staticLoggerContext LogEvent(stringparentId,stringurl,string message)
- {
- if(GlobalConfig.ConfigManager.Config.Logger.IsHttpClientLog !=1)
- return new LoggerContext();
- varfilter = Builders.Filter.Eq(i => i.ChildId, parentId);
- varcontext = NoSql.MongodbManager.Instance.Find(filter).FirstOrDefault();
- if(context !=null)
- {
- context =new LoggerContext
- {
- RootId = context.RootId,
- ParentId = context.ChildId,
- ChildId = Domain.PrimaryKey.GenerateNewStringId(),
- MessageBody = message +":"+ url,
- Url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri.Split(new char[] {'?'}, StringSplitOptions.RemoveEmptyEntries)[0],
- AddTime = DateTime.Now,
- };
- NoSql.MongodbManager.Instance.InsertOne(context);
- }
- return context;
- }
- /// <summary>
- /// 返回当前上下文
- /// </summary>
- /// <returns></returns>
- public staticLoggerContext GetCurrentContext(stringmessage,stringcurrentUrl =null)
- {
- try
- {
- currentUrl = (currentUrl ?? System.Web.HttpContext.Current.Request.Url.AbsoluteUri).Split(new char[] {'?'}, StringSplitOptions.RemoveEmptyEntries)[0];
- varcontext = GetContextFromServer();
- if(context ==null)
- {
- context = DoTransaction("","", currentUrl);
- }
- else
- {
- context = LogEvent(context.ChildId, currentUrl, message);
- }
- return context;
- }
- catch (Exception ex)
- {
- logger.Logger_Error(ex);
- return new LoggerContext();
- }
- }
- #endregion
- #region消息树UI/// <summary>
- /// 返回UI消息树
- /// </summary>
- /// <returns></returns>
- public static stringGetMongoLog(DateTime? fromDate, DateTime? toDate,intpage =1)
- {
- string from= DateTime.Now.AddYears(-1).Date.ToString("yyyy-MM-dd");
- stringto = DateTime.Now.Date.AddDays(1).ToString("yyyy-MM-dd");
- if (fromDate.HasValue)
- {
- from= fromDate.Value.ToString("yyyy-MM-dd");
- }
- if (toDate.HasValue)
- {
- to = toDate.Value.ToString("yyyy-MM-dd");
- }
- varstages =newList();
- stages.Add(newJsonPipelineStageDefinition("{$match:{AddTime:{$gt:ISODate('"+from+"'),$lt:ISODate('"+ to +"')}}}"));
- stages.Add(newJsonPipelineStageDefinition("{$group:{_id: \"$RootId\", count: {$sum: 1}}}"));
- stages.Add(newJsonPipelineStageDefinition("{$skip:"+ page *5+"}"));
- stages.Add(newJsonPipelineStageDefinition("{$limit:5}"));
- varpipeline =newPipelineStagePipelineDefinition(stages);
- varresult = NoSql.MongodbManager.Collection.Aggregate(pipeline);
- StringBuilder str =new StringBuilder();
- str.Append("<ol class='treeMsg'>");
- foreach(varitemin result.ToList())
- {
- vartimer =newList();
- varold = NoSql.MongodbManager.Instance.Find(i => i.RootId == item.Values.ToArray()[0].ToString() && i.ParentId ==null).FirstOrDefault();
- timer.Add(old.AddTime);
- str.Append("<li style='margin:5px;border:1px dashed #aaa'>");
- str.AppendFormat("<span style='color:red;'>{0}</span><span style='color:green'>{1}</span><span>{2}</span>"
- , old.Url
- , old.MessageBody
- , old.AddTime);
- MsgTree(str, old.ChildId, timer);
- str.AppendFormat("<p><b><em>本次请求用时{0}毫秒({1}秒)<em></b></p>"
- , (timer.Max() - timer.Min()).TotalMilliseconds
- , (timer.Max() - timer.Min()).TotalSeconds);
- str.Append("</li>");
- }
- str.Append("</ol>");
- return str.ToString();
- }
- #endregion
- }
来源: http://www.bubuko.com/infodetail-2123170.html