diff options
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 4 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 111 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 100 |
3 files changed, 215 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 34cad7b..101a44b 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -4905,6 +4905,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4905 | /// <param name="throttlePacketType">Throttling category for the packet</param> | 4905 | /// <param name="throttlePacketType">Throttling category for the packet</param> |
4906 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) | 4906 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) |
4907 | { | 4907 | { |
4908 | #region BinaryStats | ||
4909 | LLUDPServer.LogPacketHeader(false, m_circuitCode, 0, packet.Type, (ushort)packet.Length); | ||
4910 | #endregion BinaryStats | ||
4911 | |||
4908 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); | 4912 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); |
4909 | } | 4913 | } |
4910 | 4914 | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 6165984..c773c05 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | ||
30 | using System.Net; | 31 | using System.Net; |
31 | using System.Net.Sockets; | 32 | using System.Net.Sockets; |
32 | using System.Reflection; | 33 | using System.Reflection; |
@@ -204,6 +205,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
204 | TextureSendLimit = 20; | 205 | TextureSendLimit = 20; |
205 | } | 206 | } |
206 | 207 | ||
208 | #region BinaryStats | ||
209 | config = configSource.Configs["Statistics.Binary"]; | ||
210 | m_shouldCollectStats = false; | ||
211 | if (config != null) | ||
212 | { | ||
213 | if (config.Contains("enabled") && config.GetBoolean("enabled")) | ||
214 | { | ||
215 | if (config.Contains("collect_packet_headers")) | ||
216 | m_shouldCollectStats = config.GetBoolean("collect_packet_headers"); | ||
217 | if (config.Contains("packet_headers_period_seconds")) | ||
218 | { | ||
219 | binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("region_stats_period_seconds")); | ||
220 | } | ||
221 | if (config.Contains("stats_dir")) | ||
222 | { | ||
223 | binStatsDir = config.GetString("stats_dir"); | ||
224 | } | ||
225 | } | ||
226 | else | ||
227 | { | ||
228 | m_shouldCollectStats = false; | ||
229 | } | ||
230 | } | ||
231 | #endregion BinaryStats | ||
232 | |||
207 | m_throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps); | 233 | m_throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps); |
208 | m_throttleRates = new ThrottleRates(configSource); | 234 | m_throttleRates = new ThrottleRates(configSource); |
209 | } | 235 | } |
@@ -679,6 +705,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
679 | 705 | ||
680 | #endregion Incoming Packet Accounting | 706 | #endregion Incoming Packet Accounting |
681 | 707 | ||
708 | #region BinaryStats | ||
709 | LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length); | ||
710 | #endregion BinaryStats | ||
711 | |||
682 | #region Ping Check Handling | 712 | #region Ping Check Handling |
683 | 713 | ||
684 | if (packet.Type == PacketType.StartPingCheck) | 714 | if (packet.Type == PacketType.StartPingCheck) |
@@ -700,6 +730,87 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
700 | packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); | 730 | packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); |
701 | } | 731 | } |
702 | 732 | ||
733 | #region BinaryStats | ||
734 | |||
735 | public class PacketLogger | ||
736 | { | ||
737 | public DateTime StartTime; | ||
738 | public string Path = null; | ||
739 | public System.IO.BinaryWriter Log = null; | ||
740 | } | ||
741 | |||
742 | public static PacketLogger PacketLog; | ||
743 | |||
744 | protected static bool m_shouldCollectStats = false; | ||
745 | // Number of seconds to log for | ||
746 | static TimeSpan binStatsMaxFilesize = TimeSpan.FromSeconds(300); | ||
747 | static object binStatsLogLock = new object(); | ||
748 | static string binStatsDir = ""; | ||
749 | |||
750 | public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size) | ||
751 | { | ||
752 | if (!m_shouldCollectStats) return; | ||
753 | |||
754 | // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size | ||
755 | |||
756 | // Put the incoming bit into the least significant bit of the flags byte | ||
757 | if (incoming) | ||
758 | flags |= 0x01; | ||
759 | else | ||
760 | flags &= 0xFE; | ||
761 | |||
762 | // Put the flags byte into the most significant bits of the type integer | ||
763 | uint type = (uint)packetType; | ||
764 | type |= (uint)flags << 24; | ||
765 | |||
766 | // m_log.Debug("1 LogPacketHeader(): Outside lock"); | ||
767 | lock (binStatsLogLock) | ||
768 | { | ||
769 | DateTime now = DateTime.Now; | ||
770 | |||
771 | // m_log.Debug("2 LogPacketHeader(): Inside lock. now is " + now.Ticks); | ||
772 | try | ||
773 | { | ||
774 | if (PacketLog == null || (now > PacketLog.StartTime + binStatsMaxFilesize)) | ||
775 | { | ||
776 | if (PacketLog != null && PacketLog.Log != null) | ||
777 | { | ||
778 | PacketLog.Log.Close(); | ||
779 | } | ||
780 | |||
781 | // First log file or time has expired, start writing to a new log file | ||
782 | PacketLog = new PacketLogger(); | ||
783 | PacketLog.StartTime = now; | ||
784 | PacketLog.Path = (binStatsDir.Length > 0 ? binStatsDir + System.IO.Path.DirectorySeparatorChar.ToString() : "") | ||
785 | + String.Format("packets-{0}.log", now.ToString("yyyyMMddHHmmss")); | ||
786 | PacketLog.Log = new BinaryWriter(File.Open(PacketLog.Path, FileMode.Append, FileAccess.Write)); | ||
787 | } | ||
788 | |||
789 | // Serialize the data | ||
790 | byte[] output = new byte[18]; | ||
791 | Buffer.BlockCopy(BitConverter.GetBytes(now.Ticks), 0, output, 0, 8); | ||
792 | Buffer.BlockCopy(BitConverter.GetBytes(circuit), 0, output, 8, 4); | ||
793 | Buffer.BlockCopy(BitConverter.GetBytes(type), 0, output, 12, 4); | ||
794 | Buffer.BlockCopy(BitConverter.GetBytes(size), 0, output, 16, 2); | ||
795 | |||
796 | // Write the serialized data to disk | ||
797 | if (PacketLog != null && PacketLog.Log != null) | ||
798 | PacketLog.Log.Write(output); | ||
799 | } | ||
800 | catch (Exception ex) | ||
801 | { | ||
802 | m_log.Error("Packet statistics gathering failed: " + ex.Message, ex); | ||
803 | if (PacketLog.Log != null) | ||
804 | { | ||
805 | PacketLog.Log.Close(); | ||
806 | } | ||
807 | PacketLog = null; | ||
808 | } | ||
809 | } | ||
810 | } | ||
811 | |||
812 | #endregion BinaryStats | ||
813 | |||
703 | private void HandleUseCircuitCode(object o) | 814 | private void HandleUseCircuitCode(object o) |
704 | { | 815 | { |
705 | object[] array = (object[])o; | 816 | object[] array = (object[])o; |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 093ca3e..6edef11 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -36,6 +36,7 @@ using System.Timers; | |||
36 | using System.Xml; | 36 | using System.Xml; |
37 | using Nini.Config; | 37 | using Nini.Config; |
38 | using OpenMetaverse; | 38 | using OpenMetaverse; |
39 | using OpenMetaverse.Packets; | ||
39 | using OpenMetaverse.Imaging; | 40 | using OpenMetaverse.Imaging; |
40 | using OpenSim.Framework; | 41 | using OpenSim.Framework; |
41 | using OpenSim.Services.Interfaces; | 42 | using OpenSim.Services.Interfaces; |
@@ -397,6 +398,73 @@ namespace OpenSim.Region.Framework.Scenes | |||
397 | 398 | ||
398 | #endregion | 399 | #endregion |
399 | 400 | ||
401 | #region BinaryStats | ||
402 | |||
403 | public class StatLogger | ||
404 | { | ||
405 | public DateTime StartTime; | ||
406 | public string Path; | ||
407 | public System.IO.BinaryWriter Log; | ||
408 | } | ||
409 | static StatLogger m_statLog = null; | ||
410 | static TimeSpan m_statLogPeriod = TimeSpan.FromSeconds(300); | ||
411 | static string m_statsDir = String.Empty; | ||
412 | static Object m_statLockObject = new Object(); | ||
413 | private void LogSimStats(SimStats stats) | ||
414 | { | ||
415 | SimStatsPacket pack = new SimStatsPacket(); | ||
416 | pack.Region = new SimStatsPacket.RegionBlock(); | ||
417 | pack.Region.RegionX = stats.RegionX; | ||
418 | pack.Region.RegionY = stats.RegionY; | ||
419 | pack.Region.RegionFlags = stats.RegionFlags; | ||
420 | pack.Region.ObjectCapacity = stats.ObjectCapacity; | ||
421 | //pack.Region = //stats.RegionBlock; | ||
422 | pack.Stat = stats.StatsBlock; | ||
423 | pack.Header.Reliable = false; | ||
424 | |||
425 | // note that we are inside the reporter lock when called | ||
426 | DateTime now = DateTime.Now; | ||
427 | |||
428 | // hide some time information into the packet | ||
429 | pack.Header.Sequence = (uint)now.Ticks; | ||
430 | |||
431 | lock (m_statLockObject) // m_statLog is shared so make sure there is only executer here | ||
432 | { | ||
433 | try | ||
434 | { | ||
435 | if (m_statLog == null || now > m_statLog.StartTime + m_statLogPeriod) | ||
436 | { | ||
437 | // First log file or time has expired, start writing to a new log file | ||
438 | if (m_statLog != null && m_statLog.Log != null) | ||
439 | { | ||
440 | m_statLog.Log.Close(); | ||
441 | } | ||
442 | m_statLog = new StatLogger(); | ||
443 | m_statLog.StartTime = now; | ||
444 | m_statLog.Path = (m_statsDir.Length > 0 ? m_statsDir + System.IO.Path.DirectorySeparatorChar.ToString() : "") | ||
445 | + String.Format("stats-{0}.log", now.ToString("yyyyMMddHHmmss")); | ||
446 | m_statLog.Log = new BinaryWriter(File.Open(m_statLog.Path, FileMode.Append, FileAccess.Write)); | ||
447 | } | ||
448 | |||
449 | // Write the serialized data to disk | ||
450 | if (m_statLog != null && m_statLog.Log != null) | ||
451 | m_statLog.Log.Write(pack.ToBytes()); | ||
452 | } | ||
453 | catch (Exception ex) | ||
454 | { | ||
455 | m_log.Error("statistics gathering failed: " + ex.Message, ex); | ||
456 | if (m_statLog != null && m_statLog.Log != null) | ||
457 | { | ||
458 | m_statLog.Log.Close(); | ||
459 | } | ||
460 | m_statLog = null; | ||
461 | } | ||
462 | } | ||
463 | return; | ||
464 | } | ||
465 | |||
466 | #endregion | ||
467 | |||
400 | #region Constructors | 468 | #region Constructors |
401 | 469 | ||
402 | public Scene(RegionInfo regInfo, AgentCircuitManager authen, | 470 | public Scene(RegionInfo regInfo, AgentCircuitManager authen, |
@@ -582,6 +650,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
582 | } | 650 | } |
583 | 651 | ||
584 | m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); | 652 | m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); |
653 | |||
654 | #region BinaryStats | ||
655 | |||
656 | try | ||
657 | { | ||
658 | IConfig statConfig = m_config.Configs["Statistics.Binary"]; | ||
659 | if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled")) | ||
660 | { | ||
661 | if (statConfig.Contains("collect_region_stats")) | ||
662 | { | ||
663 | if (statConfig.GetBoolean("collect_region_stats")) | ||
664 | { | ||
665 | // if enabled, add us to the event. If not enabled, I won't get called | ||
666 | StatsReporter.OnSendStatsResult += LogSimStats; | ||
667 | } | ||
668 | } | ||
669 | if (statConfig.Contains("region_stats_period_seconds")) | ||
670 | { | ||
671 | m_statLogPeriod = TimeSpan.FromSeconds(statConfig.GetInt("region_stats_period_seconds")); | ||
672 | } | ||
673 | if (statConfig.Contains("stats_dir")) | ||
674 | { | ||
675 | m_statsDir = statConfig.GetString("stats_dir"); | ||
676 | } | ||
677 | } | ||
678 | } | ||
679 | catch | ||
680 | { | ||
681 | // if it doesn't work, we don't collect anything | ||
682 | } | ||
683 | |||
684 | #endregion BinaryStats | ||
585 | } | 685 | } |
586 | catch | 686 | catch |
587 | { | 687 | { |