aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers/BaseOpenSimServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Servers/BaseOpenSimServer.cs')
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs431
1 files changed, 52 insertions, 379 deletions
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index cf19002..2c21800 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -38,6 +38,8 @@ using log4net;
38using log4net.Appender; 38using log4net.Appender;
39using log4net.Core; 39using log4net.Core;
40using log4net.Repository; 40using log4net.Repository;
41using OpenMetaverse;
42using OpenMetaverse.StructuredData;
41using OpenSim.Framework; 43using OpenSim.Framework;
42using OpenSim.Framework.Console; 44using OpenSim.Framework.Console;
43using OpenSim.Framework.Monitoring; 45using OpenSim.Framework.Monitoring;
@@ -45,16 +47,12 @@ using OpenSim.Framework.Servers;
45using OpenSim.Framework.Servers.HttpServer; 47using OpenSim.Framework.Servers.HttpServer;
46using Timer=System.Timers.Timer; 48using Timer=System.Timers.Timer;
47 49
48using OpenMetaverse;
49using OpenMetaverse.StructuredData;
50
51
52namespace OpenSim.Framework.Servers 50namespace OpenSim.Framework.Servers
53{ 51{
54 /// <summary> 52 /// <summary>
55 /// Common base for the main OpenSimServers (user, grid, inventory, region, etc) 53 /// Common base for the main OpenSimServers (user, grid, inventory, region, etc)
56 /// </summary> 54 /// </summary>
57 public abstract class BaseOpenSimServer 55 public abstract class BaseOpenSimServer : ServerBase
58 { 56 {
59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
60 58
@@ -63,27 +61,6 @@ namespace OpenSim.Framework.Servers
63 /// server. 61 /// server.
64 /// </summary> 62 /// </summary>
65 private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); 63 private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
66
67 protected CommandConsole m_console;
68 protected OpenSimAppender m_consoleAppender;
69 protected IAppender m_logFileAppender = null;
70
71 /// <summary>
72 /// Time at which this server was started
73 /// </summary>
74 protected DateTime m_startuptime;
75
76 /// <summary>
77 /// Record the initial startup directory for info purposes
78 /// </summary>
79 protected string m_startupDirectory = Environment.CurrentDirectory;
80
81 /// <summary>
82 /// Server version information. Usually VersionInfo + information about git commit, operating system, etc.
83 /// </summary>
84 protected string m_version;
85
86 protected string m_pidFile = String.Empty;
87 64
88 /// <summary> 65 /// <summary>
89 /// Random uuid for private data 66 /// Random uuid for private data
@@ -96,35 +73,13 @@ namespace OpenSim.Framework.Servers
96 get { return m_httpServer; } 73 get { return m_httpServer; }
97 } 74 }
98 75
99 /// <summary> 76 public BaseOpenSimServer() : base()
100 /// Holds the non-viewer statistics collection object for this service/server
101 /// </summary>
102 protected IStatsCollector m_stats;
103
104 public BaseOpenSimServer()
105 { 77 {
106 m_startuptime = DateTime.Now;
107 m_version = VersionInfo.Version;
108
109 // Random uuid for private data 78 // Random uuid for private data
110 m_osSecret = UUID.Random().ToString(); 79 m_osSecret = UUID.Random().ToString();
111 80
112 m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); 81 m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
113 m_periodicDiagnosticsTimer.Enabled = true; 82 m_periodicDiagnosticsTimer.Enabled = true;
114
115 // This thread will go on to become the console listening thread
116 Thread.CurrentThread.Name = "ConsoleThread";
117
118 ILoggerRepository repository = LogManager.GetRepository();
119 IAppender[] appenders = repository.GetAppenders();
120
121 foreach (IAppender appender in appenders)
122 {
123 if (appender.Name == "LogFileAppender")
124 {
125 m_logFileAppender = appender;
126 }
127 }
128 } 83 }
129 84
130 /// <summary> 85 /// <summary>
@@ -132,76 +87,46 @@ namespace OpenSim.Framework.Servers
132 /// </summary> 87 /// </summary>
133 protected virtual void StartupSpecific() 88 protected virtual void StartupSpecific()
134 { 89 {
135 if (m_console != null) 90 if (m_console == null)
136 { 91 return;
137 ILoggerRepository repository = LogManager.GetRepository(); 92
138 IAppender[] appenders = repository.GetAppenders(); 93 RegisterCommonCommands();
139 94
140 foreach (IAppender appender in appenders) 95 m_console.Commands.AddCommand("General", false, "quit",
141 { 96 "quit",
142 if (appender.Name == "Console") 97 "Quit the application", HandleQuit);
143 { 98
144 m_consoleAppender = (OpenSimAppender)appender; 99 m_console.Commands.AddCommand("General", false, "shutdown",
145 break; 100 "shutdown",
146 } 101 "Quit the application", HandleQuit);
147 } 102
148 103 m_console.Commands.AddCommand("General", false, "show threads",
149 if (null == m_consoleAppender) 104 "show threads",
150 { 105 "Show thread status", HandleShow);
151 Notice("No appender named Console found (see the log4net config file for this executable)!"); 106
152 } 107 m_console.Commands.AddCommand("General", false, "show version",
153 else 108 "show version",
154 { 109 "Show server version", HandleShow);
155 m_consoleAppender.Console = m_console; 110
156 111 m_console.Commands.AddCommand("General", false, "threads abort",
157 // If there is no threshold set then the threshold is effectively everything. 112 "threads abort <thread-id>",
158 if (null == m_consoleAppender.Threshold) 113 "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
159 m_consoleAppender.Threshold = Level.All; 114
160 115 m_console.Commands.AddCommand("General", false, "threads show",
161 Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); 116 "threads show",
162 } 117 "Show thread status. Synonym for \"show threads\"",
163 118 (string module, string[] args) => Notice(GetThreadsReport()));
164 m_console.Commands.AddCommand("General", false, "quit", 119
165 "quit", 120 m_console.Commands.AddCommand("General", false, "force gc",
166 "Quit the application", HandleQuit); 121 "force gc",
167 122 "Manually invoke runtime garbage collection. For debugging purposes",
168 m_console.Commands.AddCommand("General", false, "shutdown", 123 HandleForceGc);
169 "shutdown", 124 }
170 "Quit the application", HandleQuit); 125
171 126 private void HandleForceGc(string module, string[] args)
172 m_console.Commands.AddCommand("General", false, "set log level", 127 {
173 "set log level <level>", 128 MainConsole.Instance.Output("Manually invoking runtime garbage collection");
174 "Set the console logging level", HandleLogLevel); 129 GC.Collect();
175
176 m_console.Commands.AddCommand("General", false, "show info",
177 "show info",
178 "Show general information about the server", HandleShow);
179
180 m_console.Commands.AddCommand("General", false, "show stats",
181 "show stats",
182 "Show statistics", HandleShow);
183
184 m_console.Commands.AddCommand("General", false, "show threads",
185 "show threads",
186 "Show thread status", HandleShow);
187
188 m_console.Commands.AddCommand("General", false, "show uptime",
189 "show uptime",
190 "Show server uptime", HandleShow);
191
192 m_console.Commands.AddCommand("General", false, "show version",
193 "show version",
194 "Show server version", HandleShow);
195
196 m_console.Commands.AddCommand("General", false, "threads abort",
197 "threads abort <thread-id>",
198 "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
199
200 m_console.Commands.AddCommand("General", false, "threads show",
201 "threads show",
202 "Show thread status. Synonym for \"show threads\"",
203 (string module, string[] args) => Notice(GetThreadsReport()));
204 }
205 } 130 }
206 131
207 /// <summary> 132 /// <summary>
@@ -226,12 +151,7 @@ namespace OpenSim.Framework.Servers
226 { 151 {
227 StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n"); 152 StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n");
228 sb.Append(GetUptimeReport()); 153 sb.Append(GetUptimeReport());
229 154 sb.Append(StatsManager.SimExtraStats.Report());
230 if (m_stats != null)
231 {
232 sb.Append(m_stats.Report());
233 }
234
235 sb.Append(Environment.NewLine); 155 sb.Append(Environment.NewLine);
236 sb.Append(GetThreadsReport()); 156 sb.Append(GetThreadsReport());
237 157
@@ -287,26 +207,11 @@ namespace OpenSim.Framework.Servers
287 } 207 }
288 208
289 /// <summary> 209 /// <summary>
290 /// Return a report about the uptime of this server
291 /// </summary>
292 /// <returns></returns>
293 protected string GetUptimeReport()
294 {
295 StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now));
296 sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime));
297 sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime));
298
299 return sb.ToString();
300 }
301
302 /// <summary>
303 /// Performs initialisation of the scene, such as loading configuration from disk. 210 /// Performs initialisation of the scene, such as loading configuration from disk.
304 /// </summary> 211 /// </summary>
305 public virtual void Startup() 212 public virtual void Startup()
306 { 213 {
307 m_log.Info("[STARTUP]: Beginning startup processing"); 214 m_log.Info("[STARTUP]: Beginning startup processing");
308
309 EnhanceVersionInformation();
310 215
311 m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine); 216 m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine);
312 // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and 217 // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
@@ -343,60 +248,10 @@ namespace OpenSim.Framework.Servers
343 Shutdown(); 248 Shutdown();
344 } 249 }
345 250
346 private void HandleLogLevel(string module, string[] cmd) 251 public override void HandleShow(string module, string[] cmd)
347 {
348 if (null == m_consoleAppender)
349 {
350 Notice("No appender named Console found (see the log4net config file for this executable)!");
351 return;
352 }
353
354 if (cmd.Length > 3)
355 {
356 string rawLevel = cmd[3];
357
358 ILoggerRepository repository = LogManager.GetRepository();
359 Level consoleLevel = repository.LevelMap[rawLevel];
360
361 if (consoleLevel != null)
362 m_consoleAppender.Threshold = consoleLevel;
363 else
364 Notice(
365 String.Format(
366 "{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF",
367 rawLevel));
368 }
369
370 Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
371 }
372
373 /// <summary>
374 /// Show help information
375 /// </summary>
376 /// <param name="helpArgs"></param>
377 protected virtual void ShowHelp(string[] helpArgs)
378 { 252 {
379 Notice(""); 253 base.HandleShow(module, cmd);
380
381 if (helpArgs.Length == 0)
382 {
383 Notice("set log level [level] - change the console logging level only. For example, off or debug.");
384 Notice("show info - show server information (e.g. startup path).");
385
386 if (m_stats != null)
387 Notice("show stats - show statistical information for this server");
388
389 Notice("show threads - list tracked threads");
390 Notice("show uptime - show server startup time and uptime.");
391 Notice("show version - show server version.");
392 Notice("");
393 254
394 return;
395 }
396 }
397
398 public virtual void HandleShow(string module, string[] cmd)
399 {
400 List<string> args = new List<string>(cmd); 255 List<string> args = new List<string>(cmd);
401 256
402 args.RemoveAt(0); 257 args.RemoveAt(0);
@@ -405,23 +260,10 @@ namespace OpenSim.Framework.Servers
405 260
406 switch (showParams[0]) 261 switch (showParams[0])
407 { 262 {
408 case "info":
409 ShowInfo();
410 break;
411
412 case "stats":
413 if (m_stats != null)
414 Notice(m_stats.Report());
415 break;
416
417 case "threads": 263 case "threads":
418 Notice(GetThreadsReport()); 264 Notice(GetThreadsReport());
419 break; 265 break;
420 266
421 case "uptime":
422 Notice(GetUptimeReport());
423 break;
424
425 case "version": 267 case "version":
426 Notice(GetVersionText()); 268 Notice(GetVersionText());
427 break; 269 break;
@@ -447,165 +289,11 @@ namespace OpenSim.Framework.Servers
447 MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId); 289 MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId);
448 else 290 else
449 MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId); 291 MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId);
450 } 292 }
451
452 protected void ShowInfo()
453 {
454 Notice(GetVersionText());
455 Notice("Startup directory: " + m_startupDirectory);
456 if (null != m_consoleAppender)
457 Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold));
458 }
459
460 protected string GetVersionText()
461 {
462 return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion);
463 }
464
465 /// <summary>
466 /// Console output is only possible if a console has been established.
467 /// That is something that cannot be determined within this class. So
468 /// all attempts to use the console MUST be verified.
469 /// </summary>
470 /// <param name="msg"></param>
471 protected void Notice(string msg)
472 {
473 if (m_console != null)
474 {
475 m_console.Output(msg);
476 }
477 }
478
479 /// <summary>
480 /// Console output is only possible if a console has been established.
481 /// That is something that cannot be determined within this class. So
482 /// all attempts to use the console MUST be verified.
483 /// </summary>
484 /// <param name="format"></param>
485 /// <param name="components"></param>
486 protected void Notice(string format, params string[] components)
487 {
488 if (m_console != null)
489 m_console.OutputFormat(format, components);
490 }
491
492 /// <summary>
493 /// Enhance the version string with extra information if it's available.
494 /// </summary>
495 protected void EnhanceVersionInformation()
496 {
497 string buildVersion = string.Empty;
498
499 // The subversion information is deprecated and will be removed at a later date
500 // Add subversion revision information if available
501 // Try file "svn_revision" in the current directory first, then the .svn info.
502 // This allows to make the revision available in simulators not running from the source tree.
503 // FIXME: Making an assumption about the directory we're currently in - we do this all over the place
504 // elsewhere as well
505 string gitDir = "../.git/";
506 string gitRefPointerPath = gitDir + "HEAD";
507
508 string svnRevisionFileName = "svn_revision";
509 string svnFileName = ".svn/entries";
510 string manualVersionFileName = ".version";
511 string inputLine;
512 int strcmp;
513
514 if (File.Exists(manualVersionFileName))
515 {
516 using (StreamReader CommitFile = File.OpenText(manualVersionFileName))
517 buildVersion = CommitFile.ReadLine();
518
519 m_version += buildVersion ?? "";
520 }
521 else if (File.Exists(gitRefPointerPath))
522 {
523// m_log.DebugFormat("[OPENSIM]: Found {0}", gitRefPointerPath);
524
525 string rawPointer = "";
526
527 using (StreamReader pointerFile = File.OpenText(gitRefPointerPath))
528 rawPointer = pointerFile.ReadLine();
529
530// m_log.DebugFormat("[OPENSIM]: rawPointer [{0}]", rawPointer);
531
532 Match m = Regex.Match(rawPointer, "^ref: (.+)$");
533
534 if (m.Success)
535 {
536// m_log.DebugFormat("[OPENSIM]: Matched [{0}]", m.Groups[1].Value);
537
538 string gitRef = m.Groups[1].Value;
539 string gitRefPath = gitDir + gitRef;
540 if (File.Exists(gitRefPath))
541 {
542// m_log.DebugFormat("[OPENSIM]: Found gitRefPath [{0}]", gitRefPath);
543
544 using (StreamReader refFile = File.OpenText(gitRefPath))
545 {
546 string gitHash = refFile.ReadLine();
547 m_version += gitHash.Substring(0, 7);
548 }
549 }
550 }
551 }
552 else
553 {
554 // Remove the else logic when subversion mirror is no longer used
555 if (File.Exists(svnRevisionFileName))
556 {
557 StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
558 buildVersion = RevisionFile.ReadLine();
559 buildVersion.Trim();
560 RevisionFile.Close();
561 }
562
563 if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName))
564 {
565 StreamReader EntriesFile = File.OpenText(svnFileName);
566 inputLine = EntriesFile.ReadLine();
567 while (inputLine != null)
568 {
569 // using the dir svn revision at the top of entries file
570 strcmp = String.Compare(inputLine, "dir");
571 if (strcmp == 0)
572 {
573 buildVersion = EntriesFile.ReadLine();
574 break;
575 }
576 else
577 {
578 inputLine = EntriesFile.ReadLine();
579 }
580 }
581 EntriesFile.Close();
582 }
583
584 m_version += string.IsNullOrEmpty(buildVersion) ? " " : ("." + buildVersion + " ").Substring(0, 6);
585 }
586 }
587
588 protected void CreatePIDFile(string path)
589 {
590 try
591 {
592 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
593 FileStream fs = File.Create(path);
594
595 Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
596 fs.Write(buf, 0, buf.Length);
597 fs.Close();
598 m_pidFile = path;
599 }
600 catch (Exception)
601 {
602 }
603 }
604 293
605 public string osSecret { 294 public string osSecret {
606 // Secret uuid for the simulator 295 // Secret uuid for the simulator
607 get { return m_osSecret; } 296 get { return m_osSecret; }
608
609 } 297 }
610 298
611 public string StatReport(IOSHttpRequest httpRequest) 299 public string StatReport(IOSHttpRequest httpRequest)
@@ -613,27 +301,12 @@ namespace OpenSim.Framework.Servers
613 // If we catch a request for "callback", wrap the response in the value for jsonp 301 // If we catch a request for "callback", wrap the response in the value for jsonp
614 if (httpRequest.Query.ContainsKey("callback")) 302 if (httpRequest.Query.ContainsKey("callback"))
615 { 303 {
616 return httpRequest.Query["callback"].ToString() + "(" + m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");"; 304 return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");";
617 } 305 }
618 else 306 else
619 { 307 {
620 return m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); 308 return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
621 }
622 }
623
624 protected void RemovePIDFile()
625 {
626 if (m_pidFile != String.Empty)
627 {
628 try
629 {
630 File.Delete(m_pidFile);
631 m_pidFile = String.Empty;
632 }
633 catch (Exception)
634 {
635 }
636 } 309 }
637 } 310 }
638 } 311 }
639} 312} \ No newline at end of file