diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/WebUtil.cs | 277 |
1 files changed, 196 insertions, 81 deletions
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 11967c9..6a40cd5 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs | |||
@@ -53,19 +53,36 @@ namespace OpenSim.Framework | |||
53 | LogManager.GetLogger( | 53 | LogManager.GetLogger( |
54 | MethodBase.GetCurrentMethod().DeclaringType); | 54 | MethodBase.GetCurrentMethod().DeclaringType); |
55 | 55 | ||
56 | private static int m_requestNumber = 0; | 56 | /// <summary> |
57 | /// Request number for diagnostic purposes. | ||
58 | /// </summary> | ||
59 | public static int RequestNumber = 0; | ||
57 | 60 | ||
58 | // this is the header field used to communicate the local request id | 61 | /// <summary> |
59 | // used for performance and debugging | 62 | /// this is the header field used to communicate the local request id |
63 | /// used for performance and debugging | ||
64 | /// </summary> | ||
60 | public const string OSHeaderRequestID = "opensim-request-id"; | 65 | public const string OSHeaderRequestID = "opensim-request-id"; |
61 | 66 | ||
62 | // number of milliseconds a call can take before it is considered | 67 | /// <summary> |
63 | // a "long" call for warning & debugging purposes | 68 | /// Number of milliseconds a call can take before it is considered |
64 | public const int LongCallTime = 500; | 69 | /// a "long" call for warning & debugging purposes |
70 | /// </summary> | ||
71 | public const int LongCallTime = 3000; | ||
72 | |||
73 | /// <summary> | ||
74 | /// The maximum length of any data logged because of a long request time. | ||
75 | /// </summary> | ||
76 | /// <remarks> | ||
77 | /// This is to truncate any really large post data, such as an asset. In theory, the first section should | ||
78 | /// give us useful information about the call (which agent it relates to if applicable, etc.). | ||
79 | /// </remarks> | ||
80 | public const int MaxRequestDiagLength = 100; | ||
65 | 81 | ||
66 | // dictionary of end points | 82 | /// <summary> |
83 | /// Dictionary of end points | ||
84 | /// </summary> | ||
67 | private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>(); | 85 | private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>(); |
68 | |||
69 | 86 | ||
70 | private static object EndPointLock(string url) | 87 | private static object EndPointLock(string url) |
71 | { | 88 | { |
@@ -128,12 +145,13 @@ namespace OpenSim.Framework | |||
128 | 145 | ||
129 | private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed) | 146 | private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed) |
130 | { | 147 | { |
131 | int reqnum = m_requestNumber++; | 148 | int reqnum = RequestNumber++; |
132 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | 149 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); |
133 | 150 | ||
134 | string errorMessage = "unknown error"; | 151 | string errorMessage = "unknown error"; |
135 | int tickstart = Util.EnvironmentTickCount(); | 152 | int tickstart = Util.EnvironmentTickCount(); |
136 | int tickdata = 0; | 153 | int tickdata = 0; |
154 | string strBuffer = null; | ||
137 | 155 | ||
138 | try | 156 | try |
139 | { | 157 | { |
@@ -148,7 +166,7 @@ namespace OpenSim.Framework | |||
148 | // If there is some input, write it into the request | 166 | // If there is some input, write it into the request |
149 | if (data != null) | 167 | if (data != null) |
150 | { | 168 | { |
151 | string strBuffer = OSDParser.SerializeJsonString(data); | 169 | strBuffer = OSDParser.SerializeJsonString(data); |
152 | byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); | 170 | byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); |
153 | 171 | ||
154 | if (compressed) | 172 | if (compressed) |
@@ -209,11 +227,18 @@ namespace OpenSim.Framework | |||
209 | } | 227 | } |
210 | finally | 228 | finally |
211 | { | 229 | { |
212 | // This just dumps a warning for any operation that takes more than 100 ms | ||
213 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | 230 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); |
214 | if (tickdiff > LongCallTime) | 231 | if (tickdiff > LongCallTime) |
215 | m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", | 232 | m_log.InfoFormat( |
216 | reqnum,url,method,tickdiff,tickdata); | 233 | "[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", |
234 | reqnum, | ||
235 | method, | ||
236 | url, | ||
237 | tickdiff, | ||
238 | tickdata, | ||
239 | strBuffer != null | ||
240 | ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) | ||
241 | : ""); | ||
217 | } | 242 | } |
218 | 243 | ||
219 | m_log.DebugFormat( | 244 | m_log.DebugFormat( |
@@ -291,17 +316,17 @@ namespace OpenSim.Framework | |||
291 | 316 | ||
292 | private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout) | 317 | private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout) |
293 | { | 318 | { |
294 | int reqnum = m_requestNumber++; | 319 | int reqnum = RequestNumber++; |
295 | string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; | 320 | string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; |
296 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method); | 321 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method); |
297 | 322 | ||
298 | string errorMessage = "unknown error"; | 323 | string errorMessage = "unknown error"; |
299 | int tickstart = Util.EnvironmentTickCount(); | 324 | int tickstart = Util.EnvironmentTickCount(); |
300 | int tickdata = 0; | 325 | int tickdata = 0; |
326 | string queryString = null; | ||
301 | 327 | ||
302 | try | 328 | try |
303 | { | 329 | { |
304 | |||
305 | HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); | 330 | HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); |
306 | request.Method = "POST"; | 331 | request.Method = "POST"; |
307 | request.Timeout = timeout; | 332 | request.Timeout = timeout; |
@@ -312,7 +337,7 @@ namespace OpenSim.Framework | |||
312 | 337 | ||
313 | if (data != null) | 338 | if (data != null) |
314 | { | 339 | { |
315 | string queryString = BuildQueryString(data); | 340 | queryString = BuildQueryString(data); |
316 | byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); | 341 | byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); |
317 | 342 | ||
318 | request.ContentLength = buffer.Length; | 343 | request.ContentLength = buffer.Length; |
@@ -355,11 +380,19 @@ namespace OpenSim.Framework | |||
355 | { | 380 | { |
356 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | 381 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); |
357 | if (tickdiff > LongCallTime) | 382 | if (tickdiff > LongCallTime) |
358 | m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", | 383 | m_log.InfoFormat( |
359 | reqnum,url,method,tickdiff,tickdata); | 384 | "[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", |
385 | reqnum, | ||
386 | method, | ||
387 | url, | ||
388 | tickdiff, | ||
389 | tickdata, | ||
390 | queryString != null | ||
391 | ? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString | ||
392 | : ""); | ||
360 | } | 393 | } |
361 | 394 | ||
362 | m_log.WarnFormat("[WEB UTIL]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage); | 395 | m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage); |
363 | 396 | ||
364 | return ErrorResponseMap(errorMessage); | 397 | return ErrorResponseMap(errorMessage); |
365 | } | 398 | } |
@@ -640,8 +673,6 @@ namespace OpenSim.Framework | |||
640 | 673 | ||
641 | return new string[0]; | 674 | return new string[0]; |
642 | } | 675 | } |
643 | |||
644 | |||
645 | } | 676 | } |
646 | 677 | ||
647 | public static class AsynchronousRestObjectRequester | 678 | public static class AsynchronousRestObjectRequester |
@@ -664,6 +695,12 @@ namespace OpenSim.Framework | |||
664 | public static void MakeRequest<TRequest, TResponse>(string verb, | 695 | public static void MakeRequest<TRequest, TResponse>(string verb, |
665 | string requestUrl, TRequest obj, Action<TResponse> action) | 696 | string requestUrl, TRequest obj, Action<TResponse> action) |
666 | { | 697 | { |
698 | int reqnum = WebUtil.RequestNumber++; | ||
699 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | ||
700 | |||
701 | int tickstart = Util.EnvironmentTickCount(); | ||
702 | int tickdata = 0; | ||
703 | |||
667 | // m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl); | 704 | // m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl); |
668 | 705 | ||
669 | Type type = typeof(TRequest); | 706 | Type type = typeof(TRequest); |
@@ -674,12 +711,13 @@ namespace OpenSim.Framework | |||
674 | XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); | 711 | XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); |
675 | 712 | ||
676 | request.Method = verb; | 713 | request.Method = verb; |
714 | MemoryStream buffer = null; | ||
677 | 715 | ||
678 | if (verb == "POST") | 716 | if (verb == "POST") |
679 | { | 717 | { |
680 | request.ContentType = "text/xml"; | 718 | request.ContentType = "text/xml"; |
681 | 719 | ||
682 | MemoryStream buffer = new MemoryStream(); | 720 | buffer = new MemoryStream(); |
683 | 721 | ||
684 | XmlWriterSettings settings = new XmlWriterSettings(); | 722 | XmlWriterSettings settings = new XmlWriterSettings(); |
685 | settings.Encoding = Encoding.UTF8; | 723 | settings.Encoding = Encoding.UTF8; |
@@ -701,6 +739,9 @@ namespace OpenSim.Framework | |||
701 | requestStream.Write(buffer.ToArray(), 0, length); | 739 | requestStream.Write(buffer.ToArray(), 0, length); |
702 | requestStream.Close(); | 740 | requestStream.Close(); |
703 | 741 | ||
742 | // capture how much time was spent writing | ||
743 | tickdata = Util.EnvironmentTickCountSubtract(tickstart); | ||
744 | |||
704 | request.BeginGetResponse(delegate(IAsyncResult ar) | 745 | request.BeginGetResponse(delegate(IAsyncResult ar) |
705 | { | 746 | { |
706 | response = request.EndGetResponse(ar); | 747 | response = request.EndGetResponse(ar); |
@@ -726,88 +767,108 @@ namespace OpenSim.Framework | |||
726 | 767 | ||
727 | }, null); | 768 | }, null); |
728 | }, null); | 769 | }, null); |
729 | |||
730 | |||
731 | return; | ||
732 | } | 770 | } |
733 | 771 | else | |
734 | request.BeginGetResponse(delegate(IAsyncResult res2) | ||
735 | { | 772 | { |
736 | try | 773 | request.BeginGetResponse(delegate(IAsyncResult res2) |
737 | { | 774 | { |
738 | // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't | ||
739 | // documented in MSDN | ||
740 | response = request.EndGetResponse(res2); | ||
741 | |||
742 | Stream respStream = null; | ||
743 | try | 775 | try |
744 | { | 776 | { |
745 | respStream = response.GetResponseStream(); | 777 | // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't |
746 | deserial = (TResponse)deserializer.Deserialize(respStream); | 778 | // documented in MSDN |
747 | } | 779 | response = request.EndGetResponse(res2); |
748 | catch (System.InvalidOperationException) | 780 | |
749 | { | 781 | Stream respStream = null; |
750 | } | 782 | try |
751 | finally | 783 | { |
752 | { | 784 | respStream = response.GetResponseStream(); |
753 | respStream.Close(); | 785 | deserial = (TResponse)deserializer.Deserialize(respStream); |
754 | response.Close(); | 786 | } |
787 | catch (System.InvalidOperationException) | ||
788 | { | ||
789 | } | ||
790 | finally | ||
791 | { | ||
792 | respStream.Close(); | ||
793 | response.Close(); | ||
794 | } | ||
755 | } | 795 | } |
756 | } | 796 | catch (WebException e) |
757 | catch (WebException e) | ||
758 | { | ||
759 | if (e.Status == WebExceptionStatus.ProtocolError) | ||
760 | { | 797 | { |
761 | if (e.Response is HttpWebResponse) | 798 | if (e.Status == WebExceptionStatus.ProtocolError) |
762 | { | 799 | { |
763 | HttpWebResponse httpResponse = (HttpWebResponse)e.Response; | 800 | if (e.Response is HttpWebResponse) |
764 | |||
765 | if (httpResponse.StatusCode != HttpStatusCode.NotFound) | ||
766 | { | 801 | { |
767 | // We don't appear to be handling any other status codes, so log these feailures to that | 802 | HttpWebResponse httpResponse = (HttpWebResponse)e.Response; |
768 | // people don't spend unnecessary hours hunting phantom bugs. | 803 | |
769 | m_log.DebugFormat( | 804 | if (httpResponse.StatusCode != HttpStatusCode.NotFound) |
770 | "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", | 805 | { |
771 | verb, requestUrl, httpResponse.StatusCode); | 806 | // We don't appear to be handling any other status codes, so log these feailures to that |
807 | // people don't spend unnecessary hours hunting phantom bugs. | ||
808 | m_log.DebugFormat( | ||
809 | "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", | ||
810 | verb, requestUrl, httpResponse.StatusCode); | ||
811 | } | ||
772 | } | 812 | } |
773 | } | 813 | } |
814 | else | ||
815 | { | ||
816 | m_log.ErrorFormat( | ||
817 | "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", | ||
818 | verb, requestUrl, e.Status, e.Message); | ||
819 | } | ||
774 | } | 820 | } |
775 | else | 821 | catch (Exception e) |
776 | { | 822 | { |
777 | m_log.ErrorFormat( | 823 | m_log.ErrorFormat( |
778 | "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", | 824 | "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", |
779 | verb, requestUrl, e.Status, e.Message); | 825 | verb, requestUrl, e.Message, e.StackTrace); |
780 | } | 826 | } |
781 | } | 827 | |
782 | catch (Exception e) | 828 | // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); |
783 | { | 829 | |
784 | m_log.ErrorFormat( | 830 | try |
785 | "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", | 831 | { |
786 | verb, requestUrl, e.Message, e.StackTrace); | 832 | action(deserial); |
787 | } | 833 | } |
834 | catch (Exception e) | ||
835 | { | ||
836 | m_log.ErrorFormat( | ||
837 | "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}", | ||
838 | verb, requestUrl, e.Message, e.StackTrace); | ||
839 | } | ||
840 | |||
841 | }, null); | ||
842 | } | ||
788 | 843 | ||
789 | // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); | 844 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); |
845 | if (tickdiff > WebUtil.LongCallTime) | ||
846 | { | ||
847 | string originalRequest = null; | ||
790 | 848 | ||
791 | try | 849 | if (buffer != null) |
792 | { | ||
793 | action(deserial); | ||
794 | } | ||
795 | catch (Exception e) | ||
796 | { | 850 | { |
797 | m_log.ErrorFormat( | 851 | originalRequest = Encoding.UTF8.GetString(buffer.ToArray()); |
798 | "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}", | 852 | |
799 | verb, requestUrl, e.Message, e.StackTrace); | 853 | if (originalRequest.Length > WebUtil.MaxRequestDiagLength) |
854 | originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); | ||
800 | } | 855 | } |
801 | 856 | ||
802 | }, null); | 857 | m_log.InfoFormat( |
858 | "[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", | ||
859 | reqnum, | ||
860 | verb, | ||
861 | requestUrl, | ||
862 | tickdiff, | ||
863 | tickdata, | ||
864 | originalRequest); | ||
865 | } | ||
803 | } | 866 | } |
804 | } | 867 | } |
805 | 868 | ||
806 | public static class SynchronousRestFormsRequester | 869 | public static class SynchronousRestFormsRequester |
807 | { | 870 | { |
808 | private static readonly ILog m_log = | 871 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
809 | LogManager.GetLogger( | ||
810 | MethodBase.GetCurrentMethod().DeclaringType); | ||
811 | 872 | ||
812 | /// <summary> | 873 | /// <summary> |
813 | /// Perform a synchronous REST request. | 874 | /// Perform a synchronous REST request. |
@@ -821,6 +882,12 @@ namespace OpenSim.Framework | |||
821 | /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> | 882 | /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> |
822 | public static string MakeRequest(string verb, string requestUrl, string obj) | 883 | public static string MakeRequest(string verb, string requestUrl, string obj) |
823 | { | 884 | { |
885 | int reqnum = WebUtil.RequestNumber++; | ||
886 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | ||
887 | |||
888 | int tickstart = Util.EnvironmentTickCount(); | ||
889 | int tickdata = 0; | ||
890 | |||
824 | WebRequest request = WebRequest.Create(requestUrl); | 891 | WebRequest request = WebRequest.Create(requestUrl); |
825 | request.Method = verb; | 892 | request.Method = verb; |
826 | string respstring = String.Empty; | 893 | string respstring = String.Empty; |
@@ -856,6 +923,9 @@ namespace OpenSim.Framework | |||
856 | { | 923 | { |
857 | if (requestStream != null) | 924 | if (requestStream != null) |
858 | requestStream.Close(); | 925 | requestStream.Close(); |
926 | |||
927 | // capture how much time was spent writing | ||
928 | tickdata = Util.EnvironmentTickCountSubtract(tickstart); | ||
859 | } | 929 | } |
860 | } | 930 | } |
861 | 931 | ||
@@ -894,6 +964,18 @@ namespace OpenSim.Framework | |||
894 | m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl); | 964 | m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl); |
895 | } | 965 | } |
896 | } | 966 | } |
967 | |||
968 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | ||
969 | if (tickdiff > WebUtil.LongCallTime) | ||
970 | m_log.InfoFormat( | ||
971 | "[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", | ||
972 | reqnum, | ||
973 | verb, | ||
974 | requestUrl, | ||
975 | tickdiff, | ||
976 | tickdata, | ||
977 | obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj); | ||
978 | |||
897 | return respstring; | 979 | return respstring; |
898 | } | 980 | } |
899 | } | 981 | } |
@@ -921,6 +1003,12 @@ namespace OpenSim.Framework | |||
921 | 1003 | ||
922 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout) | 1004 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout) |
923 | { | 1005 | { |
1006 | int reqnum = WebUtil.RequestNumber++; | ||
1007 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | ||
1008 | |||
1009 | int tickstart = Util.EnvironmentTickCount(); | ||
1010 | int tickdata = 0; | ||
1011 | |||
924 | Type type = typeof(TRequest); | 1012 | Type type = typeof(TRequest); |
925 | TResponse deserial = default(TResponse); | 1013 | TResponse deserial = default(TResponse); |
926 | 1014 | ||
@@ -928,12 +1016,13 @@ namespace OpenSim.Framework | |||
928 | request.Method = verb; | 1016 | request.Method = verb; |
929 | if (pTimeout != 0) | 1017 | if (pTimeout != 0) |
930 | request.Timeout = pTimeout * 1000; | 1018 | request.Timeout = pTimeout * 1000; |
1019 | MemoryStream buffer = null; | ||
931 | 1020 | ||
932 | if ((verb == "POST") || (verb == "PUT")) | 1021 | if ((verb == "POST") || (verb == "PUT")) |
933 | { | 1022 | { |
934 | request.ContentType = "text/xml"; | 1023 | request.ContentType = "text/xml"; |
935 | 1024 | ||
936 | MemoryStream buffer = new MemoryStream(); | 1025 | buffer = new MemoryStream(); |
937 | 1026 | ||
938 | XmlWriterSettings settings = new XmlWriterSettings(); | 1027 | XmlWriterSettings settings = new XmlWriterSettings(); |
939 | settings.Encoding = Encoding.UTF8; | 1028 | settings.Encoding = Encoding.UTF8; |
@@ -966,6 +1055,9 @@ namespace OpenSim.Framework | |||
966 | { | 1055 | { |
967 | if (requestStream != null) | 1056 | if (requestStream != null) |
968 | requestStream.Close(); | 1057 | requestStream.Close(); |
1058 | |||
1059 | // capture how much time was spent writing | ||
1060 | tickdata = Util.EnvironmentTickCountSubtract(tickstart); | ||
969 | } | 1061 | } |
970 | } | 1062 | } |
971 | 1063 | ||
@@ -1013,7 +1105,30 @@ namespace OpenSim.Framework | |||
1013 | verb, requestUrl, e.Message, e.StackTrace); | 1105 | verb, requestUrl, e.Message, e.StackTrace); |
1014 | } | 1106 | } |
1015 | 1107 | ||
1108 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | ||
1109 | if (tickdiff > WebUtil.LongCallTime) | ||
1110 | { | ||
1111 | string originalRequest = null; | ||
1112 | |||
1113 | if (buffer != null) | ||
1114 | { | ||
1115 | originalRequest = Encoding.UTF8.GetString(buffer.ToArray()); | ||
1116 | |||
1117 | if (originalRequest.Length > WebUtil.MaxRequestDiagLength) | ||
1118 | originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); | ||
1119 | } | ||
1120 | |||
1121 | m_log.InfoFormat( | ||
1122 | "[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", | ||
1123 | reqnum, | ||
1124 | verb, | ||
1125 | requestUrl, | ||
1126 | tickdiff, | ||
1127 | tickdata, | ||
1128 | originalRequest); | ||
1129 | } | ||
1130 | |||
1016 | return deserial; | 1131 | return deserial; |
1017 | } | 1132 | } |
1018 | } | 1133 | } |
1019 | } \ No newline at end of file | 1134 | } |