// #############################################################################################
    // Constructor
    // #############################################################################################

        /** ****************************************************************************************
         * Creates an AnsiLogger.
         * @param textWriter     The TextWriter object to write into.
         * @param usesStdStreams Denotes whether this logger writes to the
         *                       <em>standard output streams</em>.
         * @param name           The name of the \e Logger, defaults to what is provided with
         *                       parameter \p typeName.
         * @param typeName       The type of the \e Logger, defaults to "ANSI".
         ******************************************************************************************/
        public AnsiLogger( System.IO.TextWriter textWriter, bool usesStdStreams,
                           String name= null, String typeName= "ANSI" )
            : base( name, typeName, usesStdStreams )
        {
            this.textWriter= textWriter;

            // evaluate environment variable "ALOX_CONSOLE_HAS_LIGHT_BACKGROUND"
            Variable variable= new Variable( ALox.CONSOLE_HAS_LIGHT_BACKGROUND );
            variable.Load();
            if ( variable.Size() > 0 )
                IsBackgroundLight=  variable.IsTrue();
            else
            {
                // on ANSI terminals we can only guess. Our guess is: console windows have dark background
                IsBackgroundLight= false;
            }

            // remove verbosity information and colorize the whole line
            MetaInfo.Format.SearchAndReplace( "]%V[", "][" );
            if ( IsBackgroundLight )
            {
                MsgPrefixError           = ANSI_RED;
                MsgPrefixWarning         = ANSI_BLUE;
                MsgPrefixVerbose         = ANSI_GRAY;
            }
            else
            {
                MsgPrefixError           = ANSI_LIGHT_RED;
                MsgPrefixWarning         = ANSI_LIGHT_BLUE;
                MsgPrefixVerbose         = ANSI_LIGHT_GRAY;
            }

            // set source file background to gray
            AString ansiBGGray= new AString( ESC.BG_GRAY ); ansiBGGray._( "%SF(%SL):" )._( ANSI_BG_STD_COL );
            MetaInfo.Format.SearchAndReplace( "%SF(%SL):", ansiBGGray.ToString() );
        }
 /** ********************************************************************************************
  * Creates an AnsiConsoleLogger.
  * @param name        (Optional) The name of the \e Logger, defaults to "ANSI_CONSOLE".
  **********************************************************************************************/
 public AnsiConsoleLogger( String name= null )
 : base( Console.Out, true, name, "ANSI_CONSOLE" )
 {
     // evaluate environment variable "ALOX_CONSOLE_HAS_LIGHT_BACKGROUND"
     Variable variable= new Variable( ALox.CONSOLE_HAS_LIGHT_BACKGROUND );
     variable.Load();
     if ( variable.Size() > 0 )
         IsBackgroundLight=  variable.IsTrue();
     else
     {
         ConsoleColor fgCol= Console.ForegroundColor;
         IsBackgroundLight=      fgCol == ConsoleColor.Black
                             ||  fgCol == ConsoleColor.DarkBlue
                             ||  fgCol == ConsoleColor.DarkCyan
                             ||  fgCol == ConsoleColor.DarkGray
                             ||  fgCol == ConsoleColor.DarkGreen
                             ||  fgCol == ConsoleColor.DarkMagenta
                             ||  fgCol == ConsoleColor.DarkRed
                             ||  fgCol == ConsoleColor.DarkYellow   ;
     }
 }
        /** ****************************************************************************************
         * This method must be called prior to using ALib, e.g. at the beginning of
         * the \c main() method of an application. It is OK, to call this method more than once, which
         * allows independent code blocks (e.g. libraries) to bootstrap %ALIB independently.
         * However, only the first invocation is effective with the exclamation that if
         * command line parameters are provided with a call, those are set.
         * Also, the very first invocation should not be interrupted by a parallel invocation of a
         * second thread. Consequently, it has to be assured that this method is invoked once on
         * the real bootstrap an app.
         *
         * In the C# version of the AWorx library, the invocation of this method is optional.
         * However, it is good practice to invoke this method in the main() method of a process
         * and provide the command line arguments. If no invocation is performed, no
         * configuration plug-ins are set.
         *
         * \note
         *   If other, custom configuration data sources should be used already with this method
         *   (in the current implementation, the only configuration variable read with this method
         *   is \c WAIT_FOR_KEY_PRESS), then such plug-in(s) have to be added to
         *   public, static field #Config prior to invoking this method.
         *
         * @param args    Parameters taken from <em>standard C#</em> method \c main()
         *                (the list of command line arguments).
         *                Defaults to null.
         ******************************************************************************************/
        public static void     Init( String[] args= null )
        {
            Config.SetCommandLineArgs( args );

            if ( isInitialized )
                return;
            isInitialized= true;


            // set the system's locale as the default for our static default number format
            NumberFormat.Global.SetFromLocale();

            // --- determine if we want to wait for a keypress upon termination ---
            {
                Variable variable= new Variable( ALIB.WAIT_FOR_KEY_PRESS );
                variable.Load();
                if ( variable.Size() > 0 )
                    WaitForKeyPressOnTermination= variable.IsTrue();
                else
                {
                    #if ALIB_VSTUDIO
                        WaitForKeyPressOnTermination=  ALIB.SysInfo_HasConsoleWindow && System.Diagnostics.Debugger.IsAttached;
                    #else
                        WaitForKeyPressOnTermination=  false;
                    #endif // WIN32
                }
            }
         }
