/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
namespace OpenSim.Framework.Console
{
public enum LogPriority : int
{
CRITICAL,
HIGH,
MEDIUM,
NORMAL,
LOW,
VERBOSE,
EXTRAVERBOSE
}
public class LogBase
{
private object m_syncRoot = new object();
private StreamWriter Log;
public conscmd_callback cmdparser;
public string componentname;
private bool m_verbose;
public LogBase(string LogFile, string componentname, conscmd_callback cmdparser, bool verbose)
{
this.componentname = componentname;
this.cmdparser = cmdparser;
m_verbose = verbose;
System.Console.WriteLine("Creating new local console");
if (String.IsNullOrEmpty(LogFile))
{
LogFile = componentname + ".log";
}
System.Console.WriteLine("Logs will be saved to current directory in " + LogFile);
Log = File.AppendText(LogFile);
Log.WriteLine("========================================================================");
Log.WriteLine(componentname + " Started at " + DateTime.Now.ToString());
}
public void Close()
{
Log.WriteLine("Shutdown at " + DateTime.Now.ToString());
Log.Close();
}
///
/// derive an ansi color from a string, ignoring the darker colors.
/// This is used to help automatically bin component tags with colors
/// in various print functions.
///
/// arbitrary string for input
/// an ansii color
private ConsoleColor DeriveColor(string input)
{
int colIdx = (input.ToUpper().GetHashCode()%6) + 9;
return (ConsoleColor) colIdx;
}
///
/// Sends a warning to the current log output
///
/// The message to send
/// WriteLine-style message arguments
public void Warn(string format, params object[] args)
{
WriteNewLine(ConsoleColor.Yellow, format, args);
return;
}
///
/// Sends a warning to the current log output
///
/// The module that sent this message
/// The message to send
/// WriteLine-style message arguments
public void Warn(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.Yellow, format, args);
return;
}
///
/// Sends a notice to the current log output
///
/// The message to send
/// WriteLine-style message arguments
public void Notice(string format, params object[] args)
{
WriteNewLine(ConsoleColor.White, format, args);
return;
}
///
/// Sends a notice to the current log output
///
/// The module that sent this message
/// The message to send
/// WriteLine-style message arguments
public void Notice(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.White, format, args);
return;
}
///
/// Sends an error to the current log output
///
/// The message to send
/// WriteLine-style message arguments
public void Error(string format, params object[] args)
{
WriteNewLine(ConsoleColor.Red, format, args);
return;
}
///
/// Sends an error to the current log output
///
/// The module that sent this message
/// The message to send
/// WriteLine-style message arguments
public void Error(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
Error(format, args);
return;
}
///
/// Sends a informational message to the current log output
///
/// The message to send
/// WriteLine-style message arguments
[Obsolete("Please tag your console messages with the location your calling from")]
public void Verbose(string format, params object[] args)
{
if (m_verbose)
{
WriteNewLine(ConsoleColor.Gray, format, args);
return;
}
}
///
/// Sends an informational message to the current log output
///
/// The module that sent this message
/// The message to send
/// WriteLine-style message arguments
public void Verbose(string sender, string format, params object[] args)
{
if (m_verbose)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.Gray, format, args);
return;
}
}
///
/// Sends a status message to the current log output
///
/// The message to send
/// WriteLine-style message arguments
public void Status(string format, params object[] args)
{
WriteNewLine(ConsoleColor.Blue, format, args);
return;
}
///
/// Sends a status message to the current log output
///
/// The module that sent this message
/// The message to send
/// WriteLine-style message arguments
public void Status(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.Blue, format, args);
return;
}
[Conditional("DEBUG")]
public void Debug(string format, params object[] args)
{
WriteNewLine(ConsoleColor.Gray, format, args);
return;
}
[Conditional("DEBUG")]
public void Debug(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.Gray, format, args);
return;
}
private void WriteNewLine(ConsoleColor color, string format, params object[] args)
{
lock (m_syncRoot)
{
string now = DateTime.Now.ToString("[MM-dd hh:mm:ss] ");
Log.Write(now);
try
{
Log.WriteLine(format, args);
Log.Flush();
}
catch (FormatException)
{
System.Console.WriteLine(args);
}
System.Console.Write(now);
try
{
if (color != ConsoleColor.White)
System.Console.ForegroundColor = color;
System.Console.WriteLine(format, args);
System.Console.ResetColor();
}
catch (ArgumentNullException)
{
// Some older systems dont support coloured text.
System.Console.WriteLine(format, args);
}
catch (System.FormatException)
{
// Some older systems dont support coloured text.
System.Console.WriteLine(args);
}
return;
}
}
private void WritePrefixLine(ConsoleColor color, string sender)
{
lock (m_syncRoot)
{
sender = sender.ToUpper();
Log.WriteLine("[" + sender + "] ");
Log.Flush();
System.Console.Write("[");
try
{
System.Console.ForegroundColor = color;
System.Console.Write(sender);
System.Console.ResetColor();
}
catch (ArgumentNullException)
{
// Some older systems dont support coloured text.
System.Console.WriteLine(sender);
}
System.Console.Write("] \t");
return;
}
}
public string ReadLine()
{
try
{
string TempStr = System.Console.ReadLine();
Log.WriteLine(TempStr);
return TempStr;
}
catch (Exception e)
{
MainLog.Instance.Error("Console", "System.Console.ReadLine exception " + e.ToString());
return "";
}
}
public int Read()
{
int TempInt = System.Console.Read();
Log.Write((char) TempInt);
return TempInt;
}
public IPAddress CmdPromptIPAddress(string prompt, string defaultvalue)
{
IPAddress address;
string addressStr;
while (true)
{
addressStr = MainLog.Instance.CmdPrompt(prompt, defaultvalue);
if (IPAddress.TryParse(addressStr, out address))
{
break;
}
else
{
MainLog.Instance.Error("Illegal address. Please re-enter.");
}
}
return address;
}
public int CmdPromptIPPort(string prompt, string defaultvalue)
{
int port;
string portStr;
while (true)
{
portStr = MainLog.Instance.CmdPrompt(prompt, defaultvalue);
if (int.TryParse(portStr, out port))
{
if (port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort)
{
break;
}
}
MainLog.Instance.Error("Illegal address. Please re-enter.");
}
return port;
}
// Displays a prompt and waits for the user to enter a string, then returns that string
// Done with no echo and suitable for passwords
public string PasswdPrompt(string prompt)
{
// FIXME: Needs to be better abstracted
Log.WriteLine(prompt);
Notice(prompt);
ConsoleColor oldfg = System.Console.ForegroundColor;
System.Console.ForegroundColor = System.Console.BackgroundColor;
string temp = System.Console.ReadLine();
System.Console.ForegroundColor = oldfg;
return temp;
}
// Displays a command prompt and waits for the user to enter a string, then returns that string
public string CmdPrompt(string prompt)
{
Notice(String.Format("{0}: ", prompt));
return ReadLine();
}
// Displays a command prompt and returns a default value if the user simply presses enter
public string CmdPrompt(string prompt, string defaultresponse)
{
string temp = CmdPrompt(String.Format("{0} [{1}]", prompt, defaultresponse));
if (temp == "")
{
return defaultresponse;
}
else
{
return temp;
}
}
// Displays a command prompt and returns a default value, user may only enter 1 of 2 options
public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB)
{
bool itisdone = false;
string temp = CmdPrompt(prompt, defaultresponse);
while (itisdone == false)
{
if ((temp == OptionA) || (temp == OptionB))
{
itisdone = true;
}
else
{
Notice("Valid options are " + OptionA + " or " + OptionB);
temp = CmdPrompt(prompt, defaultresponse);
}
}
return temp;
}
// Runs a command with a number of parameters
public Object RunCmd(string Cmd, string[] cmdparams)
{
cmdparser.RunCmd(Cmd, cmdparams);
return null;
}
// Shows data about something
public void ShowCommands(string ShowWhat)
{
cmdparser.Show(ShowWhat);
}
public void MainLogPrompt()
{
string tempstr = CmdPrompt(componentname + "# ");
MainLogRunCommand(tempstr);
}
public void MainLogRunCommand(string command)
{
string[] tempstrarray;
tempstrarray = command.Split(' ');
string cmd = tempstrarray[0];
Array.Reverse(tempstrarray);
Array.Resize(ref tempstrarray, tempstrarray.Length - 1);
Array.Reverse(tempstrarray);
string[] cmdparams = (string[]) tempstrarray;
try
{
RunCmd(cmd, cmdparams);
}
catch (Exception e)
{
MainLog.Instance.Error("Console", "Command failed with exception " + e.ToString());
}
}
public string LineInfo
{
get
{
string result = String.Empty;
string stacktrace = Environment.StackTrace;
List lines = new List(stacktrace.Split(new string[] {"at "}, StringSplitOptions.None));
if (lines.Count > 4)
{
lines.RemoveRange(0, 4);
string tmpLine = lines[0];
int inIndex = tmpLine.IndexOf(" in ");
if (inIndex > -1)
{
result = tmpLine.Substring(0, inIndex);
int lineIndex = tmpLine.IndexOf(":line ");
if (lineIndex > -1)
{
lineIndex += 6;
result += ", line " + tmpLine.Substring(lineIndex, (tmpLine.Length - lineIndex) - 5);
}
}
}
return result;
}
}
}
}