void SampleALibReport() { Console.WriteLine("Sample: ALib Report via using ALox"); Log.AddDebugLogger(); Log.SetDomain("/SAMPLE", Scope.Filename); Log.SetVerbosity(Log.DebugLogger, Verbosity.Info, ""); Log.Info("Method \"Log.AddDebugLogger()\" by default creates a replacement for ALibs'\n" + "error/warning reporter. If this is a debug compiliation, let's have a try and\n" + "create 3 Messages:"); Report.GetDefault().PushHaltFlags(false, false); ALIB.ERROR("This is an error report!"); ALIB.WARNING("And this is a warning!"); AString illegalAccess = new AString(10); illegalAccess._("1234"); illegalAccess.SetCharAt_NC(5, '5'); Report.GetDefault().PopHaltFlags(); Log.SetVerbosity(Log.DebugLogger, Verbosity.Verbose, ALox.InternalDomains); ALIB.REPORT(2, "This is an ALib Report. Types other than '0' and '1' are user defined.\n" + "Verbosity of ALox.InternalDomains has to be increased to see them when using" + " ALoxReportWriter."); Log.Info("Note the domain prefix '" + ALox.InternalDomains.ToString() + "'. This addresses " + "the tree of internal domains\nof the Lox, which the report writer is just " + "using for ALib reports."); Log.RemoveDebugLogger(); }
public bool RemovePlugin(ConfigurationPlugIn plugin) { for (int i = 0; i < plugins.Count; i++) { if (plugins[i].plugIn == plugin) { plugin.Parent = null; plugins.RemoveAt(i); return(true); } } ALIB.WARNING("No Plug-in was removed "); return(false); }
void Register(Lox lox, ContainerOp operation) { try { ALIB.Lock.Acquire(); // check if (lox == null) { ALIB.ERROR("null given"); return; } // remove if (operation == ContainerOp.Remove) { if (!loxes.Remove(lox)) { ALIB.WARNING("A lox named \"" + lox.GetName() + "\" could not be found for removal."); } } // insert else { foreach (Lox it in loxes) { if (it.GetName().Equals(lox.GetName( ))) { ALIB.ERROR("A lox named \"" + lox.GetName() + "\" was already registered. Registration ignored"); return; } } loxes.Add(lox); } } finally { ALIB.Lock.Release(); } }
/** ******************************************************************************************** * Processes the next command found in the format string, by writing formatted information * into the given buffer. * The given Substring holds the next command. When method returns, the command is cut * from the front. * * @param logger The logger that we are embedded in. * @param domain The <em>Log Domain</em>. * @param verbosity The verbosity. This has been checked to be active already on this * stage and is provided to be able to be logged out only. * @param scope Information about the scope of the <em>Log Statement</em>.. * @param dest The buffer to write meta information into. * @param variable The variable to read (may have more characters appended) * * @return The number of tab sequences that were written (by adding ESC::TAB to the buffer). **********************************************************************************************/ protected virtual int processVariable(TextLogger logger, Domain domain, Verbosity verbosity, ScopeInfo scope, AString dest, Substring variable) { // process commands char c2; switch (variable.Consume()) { // scope info case 'S': { // read sub command AString val; switch (c2 = variable.Consume()) { case 'P': // SP: full path { int length; String path = scope.GetFullPath(out length); if (length > 0) { dest._(path, 0, length); return(0); } val = NoSourceFileInfo; } break; case 'p': // Sp: trimmed path { val = scope.GetTrimmedPath(); if (val.IsEmpty()) { val = NoSourceFileInfo; } } break; case 'F': // file name { val = scope.GetFileName(); if (val.IsEmpty()) { val = NoSourceFileInfo; } } break; case 'f': // file name without extension { val = scope.GetFileNameWithoutExtension(); if (val.IsEmpty()) { val = NoSourceFileInfo; } } break; case 'M': // method name { String method = scope.GetMethod(); if (method.Length == 0) { dest._(NoMethodInfo); } else { dest._(method); } return(0); } case 'L': // line number { dest._(scope.GetLineNumber()); return(0); } default: { if (!warnedOnce) { warnedOnce = true; ALIB.WARNING("Unknown format variable '%S" + c2 + "\' (only one warning)"); } dest._("%ERROR"); return(0); } } dest._(val); return(0); } // %Tx: Time case 'T': { // read sub command c2 = variable.Consume(); // %TD: Date if (c2 == 'D') { // get time stamp as DateTime once if (callerDateTime == null) { callerDateTime = scope.GetTimeStamp().InDotNetDateTime(); } // avoid the allocation of a) a StringBuilder (yes, a string builder is allocated inside StringBuilder.AppendFormat!) // and b) a DateTime object, if the format is the unchanged standard. And it is faster anyhow. if (DateFormat.Equals("yyyy-MM-dd")) { dest._(callerDateTime.Value.Year, 4)._('-') ._(callerDateTime.Value.Month, 2)._('-') ._(callerDateTime.Value.Day, 2); } // support user defined standards else { // detect changes of format string since last log if (detectDateFormatChanges != DateFormat) { detectDateFormatChanges = DateFormat; dateFormatString = "{0:" + DateFormat + "}"; } // get date string from system and append to log buffer formatSB.Clear(); formatSB.AppendFormat(CultureInfo.InvariantCulture, dateFormatString, callerDateTime); dest._(formatSB); } } // %TT: Time of Day else if (c2 == 'T') { // get time stamp as DateTime once if (callerDateTime == null) { callerDateTime = scope.GetTimeStamp().InDotNetDateTime(); } // avoid the allocation of a) a StringBuilder (yes, a string builder is allocated inside StringBuilder.AppendFormat!) // and b) a DateTime object, if the format is the unchanged standard. And it is faster anyhow. if (TimeOfDayFormat.Equals("HH:mm:ss")) { dest._(callerDateTime.Value.Hour, 2)._(':') ._(callerDateTime.Value.Minute, 2)._(':') ._(callerDateTime.Value.Second, 2); } // support user defined standards else { // detect changes of format string since last log if (detectTimeOfDayFormatChanges != TimeOfDayFormat) { detectTimeOfDayFormatChanges = TimeOfDayFormat; timeOfDayFormatString = "{0:" + TimeOfDayFormat + "}"; } // get time string from system and append to log buffer formatSB.Clear(); formatSB.AppendFormat(CultureInfo.InvariantCulture, timeOfDayFormatString, callerDateTime); dest._(formatSB); } } // %TC: Time elapsed since created else if (c2 == 'C') { // create TimeSpan object (on the stack by using new! :) TimeSpan elapsed = new TimeSpan(scope.GetTimeStamp().Raw() - logger.TimeOfCreation.Raw()); if (elapsed.Days > 0) { dest._(elapsed.Days)._(TimeElapsedDays); } if (elapsed.Hours > 0) { dest._(elapsed.Hours)._(':'); } dest._(elapsed.Minutes, 2)._(':') ._(elapsed.Seconds, 2)._('.') ._(elapsed.Milliseconds, 3); } // %TL: Time elapsed since last log call else if (c2 == 'L') { writeTimeDiff(dest, scope.GetTimeStamp().Since(logger.TimeOfLastLog).InNanos()); } else { if (!warnedOnce) { warnedOnce = true; ALIB.WARNING("Unknown format variable '%T" + c2 + "\' (only one warning)"); } dest._("%ERROR"); } return(0); } // thread name / ID case 't': { c2 = variable.Consume(); if (c2 == 'N') { dest.Field() ._(scope.GetThreadName()) .Field(logger.AutoSizes.Next(scope.GetThreadName().Length(), 0), Alignment.Center); } else if (c2 == 'I') { tmpAString._()._(scope.GetThreadID()); dest.Field() ._(tmpAString) .Field(logger.AutoSizes.Next(tmpAString.Length(), 0), Alignment.Center); } else { if (!warnedOnce) { warnedOnce = true; ALIB.WARNING("Unknown format variable '%t" + c2 + "\' (only one warning)"); } dest._("%ERROR"); } return(0); } case 'L': { c2 = variable.Consume(); if (c2 == 'G') { dest._NC(logger.GetName()); } else if (c2 == 'X') { dest._NC(scope.GetLoxName()); } else { if (!warnedOnce) { warnedOnce = true; ALIB.WARNING("Unknown format variable '%L" + c2 + "\' (only one warning)"); } dest._("%ERROR"); return(0); } return(0); } case 'P': { dest._NC(Util.GetProcessName()); return(0); } case 'V': dest._(verbosity == Verbosity.Error ? VerbosityError : verbosity == Verbosity.Warning ? VerbosityWarning : verbosity == Verbosity.Info ? VerbosityInfo : VerbosityVerbose); return(0); case 'D': { dest.Field()._(domain.FullPath).Field(logger.AutoSizes.Next(domain.FullPath.Length(), 0), Alignment.Left); return(0); } case '#': dest._(logger.CntLogs, LogNumberMinDigits); return(0); // A: Auto tab case 'A': { // read extra space from format string int oldStart = variable.Start; int extraSpace; variable.ConsumeInteger(out extraSpace); if (oldStart == variable.Start) { extraSpace = 1; } // insert ESC code to jump to next tab level extraSpace = Math.Min(extraSpace, 10 + ('Z' - 'A')); char escNo = extraSpace < 10 ? (char)('0' + extraSpace) : (char)('A' + extraSpace); dest._("\x1Bt")._(escNo); return(1); } default: { if (!warnedOnce) { warnedOnce = true; ALIB.WARNING("Unknown format variable \'" + variable.Buf[variable.Start - 1] + "\'"); } dest._("%ERROR"); } return(0); } }
// ############################################################################################# // Interface // ############################################################################################# /** ******************************************************************************************** * Thread which invokes this method gets registered as the current owner of this object, until the * same thread releases the ownership invoking Release(). * In the case that this object is already owned by another thread, the invoking thread is suspended * until ownership can be gained. * Multiple (nested) calls to this method are counted and the object is only released when the same * number of Release() calls have been made. * * @param cln (Optional) Caller info, compiler generated. Please omit. * @param csf (Optional) Caller info, compiler generated. Please omit. * @param cmn (Optional) Caller info, compiler generated. Please omit. **********************************************************************************************/ public void Acquire( [CallerLineNumber] int cln = 0, [CallerFilePath] String csf = "", [CallerMemberName] String cmn = "") { // are we in unsafe mode? if (mutex == null) { // we are still increasing the lockCount lockCount = lockMode == LockMode.Recursive ? lockCount + 1 : 1; // reached warning limit if (lockCount <= 0) { ALIB.ERROR("Unsafe mode: Counter invalid (<= 0): This should never happen. Set lock to safe mode!"); } else if (lockCount % RecursionWarningThreshold == 0) { ALIB.WARNING("Recursion depth " + lockCount + ". To prevent this, change ThreadSafe.recursionWarningThreshold or fix your code!"); } // end of unsafe version of this method return; } // get current thread Thread thisThread = Thread.CurrentThread; // synchronize on mutex lock ( mutex ) { // we already own the thread if (owner == thisThread) { // we are still increasing the lockCount lockCount = lockMode == LockMode.Recursive ? lockCount + 1 : 1; // reached warning limit if (lockCount % RecursionWarningThreshold == 0) { ALIB.WARNING("Recursion depth " + lockCount + ". To prevent this, change ThreadSafe.recursionWarningThreshold or fix your code!"); } return; } // we do not own this thread, wait until lock is free bool hasWarned = false; while (owner != null) { try { // wait unconditional if (waitWarningTimeLimitInMillis <= 0 || hasWarned) { Monitor.Wait(mutex); } // wait with time limit else { waitTime.Set(); Monitor.Wait(mutex, waitWarningTimeLimitInMillis); long time = waitTime.Age().InMillis(); if (time >= waitWarningTimeLimitInMillis) { hasWarned = true; ALIB.WARNING("Timeout (" + waitWarningTimeLimitInMillis + " ms). Change your codes critical section length if possible." + CString.NewLineChars + "This thread: " + thisThread.ManagedThreadId + "/" + thisThread.Name + CString.NewLineChars + "Owning thread: " + (owner != null ? (owner.ManagedThreadId + "/" + owner.Name) : "null") #if DEBUG + CString.NewLineChars + "Location of acquirement: " + acquirementSourcefile + ":" + acquirementLineNumber + " " + acquirementMethodName + "()" #endif ); } } } catch (Exception) {} // ignore spurious wakeups } // take control owner = thisThread; #if DEBUG acquirementLineNumber = cln; acquirementSourcefile = csf; acquirementMethodName = cmn; #endif lockCount = 1; } // synchronized }
// ############################################################################################# // logText // ############################################################################################# /** ******************************************************************************************** * * The implementation of the abstract method of parent class TextLogger. Logs messages to the * application console and/or the VStudio output window. * * @param domain The <em>Log Domain</em>. * @param verbosity The verbosity. This has been checked to be active already on this * stage and is provided to be able to be logged out only. * @param msg The log message * @param scope Information about the scope of the <em>Log Statement</em>.. * @param lineNumber The line number of a multi-line message, starting with 0. For * single line messages this is -1. **********************************************************************************************/ override protected void logText(Domain domain, Verbosity verbosity, AString msg, ScopeInfo scope, int lineNumber) { // loop over message, print the parts between the escape sequences Tokenizer msgParts = new Tokenizer(msg, '\x001B'); Substring actual = msgParts.Actual; Substring rest = msgParts.Rest; int column = 0; for (;;) { msgParts.Next(Whitespaces.Keep); // check if this is an ANSI sequence already if (rest.CharAtStart() == '[') { // read the 'm' int idx = rest.IndexOf('m'); if (idx < 0) // unknown ANSI Code { ALIB.WARNING("Unknown ANSI ESC Code "); textWriter.Write(actual.Buf, actual.Start, actual.Length()); continue; } column += actual.Length(); actual.End = rest.Start + idx; rest.Start += idx + 1; textWriter.Write(actual.Buf, actual.Start, actual.Length()); continue; } else { if (actual.IsNotEmpty()) { textWriter.Write(actual.Buf, actual.Start, actual.Length()); column += actual.Length(); } } // end of loop? if (!msgParts.HasNext()) { break; } // found an ESC sequence char c = rest.Consume(); // Colors bool isForeGround = true; if (c == 'C' || c == 'c') { isForeGround = c == 'c'; c = rest.Consume(); int colNo = c - '0'; ALIB.ASSERT_WARNING(colNo >= 0 && colNo <= 9, "Unknown ESC-c code"); // add bg colNo += isForeGround ? 0 : 10; // add light colNo += (isForeGround ? !IsBackgroundLight : IsBackgroundLight) ? 20 : 0; textWriter.Write(ansiCols[colNo]); } // Styles else if (c == 's') { // bold/italics style not supported in Windows console // reset all if (rest.Consume() == 'a') { textWriter.Write(ANSI_RESET); } } // auto tab / end of meta else if (c == 't' || c == 'A') { bool endOfMeta = c == 'A'; c = rest.Consume(); int extraSpace = c >= '0' && c <= '9' ? (int)(c - '0') : (int)(c - 'A') + 10; int tabStop = AutoSizes.Next(column, extraSpace); Util.WriteSpaces(textWriter, tabStop - column); column = tabStop; if (endOfMeta) { String msgPrefix; switch (verbosity) { case lox.Verbosity.Verbose: msgPrefix = MsgPrefixVerbose; break; case lox.Verbosity.Info: msgPrefix = MsgPrefixInfo; break; case lox.Verbosity.Warning: msgPrefix = MsgPrefixWarning; break; case lox.Verbosity.Error: msgPrefix = MsgPrefixError; break; default: msgPrefix = ""; break; } textWriter.Write(msgPrefix); } } // Link (we just colorize links here) else if (c == 'l') { textWriter.Write(rest.Consume() == 'S' ? (IsBackgroundLight ? ANSI_LIGHT_BLUE : ANSI_LIGHT_BLUE) : ANSI_STD_COL); } else { ALIB.WARNING("Unknown ESC code"); } } // write loop textWriter.WriteLine(MsgSuffix); }
/** ******************************************************************************************** * * The implementation of the abstract method of parent class TextLogger. Logs messages to the * application console and/or the VStudio output window. * * @param domain The <em>Log Domain</em>. * @param verbosity The verbosity. This has been checked to be active already on this * stage and is provided to be able to be logged out only. * @param msg The log message. * @param scope Information about the scope of the <em>Log Statement</em>.. * @param lineNumber The line number of a multi-line message, starting with 0. For * single line messages this is -1. **********************************************************************************************/ override protected void logText(Domain domain, Verbosity verbosity, AString msg, ScopeInfo scope, int lineNumber) { // get actual console attributes ConsoleColor actualFGCol = Console.ForegroundColor; ConsoleColor actualBGCol = Console.BackgroundColor; // loop over message, print the parts between the escape sequences Tokenizer msgParts = new Tokenizer(msg, '\x1B'); Substring actual = msgParts.Actual; Substring rest = msgParts.Rest; int column = 0; for (;;) { if (msgParts.Next(Whitespaces.Keep).IsNotEmpty()) { #if !(ALOX_WP71 || ALOX_WP8) Console.Write(msg.Buffer(), actual.Start, actual.Length()); #else Console.Write(msg.ToString(0, actual.Start, actual.Length()); #endif column += actual.Length(); } // end of loop? if (!msgParts.HasNext()) { break; } // found an ESC sequence char c = rest.Consume(); // Colors bool isForeGround = true; if (c == 'C' || c == 'c') { isForeGround = c == 'c'; c = rest.Consume(); int colNo = c - '0'; ALIB.ASSERT_WARNING(colNo >= 0 && colNo <= 9, "Unknown ESC-c code"); // set color if (colNo >= 0 && colNo <= 8 || colNo == 8) { ConsoleColor[] cols = (isForeGround ? !IsBackgroundLight : IsBackgroundLight) ? lightColors : darkColors; if (isForeGround) { Console.ForegroundColor = cols[colNo]; } else { Console.BackgroundColor = cols[colNo]; } } else if (colNo == 9) { if (isForeGround) { Console.ForegroundColor = actualFGCol; } else { Console.BackgroundColor = actualBGCol; } } else { ALIB.WARNING("Unknown ESC- code"); } } // Styles else if (c == 's') { // bold/italics style not supported in Windows console // reset all if (rest.Consume() == 'a') { Console.ForegroundColor = actualFGCol; Console.BackgroundColor = actualBGCol; } } // auto tab / end of meta else if (c == 't' || c == 'A') { bool endOfMeta = c == 'A'; c = rest.Consume(); int extraSpace = c >= '0' && c <= '9' ? (int) (c - '0') : (int)(c - 'A') + 10; int tabStop = AutoSizes.Next(column, extraSpace); Util.WriteSpaces(Console.Out, tabStop - column); column = tabStop; if (endOfMeta) { switch (verbosity) { case Verbosity.Verbose: Console.ForegroundColor = MsgColorVerbose; break; case Verbosity.Info: Console.ForegroundColor = MsgColorInfo; break; case Verbosity.Warning: Console.ForegroundColor = MsgColorWarning; break; case Verbosity.Error: Console.ForegroundColor = MsgColorError; break; default: break; } } } // Link (we just colorize links here) else if (c == 'l') { if (rest.Consume() == 'S') { Console.ForegroundColor = IsBackgroundLight ? ConsoleColor.DarkBlue : ConsoleColor.Blue; } else { Console.ForegroundColor = actualFGCol; } } else { ALIB.WARNING("Unknown ESC code"); } } // write loop // reset colors Console.ForegroundColor = actualFGCol; Console.BackgroundColor = actualBGCol; // write NL #if !(ALOX_WP71 || ALOX_WP8) Console.WriteLine(); #else Console.WriteLine(); #endif }