Exemple #4
0
        public static void AddDebugLogger( Lox lox= null,
        [CallerLineNumber] int cln= 0,[CallerFilePath] String csf="",[CallerMemberName] String cmn="" )
        {
            #if ALOX_DBG_LOG

                if ( lox == null )
                    lox= LOX;

                ALIB.ASSERT_ERROR( DebugLogger == null, "Illeagal repeated invocation." );

                // add a CLR logger if this a debug session
                if( System.Diagnostics.Debugger.IsAttached )
                {
                    Variable variable= new Variable(ALox.NO_IDE_LOGGER);
                    variable.Load();
                    if( !variable.IsTrue() )
                    {
                        IDELogger= new CLRDebuggerLogger( "IDE_LOGGER" );

                        // add logger
                        lox.SetVerbosity( IDELogger  , Verbosity.Verbose, "/"                 , Configuration.PrioDefault ,cln,csf,cmn );
                        lox.SetVerbosity( IDELogger  , Verbosity.Warning, ALox.InternalDomains, Configuration.PrioDefault ,cln,csf,cmn );
                    }
                }

                // add a default console logger
                DebugLogger= Lox.CreateConsoleLogger("DEBUG_LOGGER");

                lox.SetVerbosity( DebugLogger, Verbosity.Verbose, "/"                 , Configuration.PrioDefault ,cln,csf,cmn );
                lox.SetVerbosity( DebugLogger, Verbosity.Warning, ALox.InternalDomains, Configuration.PrioDefault ,cln,csf,cmn );

                // replace the ReportWriter
                Log.AddALibReportWriter( lox );

            #endif
        }
        /** ****************************************************************************************
         * Invokes grand-parent's method and in addition, de-registers with
         * \ref cs::aworx::lib::ALIB::StdOutputStreamsLock "ALIB.StdOutputStreamsLock"
         * @param acquirer The acquirer to remove.
         * @return The new number of \e acquirers set.
         ******************************************************************************************/
        public override int   RemoveAcquirer( ThreadLock acquirer )
        {
            // d-register with ALIB lockers (if not done yet)
            if ( usesStdStreams )
            {
                ALIB.Lock.Acquire();
                    int  stdStreamLockRegistrationCounter= --this.stdStreamLockRegistrationCounter;
                ALIB.Lock.Release();

                if ( stdStreamLockRegistrationCounter == 0 )
                    ALIB.StdOutputStreamsLock.RemoveAcquirer( this );
            }

            Variable variable= new Variable();

            // export autosizes to configuration
            variable.Define( ALox.AUTO_SIZES, GetName() );
            AutoSizes.Export( variable.AddString() );
            variable.Store();

            // export "max elapsed time" to configuration
            variable.Define( ALox.MAX_ELAPSED_TIME, GetName() );
            AString destVal=  variable.Load() != 0  ?  variable.GetString()
                                                    :  variable.AddString();
            destVal._()._( MetaInfo.MaxElapsedTime.InSeconds() );
            variable.Store();

            // call parents' implementation
            return base.RemoveAcquirer( acquirer );
        }
    /** ********************************************************************************************
     * Creates a ConsoleLogger.
     * @param name  (Optional) The name of the \e Logger, defaults to "COLOR_CONSOLE"
     **********************************************************************************************/
    public ColorConsoleLogger( String name= null )
    : base( name, "COLOR_CONSOLE", true )
    {
        // get actual console foreground color
        ConsoleColor fgCol= Console.ForegroundColor;

        // evaluate environment variable "ALOX_CONSOLE_HAS_LIGHT_BACKGROUND"
        Variable variable= new Variable( ALox.CONSOLE_HAS_LIGHT_BACKGROUND );
        variable.Load();
        if ( variable.Size() > 0 )
            IsBackgroundLight=  variable.IsTrue();
        else
        {
            IsBackgroundLight=      fgCol == ConsoleColor.Black
                                ||  fgCol == ConsoleColor.DarkBlue
                                ||  fgCol == ConsoleColor.DarkCyan
                                ||  fgCol == ConsoleColor.DarkGray
                                ||  fgCol == ConsoleColor.DarkGreen
                                ||  fgCol == ConsoleColor.DarkMagenta
                                ||  fgCol == ConsoleColor.DarkRed
                                ||  fgCol == ConsoleColor.DarkYellow   ;
        }


        // remove verbosity information and colorize the whole line
        MetaInfo.Format.SearchAndReplace( " %V ", " " );
        MsgColorInfo          = fgCol;
        if ( IsBackgroundLight )
        {
            MsgColorError           = ConsoleColor.DarkRed;
            MsgColorWarning         = ConsoleColor.DarkBlue;
            MsgColorVerbose         = ConsoleColor.DarkGray;
        }
        else
        {
            MsgColorError           = ConsoleColor.Red;
            MsgColorWarning         = ConsoleColor.Blue;
            MsgColorVerbose         = ConsoleColor.Gray;
        }
    }
Exemple #7
0
    public void        SetVerbosity( Logger logger, Verbosity verbosity, String domain = "/",
                                     int priority = Configuration.PrioDefault,
    [CallerLineNumber] int cln=0,[CallerFilePath] String csf="",[CallerMemberName] String cmn="" )
    {
        #if ALOX_DBG_LOG || ALOX_REL_LOG
        try { Acquire();

            // initialize scope information
            scopeInfo.Set( cln,csf,cmn, owner );

            // check
            if ( logger == null )
            {
                logInternal( Verbosity.Error, "LGR", intMsg._()
                    ._NC( "Given Logger is \"null\". Verbosity not set."  ) );
                return;
            }

            // this might create the (path of) domain(s) and set the \e Loggers' verbosity like their
            // first parent's or as given in configuration
            Domain dom= evaluateResultDomain( domain );

            // search logger, insert if not found
            bool isNewLogger= false;
            int no= dom.GetLoggerNo( logger );
            if( no < 0 )
            {
                no= dom.AddLogger( logger );

                // error, logger with same name already exists
                if( no < 0 )
                {
                    logInternal( Verbosity.Error, "LGR",  intMsg._()
                            ._NC( "Unable to add logger \"" )._NC(logger)
                            ._NC("\". Logger with same name exists." ) );

                    logInternal( Verbosity.Verbose, "LGR",  intMsg._()
                              ._NC( "  Request was: SetVerbosity( \"")._(logger)._NC("\", \"")
                              ._(domain)        ._NC("\", Verbosity.")
                              ._NC(verbosity)   ._NC("\", ")
                              ._(priority)      ._NC(" )." ));

                    Logger existingLogger= dom.GetLogger( logger.GetName() );
                    logInternal( Verbosity.Verbose, "LGR", intMsg._()
                        ._NC( "  Existing Logger: \"")._NC(existingLogger)._('\"') );

                    return;
                }

                // We have to register with the SmartLock facility of the \e Logger.
                // But only if we have not done this yet, via the 'other' root domain tree
                if ( (dom.GetRoot() == domains ? internalDomains.GetLoggerNo( logger )
                                               :         domains.GetLoggerNo( logger ) ) < 0 )
                    logger.AddAcquirer( this );

                // store size of name to support tabular internal log output
                String loggerName= logger.GetName();
                if ( maxLoggerNameLength < loggerName.Length )
                    maxLoggerNameLength=   loggerName.Length;

                // for internal log
                isNewLogger= true;

                // remember that a logger was set after the last removal
                // (for variable LOXNAME_DUMP_STATE_ON_EXIT)
                loggerAddedSinceLastDebugState= true;
            }

            // do
            dom.SetVerbosity( no, verbosity, priority );

            // get verbosities from configuration
            if( isNewLogger )
            {
                logInternal( Verbosity.Info, "LGR",  intMsg._()
                    ._("Logger \"")._( logger )
                    ._(domain.StartsWith(ALox.InternalDomains) ?
                            "\" added for internal log messages." : "\" added." ) );

                // we have to get all verbosities of already existing domains
                Variable variable= new Variable( ALox.VERBOSITY, GetName(), logger.GetName() );
                if( 0 != variable.Load() )
                {
                    getAllVerbosities( logger, domains         , variable );
                    getAllVerbosities( logger, internalDomains , variable );
                }
            }

            intMsg._()._("Logger \"")._( logger.GetName() )._NC( "\":").Tab(11 + maxLoggerNameLength)
                          ._('\'')._NC( dom.FullPath )
                          ._( '\'' ).InsertChars(' ', maxDomainPathLength - dom.FullPath.Length() + 1 )
                          ._( "= Verbosity." );
                          ALox.ToString( verbosity, priority, intMsg ).TrimEnd()._('.');

            Verbosity actVerbosity= dom.GetVerbosity( no );
            if( actVerbosity != verbosity )
                intMsg._( " Lower priority (")._( priority )
                      ._(" < ")._(dom.GetPriority(no))
                      ._( "). Remains " )._NC( actVerbosity )._( '.' );
            logInternal( Verbosity.Info, "LGR", intMsg );

        } finally { Release(); }
        #endif
    }
public void ConfigDefaultAndProtected()
{
    UT_INIT();

    String[] args=
    {
        "COMMANDLINE",
        "--TEST_VARIABLE=fromCommandLine",
    };

    Configuration cfg= new Configuration();
    cfg.SetCommandLineArgs( args );

    Variable var= new Variable();

    // command line
    UT_EQ( Configuration.PrioCmdLine,    cfg.Load  ( var.Define( "TEST",      "VARIABLE" ) ) );   UT_EQ( "fromCommandLine"    ,var.GetString() );

    // set default, does not overwrite
    cfg.DefaultValues.Store( var.Define("TEST", "VARIABLE"), "not overwriting" );
    UT_EQ( Configuration.PrioCmdLine,    cfg.Load  ( var.Define( "TEST",      "VARIABLE" ) ) );   UT_EQ( "fromCommandLine"    ,var.GetString() );

    // set protected, overwrites command line
    cfg.ProtectedValues.Store( var.Define("TEST", "VARIABLE"), "does overwrite" );
    UT_EQ( Configuration.PrioProtected,  cfg.Load  ( var.Define( "TEST",      "VARIABLE" ) ) );   UT_EQ( "does overwrite"     ,var.GetString() );

    // set default, something else
    cfg.DefaultValues.Store( var.Define("TEST", "VAR2"), "this is var 2" );
    UT_EQ( Configuration.PrioDefault,    cfg.Load  ( var.Define( "TEST",      "VAR2"     ) ) );   UT_EQ( "this is var 2"      ,var.GetString() );

    // set and remove an entry using plugin interface
    var.Define( "TEST", "Remove" );     UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );
    cfg.DefaultValues.Load( var );      UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );
    var.AddString("To be deleted");     UT_EQ( 1, var.Size() );     UT_EQ( -1                           ,var.Priority );
    cfg.DefaultValues.Store( var );     UT_EQ( 1, var.Size() );     UT_EQ( -1                           ,var.Priority );
    var.Define( "TEST", "Remove" );     UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );
    cfg.DefaultValues.Load( var );      UT_EQ( 1, var.Size() );     UT_EQ( -1                           ,var.Priority );
    var.ClearValues();                  UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );
    cfg.DefaultValues.Store( var );     UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );
    var.Define( "TEST", "Remove" );     UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );
    cfg.DefaultValues.Load( var );      UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );

    // set and remove an entry using configuration interface
    cfg              .Load ( var );     UT_EQ( 0, var.Size() );     UT_EQ(  0                           ,var.Priority );
    cfg              .Store( var );     UT_EQ( 0, var.Size() );     UT_EQ(  0                           ,var.Priority );
    var.AddString("To be deleted");     UT_EQ( 1, var.Size() );     UT_EQ(  0                           ,var.Priority );
    cfg              .Store( var );     UT_EQ( 1, var.Size() );     UT_EQ( Configuration.PrioDefault    ,var.Priority );
    var.Define( "TEST", "Remove" );     UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );
    cfg              .Load ( var );     UT_EQ( 1, var.Size() );     UT_EQ( Configuration.PrioDefault    ,var.Priority );
    var.Define( "TEST", "Remove" );     UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );
    cfg              .Store( var );     UT_EQ( 0, var.Size() );     UT_EQ( Configuration.PrioDefault    ,var.Priority );
    cfg              .Load ( var );     UT_EQ( 0, var.Size() );     UT_EQ( 0                            ,var.Priority );
    var.Define( "TEST", "Remove" );     UT_EQ( 0, var.Size() );     UT_EQ( -1                           ,var.Priority );
    cfg              .Load ( var );     UT_EQ( 0, var.Size() );     UT_EQ( 0                            ,var.Priority );

    // protected
    var.Define( "TEST", "Protected");   UT_EQ( 0, var.Size() );                 UT_EQ( -1                          ,var.Priority );
    var.DefaultValue._( "Default"  );
    var.StoreDefault( "def par");       UT_EQ( "def par",   var.GetString() );  UT_EQ( Configuration.PrioDefault   ,var.Priority );

    var.ClearValues();
    var.AddString( "def var" );
    var.StoreDefault();                 UT_EQ( "def var",   var.GetString() );  UT_EQ( Configuration.PrioDefault   ,var.Priority );

    var.ClearValues();
    var.StoreDefault();                 UT_EQ( "Default",   var.GetString() );  UT_EQ( Configuration.PrioDefault   ,var.Priority );

    var.ClearValues();
    var.AddString( "def var" );
    var.Protect();                      UT_EQ( "def var",   var.GetString() );  UT_EQ( Configuration.PrioProtected ,var.Priority );
    var.Protect("prot par");            UT_EQ( "prot par",  var.GetString() );  UT_EQ( Configuration.PrioProtected ,var.Priority );
    var.ClearValues();
    var.Protect();                      UT_EQ( "Default",   var.GetString() );  UT_EQ( Configuration.PrioProtected ,var.Priority );
    var.DefaultValue.SetNull();
    var.ClearValues();
    var.Protect();                      UT_EQ( 0, var.Size()                );  UT_EQ( Configuration.PrioProtected ,var.Priority );
    var.Load();                         UT_EQ( "Default",   var.GetString() );  UT_EQ( Configuration.PrioDefault   ,var.Priority );

}
Exemple #9
0
    /** ****************************************************************************************
     * Implements functionality for configuration variable \c LOXNAME_DUMP_STATE_ON_EXIT.
     * Is called when a logger is removed.
     ******************************************************************************************/
    protected void dumpStateOnLoggerRemoval()
    {
        if( !loggerAddedSinceLastDebugState )
            return;
        loggerAddedSinceLastDebugState= false;

        Variable variable= new Variable( ALox.DUMP_STATE_ON_EXIT, GetName() );
        variable.Load();

        String      domain=         null;
        Verbosity   verbosity=      Verbosity.Info;

        Substring tok= new Substring();
        int flags= 0;
        for( int tokNo= 0; tokNo< variable.Size(); tokNo++ )
        {
            tok.Set( variable.GetString( tokNo ) );
            if( tok.IsEmpty() )
                continue;

            // state flags
                 if( tok.Equals( "NONE"            , Case.Ignore ) )  { flags= 0; break; }
            else if( tok.Equals( "Basic"           , Case.Ignore ) )  flags|= (int) Lox.StateInfo.Basic           ;
            else if( tok.Equals( "Version"         , Case.Ignore ) )  flags|= (int) Lox.StateInfo.Version         ;
            else if( tok.Equals( "Loggers"         , Case.Ignore ) )  flags|= (int) Lox.StateInfo.Loggers         ;

            else if( tok.Equals( "Domains"         , Case.Ignore ) )  flags|= (int) Lox.StateInfo.Domains         ;
            else if( tok.Equals( "InternalDomains" , Case.Ignore ) )  flags|= (int) Lox.StateInfo.InternalDomains ;
            else if( tok.Equals( "ScopeDomains"    , Case.Ignore ) )  flags|= (int) Lox.StateInfo.ScopeDomains    ;
            else if( tok.Equals( "DSR"             , Case.Ignore ) )  flags|= (int) Lox.StateInfo.DSR             ;
            else if( tok.Equals( "PrefixLogables"  , Case.Ignore ) )  flags|= (int) Lox.StateInfo.PrefixLogables  ;
            else if( tok.Equals( "Once"            , Case.Ignore ) )  flags|= (int) Lox.StateInfo.Once            ;
            else if( tok.Equals( "LogData"         , Case.Ignore ) )  flags|= (int) Lox.StateInfo.LogData         ;
            else if( tok.Equals( "ThreadMappings"  , Case.Ignore ) )  flags|= (int) Lox.StateInfo.ThreadMappings  ;

            else if( tok.Equals( "SPTR"            , Case.Ignore ) )  flags|= (int) Lox.StateInfo.SPTR            ;


            else if( tok.Equals( "All"             , Case.Ignore ) )  flags|= (int) Lox.StateInfo.All             ;

            // domain and verbosity
            else if( tok.Consume( "domain", Case.Ignore, Whitespaces.Trim ) )
            {
                if( tok.Consume( '=', Case.Sensitive, Whitespaces.Trim ) )
                    domain= tok.Trim().ToString();
            }
            else if( tok.Consume( "verbosity", Case.Ignore, Whitespaces.Trim ) )
            {
                if( tok.Consume( '=', Case.Sensitive, Whitespaces.Trim ) )
                    verbosity= ALox.ReadVerbosity( tok.Trim() );
            }

            // unknown argument
            else
            {
                logInternal( Verbosity.Error, "VAR", intMsg._()
                             ._( "Unknown argument '" )._(tok)
                             ._( "' in variable " )._(variable.Fullname)._( " = \"")._(variable.GetString())._('\"') );
            }
        }

        if ( flags != 0 )
        {
            State( domain, verbosity, "Auto dump state on exit requested: ", (Lox.StateInfo) flags );
        }
    }
