29 using System.Collections.Generic;
30 using System.Diagnostics;
33 using System.Reflection;
35 using System.Text.RegularExpressions;
36 using System.Threading;
38 using log4net.Appender;
40 using log4net.Repository;
42 using OpenSim.Framework.Console;
43 using OpenSim.Framework.Monitoring;
45 namespace OpenSim.Framework.Servers
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 public IConfigSource Config {
get;
protected set; }
62 protected string m_startupDirectory = Environment.CurrentDirectory;
64 protected string m_pidFile = String.Empty;
75 m_startuptime = DateTime.Now;
77 EnhanceVersionInformation();
82 if (
File.Exists(path))
84 "[SERVER BASE]: Previous pid file {0} still exists on startup. Possibly previously unclean shutdown.",
89 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
91 using (FileStream fs = File.Create(path))
93 Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
94 fs.Write(buf, 0, buf.Length);
99 m_log.InfoFormat(
"[SERVER BASE]: Created pid file {0}", m_pidFile);
103 m_log.Warn(string.Format(
"[SERVER BASE]: Could not create PID file at {0} ", path), e);
109 if (m_pidFile != String.Empty)
113 File.Delete(m_pidFile);
117 m_log.Error(string.Format(
"[SERVER BASE]: Error whilst removing {0} ", m_pidFile), e);
120 m_pidFile = String.Empty;
132 m_log.InfoFormat(
"[SERVER BASE]: Starting in {0}", m_startupDirectory);
134 m_log.InfoFormat(
"[SERVER BASE]: OpenSimulator version: {0}", m_version);
140 "[SERVER BASE]: Operating system version: {0}, .NET platform {1}, {2}-bit",
141 Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ?
"64" :
"32");
146 ILoggerRepository repository = LogManager.GetRepository();
147 IAppender[] appenders = repository.GetAppenders();
149 foreach (IAppender appender
in appenders)
151 if (appender.Name ==
"Console")
155 else if (appender.Name ==
"LogFileAppender")
157 m_logFileAppender = (FileAppender)appender;
161 if (null == m_consoleAppender)
163 Notice(
"No appender named Console found (see the log4net config file for this executable)!");
168 m_consoleAppender.Console = (
ConsoleBase)m_console;
171 if (null == m_consoleAppender.Threshold)
172 m_consoleAppender.Threshold = Level.All;
174 Notice(String.Format(
"Console log level is {0}", m_consoleAppender.Threshold));
177 if (m_logFileAppender != null && startupConfig != null)
179 string cfgFileName = startupConfig.GetString(
"LogFile", null);
180 if (cfgFileName != null)
182 m_logFileAppender.File = cfgFileName;
183 m_logFileAppender.ActivateOptions();
186 m_log.InfoFormat(
"[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File);
195 if (m_console == null)
198 m_console.Commands.AddCommand(
199 "General",
false,
"show info",
"show info",
"Show general information about the server", HandleShow);
201 m_console.Commands.AddCommand(
202 "General",
false,
"show version",
"show version",
"Show server version", HandleShow);
204 m_console.Commands.AddCommand(
205 "General",
false,
"show uptime",
"show uptime",
"Show server uptime", HandleShow);
207 m_console.Commands.AddCommand(
208 "General",
false,
"get log level",
"get log level",
"Get the current console logging level",
209 (mod, cmd) => ShowLogLevel());
211 m_console.Commands.AddCommand(
212 "General",
false,
"set log level",
"set log level <level>",
213 "Set the console logging level for this session.", HandleSetLogLevel);
215 m_console.Commands.AddCommand(
216 "General",
false,
"config set",
217 "config set <section> <key> <value>",
218 "Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
220 m_console.Commands.AddCommand(
221 "General",
false,
"config get",
222 "config get [<section>] [<key>]",
223 "Synonym for config show",
226 m_console.Commands.AddCommand(
227 "General",
false,
"config show",
228 "config show [<section>] [<key>]",
229 "Show config information",
230 "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
231 +
"If a section is given but not a field, then all fields in that section are printed.",
234 m_console.Commands.AddCommand(
235 "General",
false,
"config save",
236 "config save <path>",
237 "Save current configuration to a file at the given path", HandleConfig);
239 m_console.Commands.AddCommand(
240 "General",
false,
"command-script",
241 "command-script <script>",
242 "Run a command script from file", HandleScript);
244 m_console.Commands.AddCommand(
245 "General",
false,
"show threads",
247 "Show thread status", HandleShow);
249 m_console.Commands.AddCommand(
250 "Debug",
false,
"threads abort",
251 "threads abort <thread-id>",
252 "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
254 m_console.Commands.AddCommand(
255 "General",
false,
"threads show",
257 "Show thread status. Synonym for \"show threads\"",
258 (
string module,
string[] args) => Notice(GetThreadsReport()));
260 m_console.Commands.AddCommand (
261 "Debug",
false,
"debug comms set",
262 "debug comms set serialosdreq true|false",
263 "Set comms parameters. For debug purposes.",
264 HandleDebugCommsSet);
266 m_console.Commands.AddCommand (
267 "Debug",
false,
"debug comms status",
268 "debug comms status",
269 "Show current debug comms parameters.",
270 HandleDebugCommsStatus);
272 m_console.Commands.AddCommand (
273 "Debug",
false,
"debug threadpool set",
274 "debug threadpool set worker|iocp min|max <n>",
275 "Set threadpool parameters. For debug purposes.",
276 HandleDebugThreadpoolSet);
278 m_console.Commands.AddCommand (
279 "Debug",
false,
"debug threadpool status",
280 "debug threadpool status",
281 "Show current debug threadpool parameters.",
282 HandleDebugThreadpoolStatus);
284 m_console.Commands.AddCommand(
285 "Debug",
false,
"debug threadpool level",
286 "debug threadpool level 0.." + Util.MAX_THREADPOOL_LEVEL,
287 "Turn on logging of activity in the main thread pool.",
289 +
" 0 = no logging\n"
290 +
" 1 = only first line of stack trace; don't log common threads\n"
291 +
" 2 = full stack trace; don't log common threads\n"
292 +
" 3 = full stack trace, including common threads\n",
293 HandleDebugThreadpoolLevel);
301 m_console.Commands.AddCommand(
302 "Debug",
false,
"show threadpool calls complete",
303 "show threadpool calls complete",
304 "Show details about threadpool calls that have been completed.",
305 HandleShowThreadpoolCallsComplete);
307 m_console.Commands.AddCommand(
308 "Debug",
false,
"force gc",
310 "Manually invoke runtime garbage collection. For debugging purposes",
313 m_console.Commands.AddCommand(
314 "General",
false,
"quit",
316 "Quit the application", (mod, args) => Shutdown());
318 m_console.Commands.AddCommand(
319 "General",
false,
"shutdown",
321 "Quit the application", (mod, args) => Shutdown());
323 ChecksManager.RegisterConsoleCommands(m_console);
324 StatsManager.RegisterConsoleCommands(m_console);
329 IConfig networkConfig = configSource.Configs[
"Network"];
331 if (networkConfig != null)
333 WebUtil.SerializeOSDRequestsPerEndpoint = networkConfig.GetBoolean(
"SerializeOSDRequests",
false);
337 m_serverStatsCollector.Initialise(configSource);
338 m_serverStatsCollector.Start();
341 private void HandleDebugCommsStatus(
string module,
string[] args)
343 Notice(
"serialosdreq is {0}", WebUtil.SerializeOSDRequestsPerEndpoint);
346 private void HandleDebugCommsSet(
string module,
string[] args)
348 if (args.Length != 5)
350 Notice(
"Usage: debug comms set serialosdreq true|false");
354 if (args[3] !=
"serialosdreq")
356 Notice(
"Usage: debug comms set serialosdreq true|false");
360 bool setSerializeOsdRequests;
365 WebUtil.SerializeOSDRequestsPerEndpoint = setSerializeOsdRequests;
367 Notice(
"serialosdreq is now {0}", setSerializeOsdRequests);
370 private void HandleShowThreadpoolCallsActive(
string module,
string[] args)
372 List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsInProgress().ToList();
373 calls.Sort((kvp1, kvp2) => kvp2.Value.CompareTo(kvp1.Value));
377 foreach (KeyValuePair<string, int> kvp
in calls)
381 cdl.AddRow(kvp.Key, kvp.Value);
382 namedCalls += kvp.Value;
386 cdl.AddRow(
"TOTAL NAMED", namedCalls);
388 long allQueuedCalls = Util.TotalQueuedFireAndForgetCalls;
389 long allRunningCalls = Util.TotalRunningFireAndForgetCalls;
391 cdl.AddRow(
"TOTAL QUEUED", allQueuedCalls);
392 cdl.AddRow(
"TOTAL RUNNING", allRunningCalls);
393 cdl.AddRow(
"TOTAL ANONYMOUS", allQueuedCalls + allRunningCalls - namedCalls);
394 cdl.AddRow(
"TOTAL ALL", allQueuedCalls + allRunningCalls);
396 MainConsole.Instance.Output(cdl.ToString());
399 private void HandleShowThreadpoolCallsComplete(
string module,
string[] args)
401 List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsMade().ToList();
402 calls.Sort((kvp1, kvp2) => kvp2.Value.CompareTo(kvp1.Value));
403 int namedCallsMade = 0;
406 foreach (KeyValuePair<string, int> kvp
in calls)
408 cdl.AddRow(kvp.Key, kvp.Value);
409 namedCallsMade += kvp.Value;
412 cdl.AddRow(
"TOTAL NAMED", namedCallsMade);
414 long allCallsMade = Util.TotalFireAndForgetCallsMade;
415 cdl.AddRow(
"TOTAL ANONYMOUS", allCallsMade - namedCallsMade);
416 cdl.AddRow(
"TOTAL ALL", allCallsMade);
418 MainConsole.Instance.Output(cdl.ToString());
421 private void HandleDebugThreadpoolStatus(
string module,
string[] args)
423 int workerThreads, iocpThreads;
425 ThreadPool.GetMinThreads(out workerThreads, out iocpThreads);
426 Notice(
"Min worker threads: {0}", workerThreads);
427 Notice(
"Min IOCP threads: {0}", iocpThreads);
429 ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
430 Notice(
"Max worker threads: {0}", workerThreads);
431 Notice(
"Max IOCP threads: {0}", iocpThreads);
433 ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads);
434 Notice(
"Available worker threads: {0}", workerThreads);
435 Notice(
"Available IOCP threads: {0}", iocpThreads);
438 private void HandleDebugThreadpoolSet(
string module,
string[] args)
440 if (args.Length != 6)
442 Notice(
"Usage: debug threadpool set worker|iocp min|max <n>");
451 string poolType = args[3];
452 string bound = args[4];
455 int workerThreads, iocpThreads;
457 if (poolType ==
"worker")
461 ThreadPool.GetMinThreads(out workerThreads, out iocpThreads);
463 if (!ThreadPool.SetMinThreads(newThreads, iocpThreads))
468 ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
470 if (!ThreadPool.SetMaxThreads(newThreads, iocpThreads))
478 ThreadPool.GetMinThreads(out workerThreads, out iocpThreads);
480 if (!ThreadPool.SetMinThreads(workerThreads, newThreads))
485 ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
487 if (!ThreadPool.SetMaxThreads(workerThreads, newThreads))
494 Notice(
"ERROR: Could not set {0} {1} threads to {2}", poolType, bound, newThreads);
498 int minWorkerThreads, maxWorkerThreads, minIocpThreads, maxIocpThreads;
500 ThreadPool.GetMinThreads(out minWorkerThreads, out minIocpThreads);
501 ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxIocpThreads);
503 Notice(
"Min worker threads now {0}", minWorkerThreads);
504 Notice(
"Min IOCP threads now {0}", minIocpThreads);
505 Notice(
"Max worker threads now {0}", maxWorkerThreads);
506 Notice(
"Max IOCP threads now {0}", maxIocpThreads);
510 private static void HandleDebugThreadpoolLevel(
string module,
string[] cmdparams)
512 if (cmdparams.Length < 4)
514 MainConsole.Instance.Output(
"Usage: debug threadpool level 0.." + Util.MAX_THREADPOOL_LEVEL);
518 string rawLevel = cmdparams[3];
521 if (!
int.TryParse(rawLevel, out newLevel))
523 MainConsole.Instance.OutputFormat(
"{0} is not a valid debug level", rawLevel);
527 if (newLevel < 0 || newLevel > Util.MAX_THREADPOOL_LEVEL)
529 MainConsole.Instance.OutputFormat(
"{0} is outside the valid debug level range of 0.." + Util.MAX_THREADPOOL_LEVEL, newLevel);
533 Util.LogThreadPool = newLevel;
534 MainConsole.Instance.OutputFormat(
"LogThreadPool set to {0}", newLevel);
537 private void HandleForceGc(
string module,
string[] args)
539 Notice(
"Manually invoking runtime garbage collection");
545 List<string> args =
new List<string>(cmd);
549 string[] showParams = args.ToArray();
551 switch (showParams[0])
558 Notice(GetVersionText());
562 Notice(GetUptimeReport());
566 Notice(GetThreadsReport());
576 private void HandleConfig(
string module,
string[] cmd)
578 List<string> args =
new List<string>(cmd);
580 string[] cmdparams = args.ToArray();
582 if (cmdparams.Length > 0)
584 string firstParam = cmdparams[0].ToLower();
589 if (cmdparams.Length < 4)
591 Notice(
"Syntax: config set <section> <key> <value>");
592 Notice(
"Example: config set ScriptEngine.DotNetEngine NumberOfScriptThreads 5");
597 IConfigSource source =
new IniConfigSource();
598 c = source.AddConfig(cmdparams[1]);
601 string _value = String.Join(
" ", cmdparams, 3, cmdparams.Length - 3);
602 c.Set(cmdparams[2], _value);
603 Config.Merge(source);
605 Notice(
"In section [{0}], set {1} = {2}", c.Name, cmdparams[2], _value);
612 if (cmdparams.Length == 1)
614 foreach (IConfig config
in Config.Configs)
616 Notice(
"[{0}]", config.Name);
617 string[] keys = config.GetKeys();
618 foreach (
string key in keys)
619 Notice(
" {0} = {1}", key, config.GetString(key));
622 else if (cmdparams.Length == 2 || cmdparams.Length == 3)
624 IConfig config = Config.Configs[cmdparams[1]];
627 Notice(
"Section \"{0}\" does not exist.",cmdparams[1]);
632 if (cmdparams.Length == 2)
634 Notice(
"[{0}]", config.Name);
635 foreach (
string key
in config.GetKeys())
636 Notice(
" {0} = {1}", key, config.GetString(key));
641 "config get {0} {1} : {2}",
642 cmdparams[1], cmdparams[2], config.GetString(cmdparams[2]));
648 Notice(
"Syntax: config {0} [<section>] [<key>]", firstParam);
649 Notice(
"Example: config {0} ScriptEngine.DotNetEngine NumberOfScriptThreads", firstParam);
655 if (cmdparams.Length < 2)
657 Notice(
"Syntax: config save <path>");
661 string path = cmdparams[1];
662 Notice(
"Saving configuration file: {0}", path);
664 if (Config is IniConfigSource)
666 IniConfigSource iniCon = (IniConfigSource)Config;
669 else if (Config is XmlConfigSource)
671 XmlConfigSource xmlCon = (XmlConfigSource)Config;
680 private void HandleSetLogLevel(
string module,
string[] cmd)
684 Notice(
"Usage: set log level <level>");
688 if (null == m_consoleAppender)
690 Notice(
"No appender named Console found (see the log4net config file for this executable)!");
694 string rawLevel = cmd[3];
696 ILoggerRepository repository = LogManager.GetRepository();
697 Level consoleLevel = repository.LevelMap[rawLevel];
699 if (consoleLevel != null)
700 m_consoleAppender.Threshold = consoleLevel;
703 "{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF",
709 private void ShowLogLevel()
711 Notice(
"Console log level is {0}", m_consoleAppender.Threshold);
716 if (parms.Length != 2)
718 Notice(
"Usage: command-script <path-to-script");
722 RunCommandScript(parms[1]);
731 if (m_console == null)
734 if (
File.Exists(fileName))
736 m_log.Info(
"[SERVER BASE]: Running " + fileName);
738 using (StreamReader readFile = File.OpenText(fileName))
740 string currentCommand;
741 while ((currentCommand = readFile.ReadLine()) != null)
743 currentCommand = currentCommand.Trim();
744 if (!(currentCommand ==
""
745 || currentCommand.StartsWith(
";")
746 || currentCommand.StartsWith(
"//")
747 || currentCommand.StartsWith(
"#")))
749 m_log.Info(
"[SERVER BASE]: Running '" + currentCommand +
"'");
750 m_console.RunCommand(currentCommand);
763 StringBuilder sb =
new StringBuilder(String.Format(
"Time now is {0}\n", DateTime.Now));
764 sb.Append(String.Format(
"Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime));
765 sb.Append(String.Format(
"That is an elapsed time of {0}\n", DateTime.Now - m_startuptime));
767 return sb.ToString();
772 Notice(GetVersionText());
773 Notice(
"Startup directory: " + m_startupDirectory);
774 if (null != m_consoleAppender)
775 Notice(String.Format(
"Console log level: {0}", m_consoleAppender.Threshold));
783 string buildVersion = string.Empty;
791 string gitDir =
"../.git/";
792 string gitRefPointerPath = gitDir +
"HEAD";
794 string svnRevisionFileName =
"svn_revision";
795 string svnFileName =
".svn/entries";
796 string manualVersionFileName =
".version";
800 if (
File.Exists(manualVersionFileName))
802 using (StreamReader CommitFile = File.OpenText(manualVersionFileName))
803 buildVersion = CommitFile.ReadLine();
805 m_version += buildVersion ??
"";
807 else if (
File.Exists(gitRefPointerPath))
811 string rawPointer =
"";
813 using (StreamReader pointerFile = File.OpenText(gitRefPointerPath))
814 rawPointer = pointerFile.ReadLine();
818 Match m = Regex.Match(rawPointer,
"^ref: (.+)$");
824 string gitRef = m.Groups[1].Value;
825 string gitRefPath = gitDir + gitRef;
826 if (
File.Exists(gitRefPath))
830 using (StreamReader refFile = File.OpenText(gitRefPath))
832 string gitHash = refFile.ReadLine();
833 m_version += gitHash.Substring(0, 7);
841 if (
File.Exists(svnRevisionFileName))
843 StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
844 buildVersion = RevisionFile.ReadLine();
846 RevisionFile.Close();
849 if (
string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName))
851 StreamReader EntriesFile = File.OpenText(svnFileName);
852 inputLine = EntriesFile.ReadLine();
853 while (inputLine != null)
856 strcmp = String.Compare(inputLine,
"dir");
859 buildVersion = EntriesFile.ReadLine();
864 inputLine = EntriesFile.ReadLine();
870 m_version += string.IsNullOrEmpty(buildVersion) ?
" " : (
"." + buildVersion +
" ").Substring(0, 6);
876 return String.Format(
"Version: {0} (SIMULATION/{1} - SIMULATION/{2})",
886 string reportFormat =
"{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}";
888 StringBuilder sb =
new StringBuilder();
891 sb.Append(threads.Length +
" threads are being tracked:" + Environment.NewLine);
893 int timeNow = Environment.TickCount & Int32.MaxValue;
895 sb.AppendFormat(reportFormat,
"ID",
"NAME",
"LAST UPDATE (MS)",
"LIFETIME (MS)",
"PRIORITY",
"STATE");
896 sb.Append(Environment.NewLine);
898 foreach (Watchdog.ThreadWatchdogInfo twi in threads)
906 timeNow - twi.LastTick,
907 timeNow - twi.FirstTick,
918 int totalThreads = Process.GetCurrentProcess().Threads.Count;
919 if (totalThreads > 0)
920 sb.AppendFormat(
"Total threads active: {0}\n\n", totalThreads);
922 sb.Append(
"Main threadpool (excluding script engine pools)\n");
923 sb.Append(GetThreadPoolReport());
925 return sb.ToString();
934 string threadPoolUsed = null;
937 int allocatedThreads = 0;
938 int inUseThreads = 0;
939 int waitingCallbacks = 0;
940 int completionPortThreads = 0;
942 StringBuilder sb =
new StringBuilder();
945 STPInfo stpi = Util.GetSmartThreadPoolInfo();
950 threadPoolUsed =
"SmartThreadPool";
951 maxThreads = stpi.MaxThreads;
952 minThreads = stpi.MinThreads;
953 inUseThreads = stpi.InUseThreads;
954 allocatedThreads = stpi.ActiveThreads;
955 waitingCallbacks = stpi.WaitingCallbacks;
962 threadPoolUsed =
"BuiltInThreadPool";
963 ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
964 ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
965 int availableThreads;
966 ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
967 inUseThreads = maxThreads - availableThreads;
968 allocatedThreads = -1;
969 waitingCallbacks = -1;
972 if (threadPoolUsed != null)
974 sb.AppendFormat(
"Thread pool used : {0}\n", threadPoolUsed);
975 sb.AppendFormat(
"Max threads : {0}\n", maxThreads);
976 sb.AppendFormat(
"Min threads : {0}\n", minThreads);
977 sb.AppendFormat(
"Allocated threads : {0}\n", allocatedThreads < 0 ?
"not applicable" : allocatedThreads.ToString());
978 sb.AppendFormat(
"In use threads : {0}\n", inUseThreads);
979 sb.AppendFormat(
"Work items waiting : {0}\n", waitingCallbacks < 0 ?
"not available" : waitingCallbacks.ToString());
983 sb.AppendFormat(
"Thread pool not used\n");
986 return sb.ToString();
993 MainConsole.Instance.Output(
"Usage: threads abort <thread-id>");
998 if (!
int.TryParse(cmd[2], out threadId))
1000 MainConsole.Instance.Output(
"ERROR: Thread id must be an integer");
1004 if (Watchdog.AbortThread(threadId))
1007 MainConsole.Instance.OutputFormat(
"ERROR - Thread with id {0} not found in managed threads", threadId);
1018 if (m_console != null)
1020 m_console.Output(msg);
1033 if (m_console != null)
1034 m_console.OutputFormat(
format, components);
1039 m_serverStatsCollector.Close();
Used to generated a formatted table for the console.
void OutputFormat(string format, params object[] components)
ServerStatsCollector m_serverStatsCollector
virtual void HandleScript(string module, string[] parms)
static bool TryParseConsoleInt(ICommandConsole console, string rawConsoleInt, out int i)
Convert a console input to an int, automatically complaining if a console is given.
FireAndForgetMethod
The method used by Util.FireAndForget for asynchronously firing events
virtual void HandleThreadsAbort(string module, string[] cmd)
virtual void ShutdownSpecific()
Should be overriden and referenced by descendents if they need to perform extra shutdown processing ...
Class for delivering SmartThreadPool statistical information
static bool TryParseConsoleBool(ICommandConsole console, string rawConsoleString, out bool b)
Convert a console input to a bool, automatically complaining if a console is given.
void RunCommandScript(string fileName)
Run an optional startup list of commands
static readonly float SimulationServiceVersionSupportedMin
void RegisterCommonComponents(IConfigSource configSource)
void EnhanceVersionInformation()
Enhance the version string with extra information if it's available.
OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString key
string m_version
Server version information. Usually VersionInfo + information about git commit, operating system...
void RegisterCommonAppenders(IConfig startupConfig)
void RegisterCommonCommands()
Register common commands once m_console has been set if it is going to be set
FileAppender m_logFileAppender
Writes log information out onto the console
static readonly float SimulationServiceVersionSupportedMax
virtual void HandleShow(string module, string[] cmd)
static ICommandConsole Instance
void Notice(string format, params object[] components)
Console output is only possible if a console has been established. That is something that cannot be d...
OpenSimAppender m_consoleAppender
static string GetThreadPoolReport()
Get a thread pool report.
void LogEnvironmentInformation()
Log information about the circumstances in which we're running (OpenSimulator version number...
string GetUptimeReport()
Return a report about the uptime of this server
ICommandConsole m_console
Console to be used for any command line output. Can be null, in which case there should be no output...
void CreatePIDFile(string path)
void Notice(string msg)
Console output is only possible if a console has been established. That is something that cannot be d...
string GetThreadsReport()
Get a report about the registered threads in this server.