/// <summary>
        /// 
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            ServiceContainer.Resolve<IInitRequestScopeContext>().BeginRequest(filterContext.HttpContext.Request);

            if (!filterContext.HasMarkerAttribute<NonTracingAttribute>())
            {
                var request = filterContext.HttpContext.Request;
                var response = filterContext.HttpContext.Response;

                Header reqHeader = TracingContextData.GetDefaultRequestHeader();

                TracingContextData.SetSubRpcID(reqHeader.RpcID + ".0");
                TracingContextData.SetRequestHeader(reqHeader);

                if (!filterContext.HasMarkerAttribute<NotToLogAttribute>())
                {
                    TraceLogs trace = new TraceLogs();
                    trace.ContextType = ContextType.Server.ToString();
                    trace.StartTime = DateTime.Now;
                    trace.MachineAddr = Util.TracingContextHelper.GetServerAddress();
                    trace.TraceId = reqHeader.TraceID;
                    trace.RpcId = reqHeader.RpcID;
                    trace.Protocol = request.Url.Scheme;

                    trace.Environment = this.environment ?? EnvironmentConfig.Environment;
                    trace.SystemID = this.systemID ?? EnvironmentConfig.SystemID;
                    trace.SystemName = this.systemName ?? EnvironmentConfig.SystemName;

                    //srs.InvokeID = string.Format("{0}_{1}", filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower(), filterContext.ActionDescriptor.ActionName.ToLower());

                    //InvokeID
                    trace.InvokeID = request.Url.AbsolutePath;
                    string folder = filterContext.HttpContext.Request.Headers[Config.ResponseHeaderFolderKey];
                    if (!string.IsNullOrWhiteSpace(folder))
                    {
                        trace.ServerHost = request.Url.Host + folder;
                    }
                    else
                    {
                        trace.ServerHost = request.Url.Host;
                    }

                    TraceExtensionOnActionExecuting(filterContext, trace);

                    Util.TracingContextHelper.SetContextItem(Config.ServerRSKey, trace);
                }
            }

            base.OnActionExecuting(filterContext);
        }
        //private static Dictionary<int, Tuple<string, string>> dict = new Dictionary<int, Tuple<string, string>>();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="client"></param>
        /// <param name="systemID"></param>
        /// <param name="systemName"></param>
        /// <param name="environment">环境</param>
        /// <param name="searchKeyFunc">keyFunc</param>
        public static void RegistTracing(this RpcHttpClient client, string systemID = null, string systemName = null, string environment = null, Func<RpcContext, string> searchKeyFunc = null)
        {
            RpcHttpClient.OnResponseDelegate onResponse = (response, rpcContext) =>
            {
                TraceLogs trace = new TraceLogs();
                trace.IsSuccess = true;
                trace.IsException = false;
                trace.SystemID = systemID ?? EnvironmentConfig.SystemID;
                trace.SystemName = systemName ?? EnvironmentConfig.SystemName;
                trace.Environment = environment ?? EnvironmentConfig.Environment;
                if (searchKeyFunc != null)
                {
                    trace.SearchKey = searchKeyFunc(rpcContext);
                }

                FillClientSR(trace, response.RequestMessage, response, rpcContext);

                Record(trace);
            };
            RpcHttpClient.OnErrorDelegate onError = (ex, request, rpcContext) =>
            {
                TraceLogs trace = new TraceLogs();
                trace.IsSuccess = false;
                trace.IsException = true;
                trace.SystemID = systemID ?? EnvironmentConfig.SystemID;
                trace.SystemName = systemName ?? EnvironmentConfig.SystemName;
                trace.Environment = environment ?? EnvironmentConfig.Environment;

                FillClientSR(trace, request, null, rpcContext);

                trace.Extensions.Add("Exception", Util.GetFullExceptionMessage(ex));

                Record(trace);
            };


            client.RequestContentDataHandler -= Client_RequestContentDataHandler;
            client.OnRequest -= Client_OnRequest;
            client.OnResponse -= onResponse;
            client.OnError -= onError;

            client.RequestContentDataHandler += Client_RequestContentDataHandler;
            client.OnRequest += Client_OnRequest;
            client.OnResponse += onResponse;
            client.OnError += onError;

            //dict[client.GetHashCode()] = new Tuple<string, string>(systemID, systemName);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filterContext"></param>
        /// <param name="trace"></param>
        protected virtual void TraceExtensionOnActionExecuting(ActionExecutingContext filterContext, TraceLogs trace)
        {
            trace.Extensions.Add(nameof(filterContext.HttpContext.Request.Url.PathAndQuery), filterContext.HttpContext.Request.Url.PathAndQuery);

            if (filterContext.ActionParameters != null && filterContext.ActionParameters.Count > 0)
            {
                trace.Extensions.Add(Config.ParamsKey, filterContext.ActionParameters);
            }

            var form = filterContext.HttpContext.Request.Form;
            if (form != null && form.Count > 0)
            {
                var dict = new Dictionary<string, object>();
                foreach (var k in form.AllKeys)
                {
                    dict.Add(k, form[k]);
                }
                trace.Extensions.Add(Config.FormKey, dict);
            }
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="srs"></param>
 private void Record(TraceLogs srs)
 {
     ServiceContainer.Resolve<ITracingRecord>().RecordTraceLog(srs);
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filterContext"></param>
        /// <param name="trace"></param>
        protected virtual void TraceExtensionOnActionExecuted(ActionExecutedContext filterContext, TraceLogs trace)
        {
            var jResult = filterContext.Result as JsonResult;
            if (jResult != null)
            {
                var responseModel = jResult.Data as IResponseModel;
                if (responseModel != null)
                {
                    trace.Code = responseModel.GetCode();

                    //if (responseModel.Extension == null)
                    //{
                    //    responseModel.Extension = new List<Rpc.IContractModel.KeyValue<string, string>>();
                    //}
                    //responseModel.Extension.Add(new Rpc.IContractModel.KeyValue<string, string>(nameof(Raven.Rpc.IContractModel.Header.TraceID), HttpContentData.GetRequestHeader().TraceID));
                }

                //SearchKey
                var searchKey = jResult.Data as ISearchKey;
                if (searchKey != null)
                {
                    trace.SearchKey = searchKey.GetSearchKey();
                }

                trace.Extensions.Add(Config.ResultKey, jResult.Data);
            }
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="trace"></param>
 private static void Record(TraceLogs trace)
 {
     record.RecordTraceLog(trace);
 }
        //private static void Client_OnResponse(HttpResponseMessage response, RpcContext rpcContext)
        //{
        //    TraceLogs trace = new TraceLogs();
        //    trace.IsSuccess = true;
        //    trace.IsException = false;
        //    FillClientSR(trace, response.RequestMessage, rpcContext);

        //    Record(trace);
        //}

        //private static void Client_OnError(Exception ex, HttpRequestMessage request, RpcContext rpcContext)
        //{
        //    TraceLogs trace = new TraceLogs();
        //    trace.IsSuccess = false;
        //    trace.IsException = true;
        //    FillClientSR(trace, request, rpcContext);

        //    trace.Extension.Add("Exception", Util.GetFullExceptionMessage(ex));

        //    Record(trace);
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="trace"></param>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <param name="rpcContext"></param>
        private static void FillClientSR(TraceLogs trace, HttpRequestMessage request, HttpResponseMessage response, RpcContext rpcContext)
        {
            trace.ContextType = ContextType.Client.ToString();
            //var requestHeader = TracingContextData.GetRequestHeader();  //raven Request Header
            var uri = request.RequestUri;

            //int index = uri.AbsoluteUri.IndexOf("?");
            //if (index > 0)
            //{
            //    trace.ServiceMethod = uri.AbsoluteUri.Substring(0, index);
            //}
            //else
            //{
            //    trace.ServiceMethod = uri.AbsoluteUri;
            //}

            trace.MachineAddr = Util.TracingContextHelper.GetServerAddress();

            trace.InvokeID = uri.AbsolutePath;
            trace.ServerHost = uri.Host;

            //trace.Extension.Add(nameof(uri.AbsolutePath), uri.AbsolutePath);
            trace.Extensions.Add(nameof(uri.PathAndQuery), uri.PathAndQuery);
            //trace.Extension.Add(nameof(uri.Host), uri.Host);

            trace.Extensions.Add(nameof(rpcContext.RequestModel), rpcContext.RequestModel);
            trace.Extensions.Add(nameof(rpcContext.ResponseModel), rpcContext.ResponseModel);
            trace.ResponseSize = rpcContext.ResponseSize;

            trace.Protocol = uri.Scheme;

            trace.ProtocolHeader.Add("RequestHeaders", new Dictionary<string, string>
            {
                { "Accept", request.Headers.Accept.ToString() },
                { "Accept-Encoding", request.Headers.AcceptEncoding.ToString() },
                { "Content-Type", request.Content?.Headers?.ContentType?.ToString() },
            });

            if (response != null)
            {
                trace.ProtocolHeader.Add("ResponseHeaders", new Dictionary<string, string>
                {
                    { "Content-Encoding", response.Content?.Headers?.ContentEncoding?.ToString() },
                    { "Content-Type", response.Content?.Headers?.ContentType?.ToString() },
                });
            }

            //trace.SendSTime = rpcContext.SendStartTime;
            //trace.ReceiveETime = rpcContext.ReceiveEndTime;
            //trace.ExceptionTime = rpcContext.ExceptionTime;
            trace.StartTime = rpcContext.SendStartTime;

            if (rpcContext.ReceiveEndTime.HasValue)
            {
                trace.EndTime = rpcContext.ReceiveEndTime.Value;
                trace.TimeLength = (trace.EndTime - trace.StartTime).TotalMilliseconds;
            }
            else if (rpcContext.ExceptionTime.HasValue)
            {
                trace.EndTime = rpcContext.ExceptionTime.Value;
                trace.TimeLength = (trace.EndTime - trace.StartTime).TotalMilliseconds;
            }

            //trace.TimeLength = trace.ReceiveETime.HasValue ? (trace.ReceiveETime.Value - trace.SendSTime).TotalMilliseconds : 0D;
            //trace.RpcId = modelHeader.RpcID;



            //var reqModel = rpcContext.RequestModel as IRequestModel<Header>;
            //if (reqModel != null && reqModel.Header != null)
            //{
            //    trace.RpcId = rpcContext.Items[RpcIDKey].ToString();
            //}

            //if modelHeader is null, create new traceID
            trace.RpcId = rpcContext.Items[RpcIDKey].ToString();
            trace.TraceId = rpcContext.Items[TraceIDKey].ToString();

            if (rpcContext.ResponseModel != null)
            {
                var resModel = rpcContext.ResponseModel as IResponseModel;
                if (resModel != null)
                {
                    trace.Code = resModel.GetCode();
                }

                //SearchKey
                var searchKey = rpcContext.ResponseModel as ISearchKey;
                if (searchKey != null)
                {
                    trace.SearchKey = searchKey.GetSearchKey();
                }

            }

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="actionContext"></param>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            ServiceContainer.Resolve<IInitRequestScopeContext>().BeginRequest(actionContext.Request);

            if (!actionContext.HasMarkerAttribute<NonTracingAttribute>())
            {
                var request = actionContext.Request;
                IRequestModel<Header> reqModel = null;
                Header reqHeader = null;

                if (actionContext.ActionArguments.Count > 0)
                {
                    foreach (var dic in actionContext.ActionArguments)
                    {
                        //if (dic.Value is RequestModel)
                        //{
                        //    reqModel = dic.Value as RequestModel;
                        //    break;
                        //}
                        reqModel = dic.Value as IRequestModel<Header>;
                        if (reqModel != null)
                        {
                            break;
                        }
                    }
                }
                if (reqModel == null && actionContext.Request.Content != null && string.Equals(actionContext.Request.Method.Method, "post", StringComparison.CurrentCultureIgnoreCase))
                {
                    try
                    {
                        reqModel = actionContext.Request.Content.ReadAsAsync<RequestModel>().Result;
                    }
                    catch { }
                    if (reqModel != null)
                    {
                        actionContext.ActionArguments.Add(Guid.NewGuid().ToString("N"), reqModel);
                    }
                }

                if (reqModel != null && reqModel.Header != null)
                {
                    reqHeader = reqModel.Header;
                    if (string.IsNullOrWhiteSpace(reqHeader.TraceID))
                    {
                        reqHeader.TraceID = Util.GetUniqueCode32();
                    }
                    if (string.IsNullOrWhiteSpace(reqHeader.RpcID))
                    {
                        reqHeader.RpcID = "0";
                    }

                    //HttpContentData.SetTrackID(reqHeader.TraceID);
                    //HttpContentData.SubRpcID = reqHeader.RpcID + ".0";
                    //var header = HttpContentData.CloneRequestHeader(reqModel.Header);
                    //header.RpcID = header.RpcID + ".0";
                }
                else
                {
                    reqHeader = TracingContextData.GetDefaultRequestHeader();
                    //HttpContentData.SetTrackID(reqHeader.TraceID);
                }
                TracingContextData.SetSubRpcID(reqHeader.RpcID + ".0");
                TracingContextData.SetRequestHeader(reqHeader);
                //HttpContentData.RequestHeader = reqHeader;

                //Not To Log
                if (!actionContext.HasMarkerAttribute<NotToLogAttribute>())
                {
                    TraceLogs trace = new TraceLogs();
                    trace.ContextType = ContextType.Server.ToString();
                    trace.StartTime = DateTime.Now;
                    trace.MachineAddr = Util.TracingContextHelper.GetServerAddress();
                    trace.TraceId = reqHeader.TraceID;
                    trace.RpcId = reqHeader.RpcID;
                    trace.Protocol = actionContext.Request.RequestUri.Scheme;

                    trace.Environment = this.environment ?? EnvironmentConfig.Environment;
                    trace.SystemID = this.systemID ?? EnvironmentConfig.SystemID;
                    trace.SystemName = this.systemName ?? EnvironmentConfig.SystemName;

                    //InvokeID
                    trace.InvokeID = request.RequestUri.AbsolutePath;
                    IEnumerable<string> folder;
                    if (actionContext.Request.Headers.TryGetValues(Config.ResponseHeaderFolderKey, out folder))
                    {
                        trace.ServerHost = actionContext.Request.RequestUri.Host + folder.FirstOrDefault();
                    }
                    else
                    {
                        trace.ServerHost = actionContext.Request.RequestUri.Host;
                    }

                    //SearchKey
                    var searchKey = reqModel as ISearchKey;
                    if (searchKey != null)
                    {
                        trace.SearchKey = searchKey.GetSearchKey();
                    }

                    TraceExtensionOnActionExecuting(actionContext, trace);

                    //srs.InvokeID = string.Format("{0}_{1}", actionContext.ControllerContext.ControllerDescriptor.ControllerName.ToLower(), actionContext.ActionDescriptor.ActionName.ToLower());

                    //if (actionContext.ActionArguments != null && actionContext.ActionArguments.Count > 0)
                    //{
                    //    srs.Extension.Add(Config.ParamsKey, actionContext.ActionArguments);
                    //}

                    //ServerRS Log Data TODO

                    Util.TracingContextHelper.SetContextItem(Config.ServerRSKey, trace);
                }
            }

            base.OnActionExecuting(actionContext);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        /// <param name="trace"></param>
        protected virtual void TraceExtensionOnActionExecuted(HttpActionExecutedContext actionExecutedContext, TraceLogs trace)
        {
            if (actionExecutedContext.Response != null)
            {
                IResponseModel responseModel = null;
                if (actionExecutedContext.Response.TryGetContentValue<IResponseModel>(out responseModel))
                {
                    trace.Code = responseModel.GetCode();
                    trace.Extensions.Add(Config.ResultKey, responseModel);

                    //if (responseModel.Extension == null)
                    //{
                    //    responseModel.Extension = new List<Rpc.IContractModel.KeyValue<string, string>>();
                    //}
                    //responseModel.Extension.Add(new Rpc.IContractModel.KeyValue<string, string>(nameof(Raven.Rpc.IContractModel.Header.TraceID), trace.TraceId));
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="actionContext"></param>
        /// <param name="trace"></param>
        protected virtual void TraceExtensionOnActionExecuting(HttpActionContext actionContext, TraceLogs trace)
        {
            trace.Extensions.Add(nameof(actionContext.Request.RequestUri.PathAndQuery), actionContext.Request.RequestUri.PathAndQuery);

            if (actionContext.ActionArguments != null && actionContext.ActionArguments.Count > 0)
            {
                trace.Extensions.Add(Config.ParamsKey, actionContext.ActionArguments);
            }
        }