Exemple #10
0
    /** ****************************************************************************************
     * Implements functionality for configuration variable \c LOXNAME_LOGGERNAME_VERBOSITY.
     * Is called when a logger is removed.
     * @param logger      The logger to write the verbosity for.
     ******************************************************************************************/
    protected void  writeVerbositiesOnLoggerRemoval( Logger logger )
    {
        // When writing back we will use this priority as the maximum to write. This way, if this was
        // an automatic default value, we will not write back into the user's variable store.
        // As always, only if the app fetches new variables on termination, this is entry is copied.
        Variable variable= new Variable( ALox.VERBOSITY, GetName(), logger.GetName() );
        variable.Load();

        // first token is "writeback" ?
        if ( variable.Size() == 0 )
            return;
        Substring firstArg= new Substring( variable.GetString() );
        if ( !firstArg.Consume( "writeback", Case.Ignore, Whitespaces.Trim ) )
            return;

        // optionally read a destination variable name
        Substring destVarCategory = new Substring();
        Substring destVarName     = new Substring();
        if( firstArg.Trim().IsNotEmpty() )
        {
            // separate category from variable name
            int catSeparatorIdx= firstArg.IndexOf( '_' );
            if (catSeparatorIdx >= 0 )
            {
                destVarCategory.Set( firstArg, 0                   , catSeparatorIdx );
                destVarName    .Set( firstArg, catSeparatorIdx + 1);
            }
            else
                destVarName.Set( firstArg );

            if ( destVarName.IsEmpty() )
            {
                logInternal( Verbosity.Error, "VAR", intMsg._()
                             ._( "Argument 'writeback' in variable " )
                             ._( variable.Fullname)
                             ._( "\n  Error:    Wrong destination variable name format\"" )
                             ._( firstArg )._( "\"" )  );
                return;
            }
        }

        // either write directly into LOX_LOGGER_VERBOSITY variable...
        Variable destVar= null;
        if( destVarName.IsEmpty() )
        {
            variable.ClearValues( 1 );
            destVar= variable;
        }
        // ...or into a new given variable
        else
        {
            destVar= new Variable( destVarCategory, destVarName, ALox.VERBOSITY.Delim );
            destVar.FormatHints=         variable.FormatHints;
            destVar.FormatAttrAlignment= variable.FormatAttrAlignment;
            destVar.Comments._("Created at runtime through config option 'writeback' in variable \"")._( variable.Fullname )._("\".");
        }

        // collect verbosities
        {
            int loggerNoMainDom= domains        .GetLoggerNo( logger );
            int loggerNoIntDom=  internalDomains.GetLoggerNo( logger );

            if ( loggerNoMainDom >= 0 ) verbositySettingToVariable( domains        , loggerNoMainDom, destVar );
            if ( loggerNoIntDom  >= 0 ) verbositySettingToVariable( internalDomains, loggerNoIntDom , destVar );
        }

        // now store using the same plug-in as original variable has
        destVar.Priority= variable.Priority;
        destVar.Store();

        // internal logging
        intMsg._()._( "Argument 'writeback' in variable " )._( variable.Fullname )
                  ._( ":\n  Verbosities for logger \"" )   ._( logger.GetName() )
                  ._( "\" written " );

        if( destVarName.IsEmpty() )
            intMsg._( "(to source variable)." );
        else
            intMsg._( "to variable \"" )  ._( destVar.Fullname ) ._("\".") ;
        logInternal( Verbosity.Info, "VAR", intMsg._( destVarName )._( "\"." ) );


        // verbose logging of the value written
        intMsg._()._("  Value:");
        for( int i= 0; i< destVar.Size() ; i++ )
            intMsg._( "\n    " )._( destVar.GetString(i) );
        logInternal( Verbosity.Verbose, "VAR", intMsg );
    }
Exemple #11
0
    /** ************************************************************************************
     * This method creates an adequate/default console logger. 'Adequate' here means that
     * this function tries to detect what might be the best choice for the environment
     * that the ALox based process is running in.
     * This method is due to changes with the evolution of future ALox versions and
     * should be considered as a convenience method to shorten the bootstrap code needed
     * to use ALox.
     *
     * The current C# implementation takes the following approach:
     *
     * - check if configuration variable
     *   [ALOX_CONSOLE_TYPE](../group__GrpALoxConfigVars.html) is set. This variable's
     *   setting takes priority and if set, the according logger is created.
     * - check whether a console window is attached to the current process.
     *   If not, then a plain text logger is chosen (class
     *   \ref cs::aworx::lox::loggers::ConsoleLogger "ConsoleLogger").
     * - Otherwise, on Unix like OS, class
     *   \ref cs::aworx::lox::loggers::AnsiConsoleLogger "AnsiConsoleLogger" is chosen,
     *   while on windows systems class
     *   \ref cs::aworx::lox::loggers::ColorConsoleLogger "ColorConsoleLogger"
     *   takes preference.
     *
     * For further information check out the source code.
     *
     * @param name (Optional) The name of the \e Logger.
     *             Defaults to null, which implies standard logger names defined
     *             in the \e Logger sub-classes.
     * @return The \b TextLogger chosen.
     **************************************************************************************/
    public static TextLogger CreateConsoleLogger( String name= null )
    {
        #if ALOX_DBG_LOG || ALOX_REL_LOG

        //--- first: check environment "ALOX_DBG_CONSOLE_TYPE". They have precedence ---
        Variable variable= new Variable(ALox.CONSOLE_TYPE);
        variable.Load();
        AString val= variable.GetString().Trim();

        if (    val.IsEmpty()
             || val.Equals( "DEFAULT",  Case.Ignore )
             || val.Equals( "PLAIN",    Case.Ignore ) )   return new ConsoleLogger     ( name );
        if(     val.Equals( "ANSI",     Case.Ignore ) )   return new AnsiConsoleLogger ( name );
        if(     val.Equals( "WINDOWS",  Case.Ignore ) )   return new ColorConsoleLogger( name );

        ALIB.WARNING( "Unrecognized value in config variable \"" + variable.Fullname
                       + "\"= " + variable.GetString() );

        //--- second: check debug environment
        // .... this is not implemented in C#, yet ...

        // not detected: in windows, we choose ColorConsoleLogger, in Unix ANSI
        if( ALIB.SysInfo_HasConsoleWindow )
            return  ALIB.SysInfo_IsWindowsOS()  ? (TextLogger) new ColorConsoleLogger( name )
                                                : (TextLogger) new AnsiConsoleLogger ( name );
        // default
        return new ConsoleLogger( name );

        #else
            return null;
        #endif
    }
Exemple #12
0
    /** ****************************************************************************************
     * Reads a prefix string from the ALib configuration system.
     * This internal method is used when a new domain is created,
     *
     * @param dom         The domain to set the verbosity for.
     ******************************************************************************************/
    protected void  getDomainPrefixFromConfig( Domain  dom )
    {
        Variable variable= new Variable( ALox.PREFIXES, GetName() );
        if( 0 == variable.Load() )
            return;

        Tokenizer prefixTok=        new Tokenizer();
        Tokenizer prefixTokInner=   new Tokenizer();
        Substring domainStr=        new Substring();
        AString   domainStrBuf=     new AString();
        Substring prefixStr=        new Substring();
        for( int varNo= 0; varNo< variable.Size(); varNo++ )
        {
            prefixTok.Set( variable.GetString( varNo ), '=' );

            domainStr.Set( prefixTok.Next() );
            if ( domainStr.StartsWith( "INTERNAL_DOMAINS", DomainSensitivity ) )
            {
                domainStrBuf._()._( domainStr.Buf, domainStr.Start + 16, domainStr.Length() -16 );
                while ( domainStrBuf.CharAtStart() == '/' )
                    domainStrBuf.DeleteStart( 1 );
                domainStrBuf.InsertAt( ALox.InternalDomains, 0 );
                domainStr.Set( domainStrBuf );
            }

            prefixTokInner.Set( prefixTok.Next(), ',' );
            prefixStr.Set( prefixTokInner.Next() );
            if ( prefixStr.IsEmpty() )
                continue;
            if ( prefixStr.Consume( '\"' ) )
                prefixStr.ConsumeFromEnd( '\"' );

            Inclusion otherPLs= Inclusion.Include;
            prefixTokInner.Next();
            if ( prefixTokInner.Actual.IsNotEmpty() )
                otherPLs= ALIB.ReadInclusion( prefixTokInner.Actual  );

            int searchMode= 0;
            if ( domainStr.Consume       ( '*' ) )    searchMode+= 2;
            if ( domainStr.ConsumeFromEnd( '*' ) )    searchMode+= 1;
            if(     ( searchMode == 0 && dom.FullPath.Equals          ( domainStr,    DomainSensitivity )     )
                ||  ( searchMode == 1 && dom.FullPath.StartsWith      ( domainStr,    DomainSensitivity )     )
                ||  ( searchMode == 2 && dom.FullPath.EndsWith        ( domainStr,    DomainSensitivity )     )
                ||  ( searchMode == 3 && dom.FullPath.IndexOf         ( domainStr, 0, DomainSensitivity ) >=0 )
                )
            {
                dom.PrefixLogables.Add( new Domain.PL( new AString( prefixStr ), otherPLs ) );

                // log info on this
                intMsg._()._NC( "String \"" )._NC( prefixStr )._NC ( "\" added as prefix logable for domain \'" )
                          ._NC( dom.FullPath )
                          ._NC( "\'. (Retrieved from variable" )
                          ._NC( variable.Fullname )._( ".)" );
                logInternal( Verbosity.Info, "PFX", intMsg );
            }
        }
    }
Exemple #13
0
    // #############################################################################################
    // Constructors
    // #############################################################################################

        /** ****************************************************************************************
         * Constructs a new, empty Lox with the given \p name.
         * The name is immutable and all \b %Lox objects registered with ALox must be unique.
         * The name \c "Log" is reserved for the internal default singleton used for debug-logging.
         * In addition, name \c "GLOBAL" is not allowed.
         *
         * If parameter \p register is \c true (the default), static method
         * \ref cs::aworx::lox::ALox::Register "ALox.Register" is invoked and the object will be
         * retrievable with static method
         * \ref cs::aworx::lox::ALox::Get "ALox.Get". In some situations, such 'registration'
         * may not be wanted.
         * @param name       The name of the Lox. Will be converted to upper case.
         * @param doRegister If \c true, this object is registered with static class
         *                   \ref cs::aworx::lox::ALox "ALox".
         *                   Optional and defaults to \c true.
         ******************************************************************************************/
        public Lox( String name, bool doRegister = true )   : base()
        {
            // set recursion warning of log buffer lock to 1. Warnings are logged if recursively
            // acquired more than once
            #if ALOX_DBG_LOG || ALOX_REL_LOG
                logBufLock.RecursionWarningThreshold= 1;

                scopeInfo=      new ScopeInfo( name, threadDictionary );
                scopeDomains=   new ScopeStore<AString                     >( scopeInfo, false );
                scopePrefixes=  new ScopeStore<Object                      >( scopeInfo, false );
                scopeLogData=   new ScopeStore<Dictionary<AString, LogData>>( scopeInfo, true  );
                scopeLogOnce=   new ScopeStore<Dictionary<AString, int[]>  >( scopeInfo, true  );


                // create domain trees
                domains          = new Domain( null, new AString( "") );
                internalDomains  = new Domain( null, new AString( ALox.InternalDomains,
                                                                  0, ALox.InternalDomains.Length - 1) );

                // create internal sub-domains
                bool wasCreated= false;
                String[] internalDomainList= {"LGR", "DMN", "PFX", "THR", "LGD", "VAR"  };
                foreach ( String it in internalDomainList )
                {
                    resDomainInternal._()._NC( it );
                    internalDomains.Find( resDomainInternal, Case.Sensitive, 1, ref wasCreated );
                }

                maxDomainPathLength= ALox.InternalDomains.Length + 3;

                // register with ALox
                if ( doRegister )
                    ALox.Register( this, ContainerOp.Insert );

                // read domain substitution rules from configuration
                Variable variable= new Variable( ALox.DOMAIN_SUBSTITUTION, GetName() );
                if ( variable.Load() != 0 )
                {
                    for( int ruleNo= 0; ruleNo< variable.Size(); ruleNo++ )
                    {
                        AString rule= variable.GetString( ruleNo );
                        int idx= rule.IndexOf( "->" );
                        if ( idx > 0 )
                        {
                            String domainPath=  rule.ToString( 0,  idx ).Trim();
                            String replacement= rule.ToString( idx + 2 ).Trim();
                            SetDomainSubstitutionRule( domainPath, replacement );
                        }
                        else
                        {
                            // using alib warning here as we can't do internal logging in the constructor
                            ALIB.WARNING( "Syntax error in variable \"" + variable.Fullname + "\"." );
                        }
                    }
                }
            #endif
        }