/// <summary> /// Print the string representation of each object in an enumerable to stdout along with its index /// </summary> /// <param name="enumerable"></param> /// <param name="logSeverity">Affects how the message will be displayed. Refer to the <see cref="LOG_SEVERITY"/> documentation.</param> public static void Cout(IEnumerable enumerable, LOG_SEVERITY logSeverity = LOG_SEVERITY.MESSAGE) { var i = 0; foreach (var item in enumerable) { Cout($"\t[{i++}] " + item, logSeverity); } }
/// <summary>Generate a custom config.</summary> /// <param name="logSeverity">The logging level of the connection.</param> /// <returns>A custom socket config.</returns> public static DiscordSocketConfig Generate(LOG_SEVERITY severity) { LogSeverity ls = Mappings.AppSevToDiscSev[severity]; return(new DiscordSocketConfig() { LogLevel = ls, }); }
/// <summary> /// Print a stream's content in the form of a hex dump /// </summary> /// <param name="stream">The stream to dump</param> /// <param name="bytesToDump">The amount of bytes to dump. The actual output might be less than this number, if the streams end was reached.</param> /// <param name="logSeverity"></param> public static void HexDump(Stream stream, int bytesToDump, LOG_SEVERITY logSeverity = LOG_SEVERITY.MESSAGE) { var bytesLeft = stream.Length - stream.Position; bytesToDump = Clamp(bytesToDump, 0, (int)bytesLeft); byte[] buffer = new byte[bytesToDump]; stream.KeepPosition(() => stream.Read(buffer, 0, bytesToDump)); HexDump(buffer, -1, logSeverity); if (stream.IsAtEnd()) { Cout("-- end of stream reached\n"); } }
/// <summary>Write a Message to the logger.</summary> /// <param name="msg">The message contents.</param> /// <param name="source">The origin of the message.</param> /// <param name="severity">The severity of the message.<param> public static void Log(string msg, string source, LOG_SEVERITY severity) { if (msg == null) { throw new ArgumentNullException("msg", "The message string cannot be null"); } if (source == null) { throw new ArgumentNullException("source", "The source string cannot be null"); } var c = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.White; switch (severity) { case LOG_SEVERITY.CRITICAL: Console.ForegroundColor = ConsoleColor.Red; break; case LOG_SEVERITY.ERROR: Console.ForegroundColor = ConsoleColor.DarkRed; break; case LOG_SEVERITY.WARNING: Console.ForegroundColor = ConsoleColor.Yellow; break; default: case LOG_SEVERITY.INFO: Console.ForegroundColor = ConsoleColor.White; break; case LOG_SEVERITY.VERBOSE: Console.ForegroundColor = ConsoleColor.Gray; break; case LOG_SEVERITY.DEBUG: Console.ForegroundColor = ConsoleColor.Cyan; break; } string LogString = $"{DateTime.Now} [{severity,8}] {source}: {msg}"; Console.WriteLine(LogString); Console.ForegroundColor = c; }
public void LoggerFormattingTest(LOG_SEVERITY sev) { const string message = "This is a test message"; const string source = "Testing"; string expected; string actual; using (MockConsoleOutput mco = new MockConsoleOutput()) { ApplicationLogger.Log(message, source, sev); expected = $"{DateTime.Now} [{sev,8}] {source}: {message}\r\n";//Note the '\r\n' is required as it writes a new line to the console. actual = mco.GetOuput(); Assert.NotNull(actual); Assert.Equal(expected, actual); } }
/// <summary> /// Print a message to stdout (and stderr depending on the <paramref name="logSeverity"/>) /// </summary> /// <param name="msg">The message to print</param> /// <param name="logSeverity">Affects how the message will be displayed. Refer to the <see cref="LOG_SEVERITY"/> documentation.</param> public static void Cout(string msg, LOG_SEVERITY logSeverity = LOG_SEVERITY.MESSAGE) { #if !DEBUG if (logSeverity == LOG_SEVERITY.DEBUG) { return; } #endif if (msg == null) { msg = "null"; } else if (msg.StartsWith("\n")) { Console.WriteLine(); msg = msg.Substring(1); } if (logSeverity != LOG_SEVERITY.MESSAGE) { msg = $"[{logSeverity}] {msg}"; } if (CoutPrintTime) { PrintTime(); } if (CoutKeepLog) { logStringBuilder.AppendLine(msg); } switch (logSeverity) { case LOG_SEVERITY.ERROR: case LOG_SEVERITY.CRITICAL: //Console.Error.WriteLine(msg); Console.WriteLine(msg); break; default: Console.WriteLine(msg); break; } }
public void Log(string message, LOG_SEVERITY severity) { switch (severity) { case LOG_SEVERITY.INFO: Console.WriteLine($"INFO: {message}"); break; case LOG_SEVERITY.WARNING: Console.WriteLine($"WARNING: {message}"); break; case LOG_SEVERITY.CRITICAL: Console.WriteLine($"CRITICAL!!!: {message}"); break; default: Console.WriteLine($"UNHANDLED?SEVERITY: {message}"); break; } }
/// <summary>Process a line from the config file.</summary> /// <param name="lineFromFile">A line from the file.</param> /// <returns>True if a valid line, false otherwise.</returns> private static bool ProcessLine(string lineFromFile) { if (lineFromFile == null) { lineFromFile = ""; } lineFromFile = lineFromFile.Trim(); //Remove the spaces from the start and end of the line. if (lineFromFile.Length == 0) //if the line is blank, "". { ApplicationLogger.Log("Blank line found - ignoring...", LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); return(true); //Return true, as a blank line is valid. } if (lineFromFile[0] == COMMENT_CHAR) //Check if the line is a comment. { ApplicationLogger.Log("Commented line found - ignoring...", LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); return(true); //Return true, as a commented line is a valid line. } //A valid line is in the format of 'Key=Value' or 'key = value', or ' key = value '. string[] splitLine = lineFromFile.Split('='); //Split the line around an '='. if (splitLine.Length != 2) { ApplicationLogger.Log("Split length not valid, required: 2, actual: " + splitLine.Length, LOGGER_SOURCE, LOG_SEVERITY.WARNING); return(false);//If the split length is not 2, then this line is invalid. } string key = splitLine[0].Trim(); string value = splitLine[1].Trim(); switch (key)//Switch the KEY. { case KEY_BOT_TOKEN: ApplicationLogger.Log("Setting Bot Token: " + value, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); mdl.Bot.Token = value; ApplicationLogger.Log("Bot Token set to:" + mdl.Bot.Token, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); break; case KEY_LOG_LEVEL: LOG_SEVERITY ll = LOG_SEVERITY.DEBUG; int iValue = 0; if (!int.TryParse(value, out iValue)) //If the value is not an integer.... { ApplicationLogger.Log("Value [" + value + "] not an integer.", LOGGER_SOURCE, LOG_SEVERITY.WARNING); return(false); //the key-value is invalid } if (Enum.IsDefined(typeof(LOG_SEVERITY), iValue)) //if the value is not defined in the enum.... { ll = (LOG_SEVERITY)iValue; } else { ApplicationLogger.Log("Value [" + value + "] not defined in Log_Level.", LOGGER_SOURCE, LOG_SEVERITY.WARNING); return(false); //The key-value pair is not valid } ApplicationLogger.Log("Setting Bot Log Level: " + ll, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); mdl.Bot.Severity = ll; ApplicationLogger.Log("Bot Log Level set to:" + mdl.Bot.Severity, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); break; case KEY_DATABASE_ADDRESS: ApplicationLogger.Log("Setting Database Address: " + value, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); mdl.Database.Address = value; ApplicationLogger.Log("Database Address set to:" + mdl.Database.Address, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); break; case KEY_DATABASE_NAME: ApplicationLogger.Log("Setting Database Name: " + value, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); mdl.Database.Name = value; ApplicationLogger.Log("Database Name set to:" + mdl.Database.Name, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); break; case KEY_DATABASE_USERNAME: ApplicationLogger.Log("Setting Database Username: "******"Database Username set to:" + mdl.Database.Username, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); break; case KEY_DATABASE_PASSWORD: ApplicationLogger.Log("Setting Database Password: "******"Database Password set to:" + mdl.Database.Password, LOGGER_SOURCE, LOG_SEVERITY.VERBOSE); break; default: ApplicationLogger.Log("Unknown key:" + key, LOGGER_SOURCE, LOG_SEVERITY.WARNING); return(false); } //If a config line is invalid return false. return(true); }
/// <summary> /// Prints the current time and <paramref name="msg"/> to stdout. See <see cref="Bio.Cout(string, LOG_SEVERITY)"/> /// </summary> /// <param name="msg">The message to print</param> /// <param name="logSeverity">Affects how the message will be displayed. Refer to the <see cref="LOG_SEVERITY"/> documentation.</param> public static void Tout(object msg, LOG_SEVERITY logSeverity = LOG_SEVERITY.MESSAGE) { PrintTime(); Cout(msg, logSeverity); }
/// <summary> /// Print the string representation of an object to stdout. See <see cref="Cout(string, LOG_SEVERITY)"/>. /// </summary> /// <param name="msg">The message to print</param> /// <param name="logSeverity">Affects how the message will be displayed. Refer to the <see cref="LOG_SEVERITY"/> documentation.</param> public static void Cout(object msg, LOG_SEVERITY logSeverity = LOG_SEVERITY.MESSAGE) { Cout(msg == null? "null": msg.ToString(), logSeverity); }
/// <summary> /// Pretty print a stream's content. /// Convenience function, which calls <see cref="HexDump(byte[], int, LOG_SEVERITY)"/> /// </summary> /// <param name="stream"></param> /// <param name="bytesToDump">The amount of bytes to print</param> /// <param name="logSeverity">Affects how the message will be displayed. Refer to the <see cref="LOG_SEVERITY"/> documentation.</param> public static void Cout(Stream stream, int bytesToDump = 256, LOG_SEVERITY logSeverity = LOG_SEVERITY.MESSAGE) { Cout(stream + " @ " + stream.Position + ":", logSeverity); HexDump(stream, bytesToDump, logSeverity); }
/// <summary> /// Pretty print a byte array. /// Convenience function, which calls <see cref="HexDump(byte[], int, LOG_SEVERITY)"/> /// </summary> /// <param name="array"></param> /// <param name="bytesToDump">The amount of bytes to print</param> /// <param name="logSeverity">Affects how the message will be displayed. Refer to the <see cref="LOG_SEVERITY"/> documentation.</param> public static void Cout(byte[] array, int bytesToDump = 256, LOG_SEVERITY logSeverity = LOG_SEVERITY.MESSAGE) { HexDump(array, bytesToDump, logSeverity); }
/// <summary> /// Print a byte array in the form of a hex dump /// </summary> /// <param name="array"></param> /// <param name="endIndex"></param> /// <param name="logSeverity"></param> public static void HexDump(byte[] array, int endIndex = -1, LOG_SEVERITY logSeverity = LOG_SEVERITY.MESSAGE) { PrintNumbers(array, endIndex, "X2", "X4", 16, 8, logSeverity); }
/// <summary> /// Print an array of numbers in a format that fits numeric values better than the generic <see cref="Cout(IEnumerable, LOG_SEVERITY)"/> /// </summary> /// <param name="array">The array to print</param> /// <param name="endIndex">The amount of values to print</param> /// <param name="formatString">The format string to pass to <see cref="byte.ToString(string)"/> for each number</param> /// <param name="formatStringOffset">The format string to pass to <see cref="byte.ToString(string)"/> for the offset at the beginning of each line</param> /// <param name="valuesPerLine">The maximum amount of numbers per line</param> /// <param name="separatorPosition">Position at which a larger gap should be inserted</param> /// <param name="logSeverity">The <see cref="LOG_SEVERITY"/> for the output</param> public static void PrintNumbers(byte[] array, int endIndex = -1, string formatString = "", string formatStringOffset = "", uint valuesPerLine = 16, uint separatorPosition = 8, LOG_SEVERITY logSeverity = LOG_SEVERITY.MESSAGE) { if (array.Length < 1) { Cout(); Cout("<empty>\n"); return; } var output = ""; endIndex = endIndex < 0? array.Length: Clamp(endIndex, 0, array.Length); for (int i = 0; i < endIndex; i++) { if (i % valuesPerLine == 0) { Cout(output, logSeverity); var offset = i / valuesPerLine; output = offset.ToString(formatStringOffset) + "\t" + array[i].ToString(formatString); } else { if (i % separatorPosition == 0) { output += " "; } output += " " + array[i].ToString(formatString); } } Cout(output, logSeverity); Cout(); }