diff --git a/trunk/OpenSim/Framework/ServerStatus/ServerStatus.cs b/trunk/OpenSim/Framework/ServerStatus/ServerStatus.cs new file mode 100644 index 0000000000..20f42cfae8 --- /dev/null +++ b/trunk/OpenSim/Framework/ServerStatus/ServerStatus.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Diagnostics; +using System.Web; + +namespace OpenSim.Framework.ServerStatus +{ + public class ServerStatus + { + static StatusWindow m_window = null; + static Thread m_thread = null; + + static public void ReportOutPacketUdp(int size, bool resent) + { + StatusWindow.ReportOutPacketUdp(size, resent); + } + + static public void ReportInPacketUdp(int size) + { + StatusWindow.ReportInPacketUdp(size); + } + + static public void ReportOutPacketTcp(int size) + { + StatusWindow.ReportOutPacketTcp(size); + } + + static public void ReportInPacketTcp(int size) + { + StatusWindow.ReportInPacketTcp(size); + } + + static public void ReportProcessedInPacket(string name, int size) + { + if (m_window != null) + StatusWindow.ReportProcessedInPacket(name, size); + } + + static public void ReportProcessedOutPacket(string name, int size, bool resent) + { + if (m_window != null) + StatusWindow.ReportProcessedOutPacket(name, size, resent); + } + + static public void ReportThreadName(string name) + { + StatusWindow.ReportThreadName(AppDomain.GetCurrentThreadId(), name); + } + + static public void ShowWindow() + { + if (m_window == null) + { + m_window = new StatusWindow(); + + m_thread = new Thread(new ThreadStart(run)); + m_thread.IsBackground = true; + m_thread.Start(); + } + else + { + m_window.Show(); + } + } + + static void run() + { + ReportThreadName("ServerStatus"); + m_window.ShowDialog(); + m_window.CloseStatusWindow(); + m_window = null; + m_thread = null; + } + } +} diff --git a/trunk/OpenSim/Framework/ServerStatus/StatusWindow.Designer.cs b/trunk/OpenSim/Framework/ServerStatus/StatusWindow.Designer.cs new file mode 100644 index 0000000000..d9ab71a5bd --- /dev/null +++ b/trunk/OpenSim/Framework/ServerStatus/StatusWindow.Designer.cs @@ -0,0 +1,525 @@ +namespace OpenSim.Framework.ServerStatus +{ + partial class StatusWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.panel1 = new System.Windows.Forms.Panel(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabThreads = new System.Windows.Forms.TabPage(); + this.tabNetwork = new System.Windows.Forms.TabPage(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.m_outTotalTraffic = new System.Windows.Forms.Label(); + this.m_inTotalTraffic = new System.Windows.Forms.Label(); + this.label11 = new System.Windows.Forms.Label(); + this.label12 = new System.Windows.Forms.Label(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.m_outTcpTraffic = new System.Windows.Forms.Label(); + this.m_inTcpTraffic = new System.Windows.Forms.Label(); + this.label7 = new System.Windows.Forms.Label(); + this.label8 = new System.Windows.Forms.Label(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.m_outUdpTraffic = new System.Windows.Forms.Label(); + this.m_inUdpTraffic = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.m_networkDrawing = new System.Windows.Forms.PictureBox(); + this.tabMemory = new System.Windows.Forms.TabPage(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.m_memStats = new System.Windows.Forms.PictureBox(); + this.groupBox5 = new System.Windows.Forms.GroupBox(); + this.m_callGCButton = new System.Windows.Forms.Button(); + this.m_availableMem = new System.Windows.Forms.Label(); + this.m_commitSize = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.tabCpu = new System.Windows.Forms.TabPage(); + this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); + this.m_cpuDrawing = new System.Windows.Forms.PictureBox(); + this.tabPackets = new System.Windows.Forms.TabPage(); + this.panel1.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this.tabNetwork.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.groupBox2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.m_networkDrawing)).BeginInit(); + this.tabMemory.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.m_memStats)).BeginInit(); + this.groupBox5.SuspendLayout(); + this.tabCpu.SuspendLayout(); + this.tableLayoutPanel3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.m_cpuDrawing)).BeginInit(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Controls.Add(this.tabControl1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(604, 550); + this.panel1.TabIndex = 0; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabThreads); + this.tabControl1.Controls.Add(this.tabNetwork); + this.tabControl1.Controls.Add(this.tabMemory); + this.tabControl1.Controls.Add(this.tabCpu); + this.tabControl1.Controls.Add(this.tabPackets); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 0); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(604, 550); + this.tabControl1.TabIndex = 0; + // + // tabThreads + // + this.tabThreads.Location = new System.Drawing.Point(4, 22); + this.tabThreads.Name = "tabThreads"; + this.tabThreads.Padding = new System.Windows.Forms.Padding(3); + this.tabThreads.Size = new System.Drawing.Size(596, 524); + this.tabThreads.TabIndex = 0; + this.tabThreads.Text = "Threads"; + this.tabThreads.UseVisualStyleBackColor = true; + // + // tabNetwork + // + this.tabNetwork.Controls.Add(this.tableLayoutPanel1); + this.tabNetwork.Location = new System.Drawing.Point(4, 22); + this.tabNetwork.Name = "tabNetwork"; + this.tabNetwork.Padding = new System.Windows.Forms.Padding(3); + this.tabNetwork.Size = new System.Drawing.Size(596, 524); + this.tabNetwork.TabIndex = 1; + this.tabNetwork.Text = "Network"; + this.tabNetwork.UseVisualStyleBackColor = true; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Controls.Add(this.groupBox1, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.m_networkDrawing, 0, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 94F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(590, 518); + this.tableLayoutPanel1.TabIndex = 0; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.groupBox4); + this.groupBox1.Controls.Add(this.groupBox3); + this.groupBox1.Controls.Add(this.groupBox2); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(3, 427); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(584, 88); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Traffic"; + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.m_outTotalTraffic); + this.groupBox4.Controls.Add(this.m_inTotalTraffic); + this.groupBox4.Controls.Add(this.label11); + this.groupBox4.Controls.Add(this.label12); + this.groupBox4.Location = new System.Drawing.Point(319, 20); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(148, 55); + this.groupBox4.TabIndex = 0; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "Total"; + // + // m_outTotalTraffic + // + this.m_outTotalTraffic.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.m_outTotalTraffic.Location = new System.Drawing.Point(43, 29); + this.m_outTotalTraffic.Name = "m_outTotalTraffic"; + this.m_outTotalTraffic.Size = new System.Drawing.Size(90, 13); + this.m_outTotalTraffic.TabIndex = 1; + this.m_outTotalTraffic.Text = "0,00 kB/s"; + // + // m_inTotalTraffic + // + this.m_inTotalTraffic.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.m_inTotalTraffic.Location = new System.Drawing.Point(43, 16); + this.m_inTotalTraffic.Name = "m_inTotalTraffic"; + this.m_inTotalTraffic.Size = new System.Drawing.Size(90, 13); + this.m_inTotalTraffic.TabIndex = 1; + this.m_inTotalTraffic.Text = "0,00 kB/s"; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(10, 29); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(27, 13); + this.label11.TabIndex = 0; + this.label11.Text = "Out:"; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Location = new System.Drawing.Point(10, 16); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(19, 13); + this.label12.TabIndex = 0; + this.label12.Text = "In:"; + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.m_outTcpTraffic); + this.groupBox3.Controls.Add(this.m_inTcpTraffic); + this.groupBox3.Controls.Add(this.label7); + this.groupBox3.Controls.Add(this.label8); + this.groupBox3.Location = new System.Drawing.Point(165, 20); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(148, 55); + this.groupBox3.TabIndex = 0; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "Tcp"; + // + // m_outTcpTraffic + // + this.m_outTcpTraffic.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.m_outTcpTraffic.Location = new System.Drawing.Point(43, 29); + this.m_outTcpTraffic.Name = "m_outTcpTraffic"; + this.m_outTcpTraffic.Size = new System.Drawing.Size(90, 13); + this.m_outTcpTraffic.TabIndex = 1; + this.m_outTcpTraffic.Text = "0,00 kB/s"; + // + // m_inTcpTraffic + // + this.m_inTcpTraffic.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.m_inTcpTraffic.Location = new System.Drawing.Point(43, 16); + this.m_inTcpTraffic.Name = "m_inTcpTraffic"; + this.m_inTcpTraffic.Size = new System.Drawing.Size(90, 13); + this.m_inTcpTraffic.TabIndex = 1; + this.m_inTcpTraffic.Text = "0,00 kB/s"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(10, 29); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(27, 13); + this.label7.TabIndex = 0; + this.label7.Text = "Out:"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(10, 16); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(19, 13); + this.label8.TabIndex = 0; + this.label8.Text = "In:"; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.m_outUdpTraffic); + this.groupBox2.Controls.Add(this.m_inUdpTraffic); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.label1); + this.groupBox2.Location = new System.Drawing.Point(11, 20); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(148, 55); + this.groupBox2.TabIndex = 0; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Udp"; + // + // m_outUdpTraffic + // + this.m_outUdpTraffic.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.m_outUdpTraffic.Location = new System.Drawing.Point(43, 29); + this.m_outUdpTraffic.Name = "m_outUdpTraffic"; + this.m_outUdpTraffic.Size = new System.Drawing.Size(90, 13); + this.m_outUdpTraffic.TabIndex = 1; + this.m_outUdpTraffic.Text = "0,00 kB/s"; + // + // m_inUdpTraffic + // + this.m_inUdpTraffic.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.m_inUdpTraffic.Location = new System.Drawing.Point(43, 16); + this.m_inUdpTraffic.Name = "m_inUdpTraffic"; + this.m_inUdpTraffic.Size = new System.Drawing.Size(90, 13); + this.m_inUdpTraffic.TabIndex = 1; + this.m_inUdpTraffic.Text = "0,00 kB/s"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(10, 29); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(27, 13); + this.label2.TabIndex = 0; + this.label2.Text = "Out:"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(10, 16); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(19, 13); + this.label1.TabIndex = 0; + this.label1.Text = "In:"; + // + // m_networkDrawing + // + this.m_networkDrawing.Dock = System.Windows.Forms.DockStyle.Fill; + this.m_networkDrawing.Location = new System.Drawing.Point(3, 3); + this.m_networkDrawing.Name = "m_networkDrawing"; + this.m_networkDrawing.Size = new System.Drawing.Size(584, 418); + this.m_networkDrawing.TabIndex = 1; + this.m_networkDrawing.TabStop = false; + // + // tabMemory + // + this.tabMemory.Controls.Add(this.tableLayoutPanel2); + this.tabMemory.Location = new System.Drawing.Point(4, 22); + this.tabMemory.Name = "tabMemory"; + this.tabMemory.Padding = new System.Windows.Forms.Padding(3); + this.tabMemory.Size = new System.Drawing.Size(596, 524); + this.tabMemory.TabIndex = 2; + this.tabMemory.Text = "Memory"; + this.tabMemory.UseVisualStyleBackColor = true; + // + // tableLayoutPanel2 + // + this.tableLayoutPanel2.ColumnCount = 1; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.Controls.Add(this.m_memStats, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.groupBox5, 0, 1); + this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 3); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 2; + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 72F)); + this.tableLayoutPanel2.Size = new System.Drawing.Size(590, 518); + this.tableLayoutPanel2.TabIndex = 0; + // + // m_memStats + // + this.m_memStats.Dock = System.Windows.Forms.DockStyle.Fill; + this.m_memStats.Location = new System.Drawing.Point(3, 3); + this.m_memStats.Name = "m_memStats"; + this.m_memStats.Size = new System.Drawing.Size(584, 440); + this.m_memStats.TabIndex = 2; + this.m_memStats.TabStop = false; + // + // groupBox5 + // + this.groupBox5.Controls.Add(this.m_callGCButton); + this.groupBox5.Controls.Add(this.m_availableMem); + this.groupBox5.Controls.Add(this.m_commitSize); + this.groupBox5.Controls.Add(this.label4); + this.groupBox5.Controls.Add(this.label3); + this.groupBox5.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox5.Location = new System.Drawing.Point(3, 449); + this.groupBox5.Name = "groupBox5"; + this.groupBox5.Size = new System.Drawing.Size(584, 66); + this.groupBox5.TabIndex = 3; + this.groupBox5.TabStop = false; + this.groupBox5.Text = "Current memory usage"; + // + // m_callGCButton + // + this.m_callGCButton.Location = new System.Drawing.Point(224, 16); + this.m_callGCButton.Name = "m_callGCButton"; + this.m_callGCButton.Size = new System.Drawing.Size(127, 23); + this.m_callGCButton.TabIndex = 2; + this.m_callGCButton.Text = "Call garbage collector"; + this.m_callGCButton.UseVisualStyleBackColor = true; + this.m_callGCButton.Click += new System.EventHandler(this.m_callGCButton_Click); + // + // m_availableMem + // + this.m_availableMem.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.m_availableMem.Location = new System.Drawing.Point(90, 38); + this.m_availableMem.Name = "m_availableMem"; + this.m_availableMem.Size = new System.Drawing.Size(100, 15); + this.m_availableMem.TabIndex = 1; + this.m_availableMem.Text = "0,00 mb"; + // + // m_commitSize + // + this.m_commitSize.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.m_commitSize.Location = new System.Drawing.Point(90, 20); + this.m_commitSize.Name = "m_commitSize"; + this.m_commitSize.Size = new System.Drawing.Size(100, 15); + this.m_commitSize.TabIndex = 1; + this.m_commitSize.Text = "0,00 mb"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(31, 39); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(53, 13); + this.label4.TabIndex = 0; + this.label4.Text = "Available:"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(19, 21); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(65, 13); + this.label3.TabIndex = 0; + this.label3.Text = "Commit size:"; + // + // tabCpu + // + this.tabCpu.Controls.Add(this.tableLayoutPanel3); + this.tabCpu.Location = new System.Drawing.Point(4, 22); + this.tabCpu.Name = "tabCpu"; + this.tabCpu.Padding = new System.Windows.Forms.Padding(3); + this.tabCpu.Size = new System.Drawing.Size(596, 524); + this.tabCpu.TabIndex = 3; + this.tabCpu.Text = "Cpu"; + this.tabCpu.UseVisualStyleBackColor = true; + // + // tableLayoutPanel3 + // + this.tableLayoutPanel3.ColumnCount = 1; + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel3.Controls.Add(this.m_cpuDrawing, 0, 0); + this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 3); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + this.tableLayoutPanel3.RowCount = 2; + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel3.Size = new System.Drawing.Size(590, 518); + this.tableLayoutPanel3.TabIndex = 0; + // + // m_cpuDrawing + // + this.m_cpuDrawing.Dock = System.Windows.Forms.DockStyle.Fill; + this.m_cpuDrawing.Location = new System.Drawing.Point(3, 3); + this.m_cpuDrawing.Name = "m_cpuDrawing"; + this.m_cpuDrawing.Size = new System.Drawing.Size(584, 492); + this.m_cpuDrawing.TabIndex = 0; + this.m_cpuDrawing.TabStop = false; + // + // tabPackets + // + this.tabPackets.Location = new System.Drawing.Point(4, 22); + this.tabPackets.Name = "tabPackets"; + this.tabPackets.Padding = new System.Windows.Forms.Padding(3); + this.tabPackets.Size = new System.Drawing.Size(596, 524); + this.tabPackets.TabIndex = 4; + this.tabPackets.Text = "Packets"; + this.tabPackets.UseVisualStyleBackColor = true; + // + // StatusWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(604, 550); + this.Controls.Add(this.panel1); + this.Name = "StatusWindow"; + this.Text = "realXtend server status"; + this.panel1.ResumeLayout(false); + this.tabControl1.ResumeLayout(false); + this.tabNetwork.ResumeLayout(false); + this.tableLayoutPanel1.ResumeLayout(false); + this.groupBox1.ResumeLayout(false); + this.groupBox4.ResumeLayout(false); + this.groupBox4.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.groupBox3.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.m_networkDrawing)).EndInit(); + this.tabMemory.ResumeLayout(false); + this.tableLayoutPanel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.m_memStats)).EndInit(); + this.groupBox5.ResumeLayout(false); + this.groupBox5.PerformLayout(); + this.tabCpu.ResumeLayout(false); + this.tableLayoutPanel3.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.m_cpuDrawing)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabThreads; + private System.Windows.Forms.TabPage tabNetwork; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.Label m_outTotalTraffic; + private System.Windows.Forms.Label m_inTotalTraffic; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.Label m_outTcpTraffic; + private System.Windows.Forms.Label m_inTcpTraffic; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Label m_outUdpTraffic; + private System.Windows.Forms.Label m_inUdpTraffic; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.PictureBox m_networkDrawing; + private System.Windows.Forms.TabPage tabMemory; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private System.Windows.Forms.PictureBox m_memStats; + private System.Windows.Forms.GroupBox groupBox5; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label m_availableMem; + private System.Windows.Forms.Label m_commitSize; + private System.Windows.Forms.TabPage tabCpu; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; + private System.Windows.Forms.PictureBox m_cpuDrawing; + private System.Windows.Forms.TabPage tabPackets; + private System.Windows.Forms.Button m_callGCButton; + + + + } +} \ No newline at end of file diff --git a/trunk/OpenSim/Framework/ServerStatus/StatusWindow.cs b/trunk/OpenSim/Framework/ServerStatus/StatusWindow.cs new file mode 100644 index 0000000000..fc36a4c5c3 --- /dev/null +++ b/trunk/OpenSim/Framework/ServerStatus/StatusWindow.cs @@ -0,0 +1,889 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Timers; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace OpenSim.Framework.ServerStatus +{ + public partial class StatusWindow : Form + { + System.Timers.Timer m_updateTimer; + static Dictionary m_threadItems = new Dictionary(); + static Dictionary m_idToName = new Dictionary(); + static int m_nCoreCount = System.Environment.ProcessorCount; + + PerformanceCounter m_pcAvailRam = null; + + class TrafficHistory { + public float outUdpBytes = 0; + public float inUdpBytes = 0; + public float outTcpBytes = 0; + public float inTcpBytes = 0; + public float outTotalBytes = 0; + public float inTotalBytes = 0; + public float resentBytes = 0; + } + + class MemoryHistory { + public float nonpagedSystemMemory; + public float pagedMemory; + public float pagedSystemMemory; + public float gcReportedMem; + public float workingSet; + } + + class CpuHistory { + public float[] cpuUsage = new float[m_nCoreCount]; + public float totalUsage = 0; + } + + class PacketItem + { + public long m_bytesOut = 0; + public long m_packetsOut = 0; + public long m_bytesIn = 0; + public long m_packetsIn = 0; + public long m_resent = 0; + + public bool m_addedToList = false; + public ListViewItem.ListViewSubItem m_listBytesOut = null; + public ListViewItem.ListViewSubItem m_listPacketsOut = null; + public ListViewItem.ListViewSubItem m_listBytesIn = null; + public ListViewItem.ListViewSubItem m_listPacketsIn = null; + public ListViewItem.ListViewSubItem m_listResent = null; + } + + static float m_fNetworkHistoryScale; + static float m_fMemoryHistoryScale; + + static Dictionary m_packets = new Dictionary(); + static LinkedList m_trafficHistory = new LinkedList(); + static LinkedList m_memoryHistory = new LinkedList(); + static LinkedList m_cpuHistory = new LinkedList(); + + PerformanceCounter[] m_pcCpu = new PerformanceCounter[System.Environment.ProcessorCount]; + PerformanceCounter m_pcCpuTotal = null; + + static volatile int outUdpBytes = 0; + static volatile int inUdpBytes = 0; + static volatile int outTcpBytes = 0; + static volatile int inTcpBytes = 0; + static volatile int outResent = 0; + + BufferedListView m_threads; + BufferedListView m_listPackets; + + #region BufferedListView + /** + * Flicker minimized listview + **/ + public class BufferedListView : ListView + { + #region WM - Window Messages + public enum WM + { + WM_NULL = 0x0000, + WM_CREATE = 0x0001, + WM_DESTROY = 0x0002, + WM_MOVE = 0x0003, + WM_SIZE = 0x0005, + WM_ACTIVATE = 0x0006, + WM_SETFOCUS = 0x0007, + WM_KILLFOCUS = 0x0008, + WM_ENABLE = 0x000A, + WM_SETREDRAW = 0x000B, + WM_SETTEXT = 0x000C, + WM_GETTEXT = 0x000D, + WM_GETTEXTLENGTH = 0x000E, + WM_PAINT = 0x000F, + WM_CLOSE = 0x0010, + WM_QUERYENDSESSION = 0x0011, + WM_QUIT = 0x0012, + WM_QUERYOPEN = 0x0013, + WM_ERASEBKGND = 0x0014, + + } + #endregion + + #region RECT + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + } + #endregion + + #region Imported User32.DLL functions + [DllImport("user32.dll", CharSet = CharSet.Auto)] + static public extern bool ValidateRect(IntPtr handle, ref RECT rect); + #endregion + + #region GetWindowRECT + // Get the listview's rectangle and return it as a RECT structure + private RECT GetWindowRECT() + { + RECT rect = new RECT(); + rect.left = this.Left; + rect.right = this.Right; + rect.top = this.Top; + rect.bottom = this.Bottom; + return rect; + } + #endregion + + volatile public bool updating = false; + + public BufferedListView() + { + } + + + protected override void OnPaintBackground(PaintEventArgs pea) + { + // do nothing here since this event is now handled by OnPaint + } + + + protected override void OnPaint(PaintEventArgs pea) + { + base.OnPaint(pea); + } + + protected override void WndProc(ref Message messg) + { + if (updating) + { + if ((int)WM.WM_ERASEBKGND == messg.Msg) + { + return; + } + else if ((int)WM.WM_PAINT == messg.Msg) + { + RECT vrect = this.GetWindowRECT(); + // validate the entire window + ValidateRect(this.Handle, ref vrect); + } + + } + base.WndProc(ref messg); + } + } + #endregion + + #region ThreadItem + /** + * Represents a single thread item in the listview control + **/ + class ThreadItem + { + public ListViewItem listItem; + public ListViewItem.ListViewSubItem name; + public ListViewItem.ListViewSubItem cpu; + } + #endregion + + + public static void ReportOutPacketUdp(int size, bool resent) + { + if (resent) + { + outResent += size += 8; + } + outUdpBytes += size + 8; + } + + public static void ReportInPacketUdp(int size) { inUdpBytes += size + 8; } + + public static void ReportOutPacketTcp(int size) { outTcpBytes += size + 20; } + public static void ReportInPacketTcp(int size) { inTcpBytes += size + 20; } + + public static void ReportProcessedOutPacket(string name, int size, bool resent) + { + PacketItem item = null; + if (m_packets.ContainsKey(name)) + { + item = m_packets[name]; + } + else + { + item = new PacketItem(); + m_packets[name] = item; + } + + if (resent) + { + item.m_resent += size; + } + item.m_bytesOut += size; + item.m_packetsOut++; + } + + public static void ReportProcessedInPacket(string name, int size) + { + PacketItem item = null; + if (m_packets.ContainsKey(name)) + { + item = m_packets[name]; + } + else + { + item = new PacketItem(); + m_packets[name] = item; + } + + item.m_bytesIn += size; + item.m_packetsIn++; + } + + + public StatusWindow() + { + m_pcAvailRam = new PerformanceCounter("Memory", "Available MBytes"); + m_packets = new Dictionary(); + + InitializeComponent(); + + m_listPackets = new BufferedListView(); + m_listPackets.Dock = System.Windows.Forms.DockStyle.Fill; + m_listPackets.GridLines = true; + m_listPackets.Location = new System.Drawing.Point(3, 3); + m_listPackets.MultiSelect = false; + m_listPackets.Name = "m_listPackets"; + m_listPackets.Size = new System.Drawing.Size(500, 400); + m_listPackets.TabIndex = 0; + m_listPackets.View = System.Windows.Forms.View.Details; + + tabPackets.Controls.Add(m_listPackets); + + m_listPackets.Columns.Add("Packet").Width = 260; + m_listPackets.Columns.Add("In count").Width = 80; + m_listPackets.Columns.Add("In bytes").Width = 80; + m_listPackets.Columns.Add("Out count").Width = 80; + m_listPackets.Columns.Add("Out bytes").Width = 80; + m_listPackets.Columns.Add("Resent").Width = 80; + + + m_threads = new BufferedListView(); + m_threads.Dock = System.Windows.Forms.DockStyle.Fill; + m_threads.GridLines = true; + m_threads.Location = new System.Drawing.Point(3, 3); + m_threads.MultiSelect = false; + m_threads.Name = "m_threads"; + m_threads.Size = new System.Drawing.Size(500, 400); + m_threads.TabIndex = 0; + m_threads.View = System.Windows.Forms.View.Details; + + tabThreads.Controls.Add(m_threads); + + m_threads.Columns.Add("ID"); + m_threads.Columns.Add("Name").Width = 260; + m_threads.Columns.Add("CPU Time").Width=100; + + m_updateTimer = new System.Timers.Timer(2000); + m_updateTimer.Elapsed += new ElapsedEventHandler(UpdateTimer); + outUdpBytes = 0; + inUdpBytes = 0; + outTcpBytes = 0; + inTcpBytes = 0; + outResent = 0; + m_updateTimer.Start(); + + for(int i = 0; i < m_nCoreCount; i++) + { + m_pcCpu[i] = new PerformanceCounter("Processor", "% Processor Time", i.ToString(), true); + m_pcCpu[i].MachineName = "."; + } + m_pcCpuTotal = new PerformanceCounter("Processor", "% Processor Time", "_Total", true); + } + + public void CloseStatusWindow() { + Close(); + m_updateTimer.Stop(); + m_threadItems.Clear(); + + m_pcAvailRam.Close(); + m_pcAvailRam = null; + + for (int i = 0; i < m_nCoreCount; i++) + { + m_pcCpu[i].Close(); + m_pcCpu[i] = null; + } + + foreach(PacketItem item in m_packets.Values) + { + item.m_addedToList = false; + } + + m_packets = null; + + m_pcCpuTotal.Close(); + m_pcCpuTotal = null; + } + + public static void ReportThreadName(int id, string name) + { + lock (m_threadItems) + { + m_idToName[id] = name; + } + } + + delegate void UpdateControlsDelegate(); + + TrafficHistory UpdateNetworkHistory() + { + TrafficHistory item = new TrafficHistory(); + + item.inUdpBytes = ((float)inUdpBytes) / 1024.0f / 2.0f; + item.outUdpBytes = ((float)outUdpBytes) / 1024.0f / 2.0f; + item.inTcpBytes = ((float)inTcpBytes) / 1024.0f / 2.0f; + item.outTcpBytes = ((float)outTcpBytes) / 1024.0f / 2.0f; + item.resentBytes = ((float)outResent) / 1024.0f / 2.0f; + item.inTotalBytes = item.inUdpBytes + item.inTcpBytes; + item.outTotalBytes = item.outUdpBytes + item.outTcpBytes; + inUdpBytes = 0; + outUdpBytes = 0; + inTcpBytes = 0; + outTcpBytes = 0; + outResent = 0; + + m_trafficHistory.AddFirst(item); + if (m_trafficHistory.Count > 500) + { + m_trafficHistory.RemoveLast(); + } + + return item; + } + + MemoryHistory UpdateMemoryHistory(Process proc) + { + MemoryHistory item = new MemoryHistory(); + + item.gcReportedMem = ((float)System.GC.GetTotalMemory(false)) / 1024.0f / 1024.0f; + item.workingSet = ((float)proc.WorkingSet64) / 1024.0f / 1024.0f; + item.nonpagedSystemMemory = ((float)proc.NonpagedSystemMemorySize64) / 1024.0f / 1024.0f; + item.pagedSystemMemory = ((float)proc.PagedMemorySize64) / 1024.0f / 1024.0f; + item.pagedSystemMemory = ((float)proc.PagedSystemMemorySize64) / 1024.0f / 1024.0f; + + m_memoryHistory.AddFirst(item); + if (m_memoryHistory.Count > 500) + { + m_memoryHistory.RemoveLast(); + } + + return item; + } + + void UpdateCpuHistory() { + CpuHistory item = new CpuHistory(); + + for( int i = 0; i < m_nCoreCount; i++) + { + item.cpuUsage[i] = m_pcCpu[i].NextValue(); + } + + item.totalUsage = m_pcCpuTotal.NextValue(); + + m_cpuHistory.AddFirst(item); + if (m_cpuHistory.Count > 500) + { + m_cpuHistory.RemoveLast(); + } + } + + string FormatDataSize(long byteCount) + { + double fCount = (double)byteCount; + if (byteCount > 1024 * 1024 * 1024) + { + fCount/=(1024.0*1024.0*1024.0); + return fCount.ToString("##0.00") + "GB"; + } + else if (byteCount > 1024*1024*10) + { + fCount/=(1024.0*1024.0); + return fCount.ToString("##0.00") + "MB"; + } + else if (byteCount > 1024*10) + { + fCount/=1024.0; + return fCount.ToString("##0.00") + "KB"; + } + else + { + return byteCount.ToString() +"B"; + } + } + + void UpdatePacketView() + { + foreach(KeyValuePair item in m_packets) + { + if (item.Value.m_addedToList) + { + item.Value.m_listPacketsIn.Text = item.Value.m_packetsIn.ToString(); + item.Value.m_listBytesIn.Text = FormatDataSize(item.Value.m_bytesIn); + item.Value.m_listPacketsOut.Text = item.Value.m_packetsOut.ToString(); + item.Value.m_listBytesOut.Text = FormatDataSize(item.Value.m_bytesOut); + item.Value.m_listResent.Text = FormatDataSize(item.Value.m_resent); + } + else + { + ListViewItem listItem = m_listPackets.Items.Add(item.Key); + item.Value.m_listPacketsIn = listItem.SubItems.Add(item.Value.m_packetsIn.ToString()); + item.Value.m_listBytesIn = listItem.SubItems.Add(FormatDataSize(item.Value.m_bytesIn)); + item.Value.m_listPacketsOut = listItem.SubItems.Add(item.Value.m_packetsOut.ToString()); + item.Value.m_listBytesOut = listItem.SubItems.Add(FormatDataSize(item.Value.m_bytesOut)); + item.Value.m_listResent = listItem.SubItems.Add(FormatDataSize(item.Value.m_resent)); + item.Value.m_addedToList = true; + } + + } + } + + void UpdateControls() + { + Process proc = Process.GetCurrentProcess(); + + TrafficHistory netItem = UpdateNetworkHistory(); + MemoryHistory memItem = UpdateMemoryHistory(proc); + + UpdateCpuHistory(); + + if (tabControl1.SelectedIndex == 0) + { + m_threads.updating = true; + UpdateThreadList(); + m_threads.updating = false; + m_threads.Invalidate(); + } + else if (tabControl1.SelectedIndex == 1) + { + RefreshNetworkStats(netItem); + PaintNetworkHistory(); + } + else if (tabControl1.SelectedIndex == 2) + { + m_availableMem.Text = m_pcAvailRam.NextValue().ToString("##0.00") + " MB"; + m_commitSize.Text = memItem.workingSet.ToString("##0.00") + " MB"; + PaintMemoryHistory(); + } + else if (tabControl1.SelectedIndex == 3) + { + PaintCpuHistory(); + } + else if (tabControl1.SelectedIndex == 4) + { + m_listPackets.updating = true; + UpdatePacketView(); + m_listPackets.updating = false; + m_listPackets.Invalidate(); + } + } + + protected void PaintCpuHistory() + { + Pen[] pens = { Pens.Yellow, Pens.Blue, Pens.Green, Pens.Red, + Pens.White, Pens.Turquoise, Pens.Linen, Pens.Gray, + Pens.Purple, Pens.Pink, Pens.LightBlue, Pens.LightSalmon}; + + Pen penLine = Pens.DarkSlateGray; + + Graphics screenGfx = m_cpuDrawing.CreateGraphics(); + Bitmap backBuffer = new Bitmap(m_cpuDrawing.Width, m_cpuDrawing.Height); + Graphics gfx = Graphics.FromImage(backBuffer); + + gfx.Clear(Color.Black); + + float fMax = 105.0f; + for (int i = 0; i < m_cpuDrawing.Height - 10; i += 30) + { + float yPos = m_cpuDrawing.Height - i - 15; + float fPos = ((float)(i)) / ((float)m_cpuDrawing.Height); + gfx.DrawLine(penLine, 0, yPos, m_cpuDrawing.Width, yPos); + } + + //Size of second in pixels + float fSecondStep = 2.5f; //120 seconds + float fTotalSeconds = (1 / fSecondStep) * (m_cpuDrawing.Width - 90); + for (int i = 0; i < m_cpuDrawing.Width - 90; i += 50) + { + float xPos = 90 + i; + float fTime = fTotalSeconds - (((float)(i)) / fSecondStep); + + gfx.DrawLine(penLine, xPos, 0, xPos, m_cpuDrawing.Height - 15); + string strText = fTime.ToString("##0"); + gfx.DrawString(strText, SystemFonts.DialogFont, Brushes.CadetBlue, + xPos - 4 * strText.Length, m_cpuDrawing.Height - 15); + } + + + float nXPos = m_cpuDrawing.Width; + float fHeightMul = m_cpuDrawing.Height - 15; + float fYStart = m_cpuDrawing.Height - 15; + CpuHistory lastItem = null; + + foreach (CpuHistory item in m_cpuHistory) + { + if (lastItem != null) + { + nXPos -= fSecondStep * 2; + + for (int i = 0; i < m_nCoreCount; i++) + { + gfx.DrawLine(pens[i+1], nXPos, fYStart - (item.cpuUsage[i] / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.cpuUsage[i] / fMax) * fHeightMul); + } + + gfx.DrawLine(pens[0], nXPos, fYStart - (item.totalUsage / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.totalUsage / fMax) * fHeightMul); + + if (nXPos < 0) + break; + } + + lastItem = item; + } + + for (int i = 0; i < m_cpuDrawing.Height - 10; i += 30) + { + float yPos = m_cpuDrawing.Height - i - 15; + float fPos = ((float)(i)) / ((float)m_cpuDrawing.Height); + gfx.DrawString((fPos * fMax).ToString("##0.00") + "%", + SystemFonts.DialogFont, Brushes.CadetBlue, 3, yPos); + } + + int nPosX = m_cpuDrawing.Width - 50; + + + gfx.DrawString("Total", SystemFonts.DialogFont, pens[0].Brush, nPosX, 10); + for (int i = 0; i < m_nCoreCount; i++ ) + { + gfx.DrawString("Core " + i, SystemFonts.DialogFont, pens[i+1].Brush, nPosX, 22 + i * 12); + } + + screenGfx.DrawImageUnscaled(backBuffer, 0, 0); + } + + protected void PaintNetworkHistory() + { + Pen penUdpOut = Pens.SkyBlue; + Pen penUdpIn = Pens.Blue; + Pen penTcpOut = Pens.Red; + Pen penTcpIn = Pens.Pink; + Pen penTotalOut = Pens.Green; + Pen penTotalIn = Pens.LimeGreen; + Pen penResent = Pens.Orange; + + Pen penLine = Pens.DarkSlateGray; + + + Graphics screenGfx = m_networkDrawing.CreateGraphics(); + Bitmap backBuffer = new Bitmap(m_networkDrawing.Width, m_networkDrawing.Height); + Graphics gfx = Graphics.FromImage(backBuffer); + + gfx.Clear(Color.Black); + + float fMax = m_fNetworkHistoryScale; + if (fMax < 12.0f) + fMax = 12.0f; + for( int i = 0; i < m_networkDrawing.Height-10; i+= 30) + { + float yPos = m_networkDrawing.Height - i-15; + float fPos = ((float)(i)) / ((float)m_networkDrawing.Height); + gfx.DrawLine(penLine, 0, yPos, m_networkDrawing.Width, yPos); + } + + //Size of second in pixels + float fSecondStep = 1.5f; //120 seconds + float fTotalSeconds = (1/fSecondStep) * (m_networkDrawing.Width - 90); + for( int i = 0; i < m_networkDrawing.Width-90; i+= 50) + { + float xPos = 90 + i; + float fTime = fTotalSeconds - (((float)(i)) / fSecondStep); + + gfx.DrawLine(penLine, xPos, 0, xPos, m_networkDrawing.Height - 15); + string strText = fTime.ToString("##0"); + gfx.DrawString(strText, SystemFonts.DialogFont, Brushes.CadetBlue, + xPos - 4 * strText.Length, m_networkDrawing.Height - 15); + } + + + float nXPos = m_networkDrawing.Width; + float fHeightMul = m_networkDrawing.Height - 15; + float fYStart = m_networkDrawing.Height - 15; + TrafficHistory lastItem = null; + + float fHighestRate = 0; + foreach(TrafficHistory item in m_trafficHistory) { + if (lastItem != null) + { + nXPos -= fSecondStep * 2; + + gfx.DrawLine(penUdpIn, nXPos, fYStart - (item.inUdpBytes / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.inUdpBytes / fMax) * fHeightMul); + gfx.DrawLine(penUdpOut, nXPos, fYStart - (item.outUdpBytes / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.outUdpBytes / fMax) * fHeightMul); + + gfx.DrawLine(penTcpIn, nXPos, fYStart - (item.inTcpBytes / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.inTcpBytes / fMax) * fHeightMul); + gfx.DrawLine(penTcpOut, nXPos, fYStart - (item.outTcpBytes / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.outTcpBytes / fMax) * fHeightMul); + + gfx.DrawLine(penTotalIn, nXPos, fYStart - (item.inTotalBytes / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.inTotalBytes / fMax) * fHeightMul); + gfx.DrawLine(penTotalOut, nXPos, fYStart - (item.outTotalBytes / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.outTotalBytes / fMax) * fHeightMul); + + gfx.DrawLine(penResent, nXPos, fYStart - (item.resentBytes / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.resentBytes / fMax) * fHeightMul); + + if (nXPos < 0) + break; + } + lastItem = item; + if (item.inTotalBytes > fHighestRate) + fHighestRate = item.inTotalBytes; + if (item.outTotalBytes > fHighestRate) + fHighestRate = item.outTotalBytes; + } + + for (int i = 0; i < m_networkDrawing.Height - 10; i += 30) + { + float yPos = m_networkDrawing.Height - i - 15; + float fPos = ((float)(i)) / ((float)m_networkDrawing.Height); + gfx.DrawString((fPos * fMax).ToString("##0.00") + " KB/s", + SystemFonts.DialogFont, Brushes.CadetBlue, 3, yPos); + } + + int nPosX = m_networkDrawing.Width-60; + gfx.DrawString("Udp in", SystemFonts.DialogFont, penUdpIn.Brush, nPosX, 10); + gfx.DrawString("Udp out", SystemFonts.DialogFont, penUdpOut.Brush, nPosX, 22); + gfx.DrawString("Tcp in", SystemFonts.DialogFont, penTcpIn.Brush, nPosX, 34); + gfx.DrawString("Tcp out", SystemFonts.DialogFont, penTcpOut.Brush, nPosX, 46); + gfx.DrawString("Total in", SystemFonts.DialogFont, penTotalIn.Brush, nPosX, 58); + gfx.DrawString("Total out", SystemFonts.DialogFont, penTotalOut.Brush, nPosX, 70); + gfx.DrawString("Resent", SystemFonts.DialogFont, penResent.Brush, nPosX, 82); + + screenGfx.DrawImageUnscaled(backBuffer, 0, 0); + + m_fNetworkHistoryScale = fHighestRate + 10; + } + + protected void PaintMemoryHistory() + { + Pen penPagedMemory = Pens.Gray; + Pen penPagedSystemMemory = Pens.Orange; + Pen penNonPagedMemory = Pens.LawnGreen; + Pen penWorkingSet = Pens.HotPink; + Pen penGcReported = Pens.Red; + + + Pen penLine = Pens.DarkSlateGray; + + Graphics screenGfx = m_memStats.CreateGraphics(); + Bitmap backBuffer = new Bitmap(m_memStats.Width, m_memStats.Height); + Graphics gfx = Graphics.FromImage(backBuffer); + + gfx.Clear(Color.Black); + + float fMax = m_fMemoryHistoryScale; + if (fMax < 12.0f) + fMax = 12.0f; + for (int i = 0; i < m_memStats.Height - 10; i += 30) + { + float yPos = m_memStats.Height - i - 15; + float fPos = ((float)(i)) / ((float)m_memStats.Height); + gfx.DrawLine(penLine, 0, yPos, m_memStats.Width, yPos); + } + + //Size of second in pixels + float fSecondStep = 1.5f; //120 seconds + float fTotalSeconds = (1 / fSecondStep) * (m_memStats.Width - 90); + for (int i = 0; i < m_memStats.Width - 90; i += 50) + { + float xPos = 90 + i; + float fTime = fTotalSeconds - (((float)(i)) / fSecondStep); + + gfx.DrawLine(penLine, xPos, 0, xPos, m_memStats.Height - 15); + string strText = fTime.ToString("##0"); + gfx.DrawString(strText, SystemFonts.DialogFont, Brushes.CadetBlue, + xPos - 4 * strText.Length, m_memStats.Height - 15); + } + + + float nXPos = m_memStats.Width; + float fHeightMul = m_memStats.Height - 15; + float fYStart = m_memStats.Height - 15; + MemoryHistory lastItem = null; + + float fHighestRate = 0; + foreach (MemoryHistory item in m_memoryHistory) + { + if (lastItem != null) + { + + nXPos -= fSecondStep * 2; + + gfx.DrawLine(penPagedMemory, nXPos, fYStart - (item.pagedMemory / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.pagedMemory / fMax) * fHeightMul); + + gfx.DrawLine(penPagedSystemMemory, nXPos, fYStart - (item.pagedSystemMemory / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.pagedSystemMemory / fMax) * fHeightMul); + + gfx.DrawLine(penNonPagedMemory, nXPos, fYStart - (item.nonpagedSystemMemory / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.nonpagedSystemMemory / fMax) * fHeightMul); + + gfx.DrawLine(penWorkingSet, nXPos, fYStart - (item.workingSet / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.workingSet / fMax) * fHeightMul); + + gfx.DrawLine(penGcReported, nXPos, fYStart - (item.gcReportedMem / fMax) * fHeightMul, + nXPos + fSecondStep * 2, fYStart - (lastItem.gcReportedMem / fMax) * fHeightMul); + + if (nXPos < 0) + break; + } + + lastItem = item; + if (item.nonpagedSystemMemory > fHighestRate) + fHighestRate = item.nonpagedSystemMemory; + if (item.pagedMemory > fHighestRate) + fHighestRate = item.pagedMemory; + if (item.pagedSystemMemory > fHighestRate) + fHighestRate = item.pagedSystemMemory; + if (item.workingSet > fHighestRate) + fHighestRate = item.workingSet; + if (item.gcReportedMem > fHighestRate) + fHighestRate = item.gcReportedMem; + } + + for (int i = 0; i < m_memStats.Height - 10; i += 30) + { + float yPos = m_memStats.Height - i - 15; + float fPos = ((float)(i)) / ((float)m_memStats.Height); + gfx.DrawString((fPos * fMax).ToString("##0.00") + " MB", + SystemFonts.DialogFont, Brushes.CadetBlue, 3, yPos); + } + + int nPosX = m_memStats.Width - 120; + + gfx.DrawString("Working set", SystemFonts.DialogFont, penWorkingSet.Brush, nPosX, 10); + gfx.DrawString("GC Reported mem.", SystemFonts.DialogFont, penGcReported.Brush, nPosX, 22); + gfx.DrawString("Paged mem.", SystemFonts.DialogFont, penPagedMemory.Brush, nPosX, 34); + gfx.DrawString("Paged system mem.", SystemFonts.DialogFont, penPagedSystemMemory.Brush, nPosX, 46); + gfx.DrawString("Nonpaged mem.", SystemFonts.DialogFont, penNonPagedMemory.Brush, nPosX, 58); + + screenGfx.DrawImageUnscaled(backBuffer, 0, 0); + + m_fMemoryHistoryScale = fHighestRate + 10; + } + + void RefreshNetworkStats(TrafficHistory item) + { + m_inUdpTraffic.Text = item.inUdpBytes.ToString("##0.00") + " KB/s"; + m_outUdpTraffic.Text = item.outUdpBytes.ToString("##0.00") + " KB/s"; + m_inTcpTraffic.Text = item.inTcpBytes.ToString("##0.00") + " KB/s"; + m_outTcpTraffic.Text = item.outTcpBytes.ToString("##0.00") + " KB/s"; + m_inTotalTraffic.Text = item.inTotalBytes.ToString("##0.00") + " KB/s"; + m_outTotalTraffic.Text = item.outTotalBytes.ToString("##0.00") + " KB/s"; + } + + protected void UpdateTimer(object sender, ElapsedEventArgs ea) + { + if (m_threads.InvokeRequired) + { + m_threads.Invoke(new UpdateControlsDelegate(UpdateControls)); + } + else + { + UpdateControls(); + } + } + + + #region Thread items access + void UpdateThreadItem(ProcessThread pt) + { + if (m_threadItems.ContainsKey(pt.Id)) + { + ThreadItem item = m_threadItems[pt.Id]; + + item.cpu.Text = pt.TotalProcessorTime.ToString(); + if (m_idToName.ContainsKey(pt.Id)) + { + item.name.Text = m_idToName[pt.Id]; + } + } + else + { + ThreadItem item = new ThreadItem(); + item.listItem = m_threads.Items.Add(pt.Id.ToString()); + string name = "[n/a]"; + if (m_idToName.ContainsKey(pt.Id)) + { + name = m_idToName[pt.Id]; + } + item.name = item.listItem.SubItems.Add(name); + item.cpu = item.listItem.SubItems.Add(pt.TotalProcessorTime.ToString()); + + m_threadItems[pt.Id] = item; + } + } + + void RemoveThreadItems(List removed) + { + foreach (int id in removed) + { + m_threads.Items.Remove(m_threadItems[id].listItem); + m_threadItems.Remove(id); + m_idToName.Remove(id); + } + } + + private void UpdateThreadList() + { + ProcessThreadCollection threads = Process.GetCurrentProcess().Threads; + + lock (m_threadItems) + { + Dictionary runningThreads = new Dictionary(); + + foreach (ProcessThread pt in threads) + { + runningThreads[pt.Id] = 0; + + UpdateThreadItem(pt); + } + + List removed = new List(); + foreach (int id in m_threadItems.Keys) + { + if (!runningThreads.ContainsKey(id)) + { + removed.Add(id); + } + } + + RemoveThreadItems(removed); + } + } + + #endregion + + private void m_callGCButton_Click(object sender, EventArgs e) + { + System.GC.Collect(); + } + } +} \ No newline at end of file diff --git a/trunk/OpenSim/Framework/ServerStatus/StatusWindow.resx b/trunk/OpenSim/Framework/ServerStatus/StatusWindow.resx new file mode 100644 index 0000000000..ff31a6db56 --- /dev/null +++ b/trunk/OpenSim/Framework/ServerStatus/StatusWindow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/trunk/OpenSim/Region/Application/OpenSimMain.cs b/trunk/OpenSim/Region/Application/OpenSimMain.cs index 1e5fcfbc96..70afe9495c 100644 --- a/trunk/OpenSim/Region/Application/OpenSimMain.cs +++ b/trunk/OpenSim/Region/Application/OpenSimMain.cs @@ -722,6 +722,7 @@ namespace OpenSim m_console.Notice("show modules - shows info about loaded modules."); m_console.Notice("show stats - statistical information for this server not displayed in the client"); m_console.Notice("shutdown - disconnect all clients and shutdown."); + m_console.Notice("status - open server status window"); m_console.Notice("config set section field value - set a config value"); m_console.Notice("config get section field - get a config value"); m_console.Notice("config save - save OpenSim.ini"); @@ -991,6 +992,9 @@ namespace OpenSim } break; + case "status": + Framework.ServerStatus.ServerStatus.ShowWindow(); + break; /* * Temporarily disabled but it would be good to have this - needs to be levered * in to BaseOpenSimServer (which requires a RunCmd method restrcuture probably) diff --git a/trunk/OpenSim/Region/ClientStack/ClientView.cs b/trunk/OpenSim/Region/ClientStack/ClientView.cs index a027c5b200..a26a687a1e 100644 --- a/trunk/OpenSim/Region/ClientStack/ClientView.cs +++ b/trunk/OpenSim/Region/ClientStack/ClientView.cs @@ -38,9 +38,11 @@ using libsecondlife.Packets; using OpenSim.Framework; using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Console; +using OpenSim.Framework.ServerStatus; using OpenSim.Region.Environment.Scenes; using Timer = System.Timers.Timer; + namespace OpenSim.Region.ClientStack { public delegate bool PacketMethod(IClientAPI simClient, Packet packet); @@ -2464,10 +2466,16 @@ namespace OpenSim.Region.ClientStack { int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode); + + ServerStatus.ReportOutPacketUdp(packetsize, Pack.Header.Resent); + ServerStatus.ReportProcessedOutPacket(Pack.Type.ToString(), packetsize, Pack.Header.Resent); } else { m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode); + + ServerStatus.ReportOutPacketUdp(sendbuffer.Length, Pack.Header.Resent); + ServerStatus.ReportProcessedOutPacket(Pack.Type.ToString(), sendbuffer.Length, Pack.Header.Resent); } } catch (Exception e) @@ -2672,6 +2680,10 @@ namespace OpenSim.Region.ClientStack { ack_pack(Pack); + int packetLength = Pack.ToBytes().Length; + ServerStatus.ReportProcessedInPacket(Pack.Type.ToString(), packetLength); + ServerStatus.ReportInPacketUdp(packetLength); + if (ProcessPacketMethod(Pack)) { //there is a handler registered that handled this packet type diff --git a/trunk/OpenSim/Region/Communications/VoiceChat/VoiceChatServer.cs b/trunk/OpenSim/Region/Communications/VoiceChat/VoiceChatServer.cs index 00d150c92e..0c03638417 100644 --- a/trunk/OpenSim/Region/Communications/VoiceChat/VoiceChatServer.cs +++ b/trunk/OpenSim/Region/Communications/VoiceChat/VoiceChatServer.cs @@ -6,6 +6,7 @@ using System.Net.Sockets; using System.Net; using OpenSim.Region.Environment.Scenes; using OpenSim.Framework; +using OpenSim.Framework.ServerStatus; using libsecondlife; namespace OpenSim.Region.Communications.VoiceChat @@ -14,6 +15,8 @@ namespace OpenSim.Region.Communications.VoiceChat { private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + int m_dummySocketPort = 53134; + Thread m_listenerThread; Thread m_mainThread; Scene m_scene; @@ -53,7 +56,7 @@ namespace OpenSim.Region.Communications.VoiceChat Thread.Sleep(500); m_selectCancel = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - m_selectCancel.Connect("localhost", 59214); + m_selectCancel.Connect("localhost", m_dummySocketPort); } public void NewClient(IClientAPI client) @@ -132,7 +135,7 @@ namespace OpenSim.Region.Communications.VoiceChat void ListenIncomingConnections() { m_log.Info("[VOICECHAT]: Listening connections..."); - //ServerStatus.ReportThreadName("VoiceChat: Connection listener"); + ServerStatus.ReportThreadName("VoiceChat: Connection listener"); byte[] dummyBuffer = new byte[1]; @@ -157,7 +160,7 @@ namespace OpenSim.Region.Communications.VoiceChat Socket ListenLoopbackSocket() { - IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 59214); + IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), m_dummySocketPort); Socket dummyListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); dummyListener.Bind(listenEndPoint); dummyListener.Listen(1); @@ -169,7 +172,7 @@ namespace OpenSim.Region.Communications.VoiceChat void RunVoiceChat() { m_log.Info("[VOICECHAT]: Connection handler started..."); - //ServerStatus.ReportThreadName("VoiceChat: Connection handler"); + ServerStatus.ReportThreadName("VoiceChat: Connection handler"); //Listen a loopback socket for aborting select call Socket dummySocket = ListenLoopbackSocket(); @@ -194,7 +197,14 @@ namespace OpenSim.Region.Communications.VoiceChat } sockets.Add(dummySocket); - Socket.Select(sockets, null, null, 200000); + try + { + Socket.Select(sockets, null, null, 200000); + } + catch (SocketException e) + { + m_log.Warn("[VOICECHAT]: " + e.Message); + } foreach (Socket s in sockets) { @@ -204,6 +214,15 @@ namespace OpenSim.Region.Communications.VoiceChat { ReceiveFromSocket(s, buffer); } + else + { + //Receive data and check if there was an error with select abort socket + if (s.Receive(buffer) <= 0) + { + //Just give a warning for now + m_log.Error("[VOICECHAT]: Select abort socket was closed"); + } + } } catch(ObjectDisposedException e) { @@ -234,17 +253,17 @@ namespace OpenSim.Region.Communications.VoiceChat } else { - //ServerStatus.ReportInPacketTcp(byteCount); + ServerStatus.ReportInPacketTcp(byteCount); lock (m_clients) - { - if (m_clients.ContainsKey(s)) + { + if (m_clients.ContainsKey(s)) { - m_clients[s].OnDataReceived(buffer, byteCount); - } - else - { - m_log.Warn("[VOICECHAT]: Got data from " + s.RemoteEndPoint + - ", but source is not a valid voice client"); + m_clients[s].OnDataReceived(buffer, byteCount); + } + else + { + m_log.Warn("[VOICECHAT]: Got data from " + s.RemoteEndPoint + + ", but source is not a valid voice client"); } } } diff --git a/trunk/OpenSim/Region/Communications/VoiceChat/VoiceClient.cs b/trunk/OpenSim/Region/Communications/VoiceChat/VoiceClient.cs index 6da516b784..8c5e5b572b 100644 --- a/trunk/OpenSim/Region/Communications/VoiceChat/VoiceClient.cs +++ b/trunk/OpenSim/Region/Communications/VoiceChat/VoiceClient.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Text; using System.Net.Sockets; using OpenSim.Region.Environment.Scenes; +using OpenSim.Framework.ServerStatus; using libsecondlife; namespace OpenSim.Region.Communications.VoiceChat @@ -162,8 +163,7 @@ namespace OpenSim.Region.Communications.VoiceChat { if (m_authenticated) { - //ServerStatus.ReportOutPacketTcp(m_socket.Send(data)); - m_socket.Send(data); + ServerStatus.ReportOutPacketTcp(m_socket.Send(data)); } } } diff --git a/trunk/prebuild.xml b/trunk/prebuild.xml index 0e651d133a..e199f75aff 100644 --- a/trunk/prebuild.xml +++ b/trunk/prebuild.xml @@ -752,6 +752,7 @@ + @@ -874,6 +875,7 @@ + @@ -1557,6 +1559,7 @@ + @@ -1565,7 +1568,35 @@ + + + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + +