ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
loxpimpl.cpp
1#if !DOXYGEN
2#if !ALIB_SINGLE_THREADED
3# define UNDEFINED_THREAD threads::UNDEFINED
4#else
5# define UNDEFINED_THREAD 0
6#endif
7
9 ALIB_COMMA alib::variables::Priority>, vt_lox_pair_verby_prio )
10
12#endif
13
15
16namespace alib { namespace lox { namespace detail {
17
18/// Domain substitution rules.
20 /// Rule types.
21 enum class Type {
22 Exact, ///< Exact match.
23 StartsWith, ///< Starts with match.
24 EndsWith, ///< Ends with match.
25 Substring ///< Any substring.
26 };
27
28 Type type; ///< Denotes the type of the rule, depending of what
29 ///< was set in originally as search path
30 NString32 Search; ///< The path to search.
31 NString32 Replacement; ///< The replacement.
32
33 /// Constructor.
34 /// @param s The path to search.
35 /// @param r The replacement.
36 DomainSubstitutionRule( const NString& s, const NString& r ) {
37 Search .DbgDisableBufferReplacementWarning();
38 Replacement.DbgDisableBufferReplacementWarning();
39
40 // get type and adjust given search parameter
41 integer startPos= 0;
42 integer length= s.Length();
43 if ( s.CharAtStart() == '*' ) {
44 ++startPos;
45 --length;
46 if ( s.CharAtEnd() == '*' ) {
48 --length;
49 }
50 else
52 } else {
53 if ( s.CharAtEnd() == '*' ) {
55 --length;
56 }
57 else
59 }
60 Search._( s, startPos, length );
61
62 // minimum rule check
63 if ( ( ( type == Type::Exact
65 && Search.CharAtStart() != '/'
66 )
67 || ( type == Type::EndsWith
68 && Search.CharAtEnd() == '/'
69 )
70 )
71 Search.Reset(); // illegal rule
72
73
74 Replacement= r;
75 }
76}; // struct DomainSubstitutionRule
77
78
79//==================================================================================================
80/// Implementation struct for class #"Lox" following the
81/// \https{Pimpl Idiom,en.cppreference.com/w/cpp/language/pimpl}.
82//==================================================================================================
83struct LoxImpl {
84 /// The self-contained monotonic allocator, that also contains this struct itself.
86
87 /// A pool allocator that uses #"monoAllocator" as its source.
89
90 /// Snapshot taken before embedding the lox in the #"monoAllocator".
92
93 #if !ALIB_SINGLE_THREADED
94 /// A mutex to control parallel access.
96 #endif
97
98 /// Counts the number of nested (recursive) acquirements.
100
101 /// A counter for the quantity of calls. The count includes logs suppressed by
102 /// disabled <em>Log Domain</em> and those suppressed by the optional log condition parameter.
104
105 /// A list of a list of logables used for (recursive) logging.
107
108 /// A list of a list of logables used for (recursive) internal logging.
110
111 /// The recursion counter for internal logging.
113
114 /// Information about the source code, method, thread, etc. invoking a log call
116
117 /// The root domain \"/\". All registered domains become a sub domain of this root.
118 /// If a <em>Sub-Log Domain's Verbosity</em> is not explicitly set, such sub domain inherits
119 /// the verbosity of its parent.
121
122 /// The root domain for internal <em>Log Domains</em>.
124
125 /// Scope Domains
127
128 /// Prefix logables store
130
131 /// Log once counters
133
134 /// Log data store
136
137 /// Used for tabular output of logger lists
139
140 /// Used for tabular output of logger lists
142
143 /// A key value used in stores if no key is given (global object).
145
146
147 /// The list of domain substitution rules.
149
150 /// Flag if a warning on circular rule detection was logged.
152
153 /// Flag used with configuration variable LOXNAME_DUMP_STATE_ON_EXIT.
155
156 /// Constructor.
157 /// @param ma The externally created, self-contained monotonic allocator, that also contains
158 /// this instance.
159 /// @param name The lox's name.
176
177 /// Destructor.
179 // unregister each logger in std domains and remove it in internals
180 for ( int i= domains->CountLoggers() - 1 ; i >= 0 ; --i ) {
181 Logger* logger= domains->GetLogger( i );
182 int ii= internalDomains->GetLoggerNo( logger );
183 if ( ii >= 0 )
184 internalDomains->RemoveLogger( ii );
186 }
187
188 // unregister remaining loggers in internal domains
189 for ( int i= internalDomains->CountLoggers() - 1 ; i >= 0 ; --i ) {
190 Logger* logger= internalDomains->GetLogger( i );
192 } }
193
194 /// Returns the number of (recursive) acquirements of this #"%Lox".
195 /// If greater than \c 1, this is either recursive logging or a user has explicitly
196 /// acquired this lox repeatedly (which is not recommended to do).
197 ///
198 /// @return The number of acquirements.
199 int CountAcquirements() const noexcept { return AcquirementsCount; }
200
201 /// Shortcut to allocate arbitrary objects in #"poolAllocator".
202 /// @tparam T The type to allocate.
203 /// @tparam TArgs Types of variadic parameters given with parameter \p{args}.
204 /// Deduced by the compiler.
205 /// @param args Variadic parameters to be forwarded to the constructor of type \p{T}.
206 /// @return The allocated object.
207 template<typename T, typename... TArgs>
208 T* newPO(TArgs&&... args) { return poolAllocator().New<T>(std::forward<TArgs>(args)...); }
209
210 /// Shortcut to delete arbitrary objects in #".poolAllocator".
211 /// @tparam T The type to allocate. Deduced by the compiler.
212 /// @param o The allocated object.
213 template<typename T>
214 void deletePO(T* o) { poolAllocator().Delete<T>(o); }
215
216}; // struct LoxImpl
217
218#if !DOXYGEN
219#define ASSERT_ACQUIRED ALIB_ASSERT_ERROR( impl->CountAcquirements() >0,"ALOX","Lox not acquired" )
220#endif
221
222//##################################################################################################
223// Constructors/destructor
224//##################################################################################################
227 MonoAllocator* selfContainedMA= MonoAllocator::Create( ALIB_DBG(nullptr,) ha, 8* 1024 );
228 ALIB_DBG( selfContainedMA->DbgName= NCString(*selfContainedMA, NString128("Lox") << name).Buffer(); )
229 auto snapShot= selfContainedMA->TakeSnapshot();
230 LoxImpl* result= (*selfContainedMA)().New<LoxImpl>( selfContainedMA, name );
231 result->beforeLox= snapShot;
232 return result;
233}
234
235void LI::Destruct( LoxImpl* impl ) {
236 auto& ma= impl->monoAllocator;
237 impl->~LoxImpl();
238 lang::Destruct(ma); // just destruct, as this is self-contained
239}
240
241const NString& LI::GetName(LoxImpl* impl) { return impl->scopeInfo.loxName; }
242
244
245#if !ALIB_SINGLE_THREADED
247{
249 return impl->Lock;
250}
251#endif
252
253void LI::Acquire(LoxImpl* impl, const lang::CallerInfo& ci ) {
254 #if !ALIB_SINGLE_THREADED
256 , impl->Lock.AcquireRecursive(ci); )
257 #else
259 #endif
260 ++impl->AcquirementsCount;
261 impl->scopeInfo.Set( ci );
262}
263
264void LI::Release(LoxImpl* impl) {
266 --impl->AcquirementsCount;
267 #if !ALIB_SINGLE_THREADED
269 #endif
270}
271
272void LI::init(LoxImpl* impl) {
273 impl->logableContainers.reserve(5); // 5 equals the recursive logging warning threshold
274
275 // create domain trees
276 impl->domains = impl->monoAllocator().New<Domain>(impl->monoAllocator, impl->poolAllocator, "" );
277 impl->internalDomains= impl->monoAllocator().New<Domain>(impl->monoAllocator, impl->poolAllocator, "$" );
278
279 // create internal Subdomains
280 const NString internalDomainList[]= {"LGR","DMN", "PFX", "THR", "LGD", "VAR" };
281 for ( auto& it : internalDomainList )
282 impl->internalDomains->Find( it, 1, nullptr );
283 impl->maxDomainPathLength= Lox::InternalDomains.Length() + 3;
284
285 // read domain substitution rules from configuration
287 {
288 ALIB_LOCK_WITH(ALOX.GetConfig())
291 GetName(impl)
292 #else
293 String128( GetName( impl ) )
294 #endif
295 );
296 }
297 if ( var.IsDefined() ) {
298 for( int ruleNo= 0 ; ruleNo < var.Size() ; ++ruleNo ) {
299 Substring rule= var.GetString(ruleNo);
300 if( rule.Trim().IsEmpty() )
301 continue;
302
303 integer idx= rule.IndexOf( A_CHAR("->") );
304 if ( idx > 0 ) {
305 NString256 domainPath ( rule.Substring<NC>( 0, idx ) ); domainPath .Trim();
306 NString256 replacement( rule.Substring<NC>( idx + 2, rule.Length() - idx - 2 ) ); replacement.Trim();
307 SetDomainSubstitutionRule( impl, domainPath, replacement );
308 } else {
309 // using alib warning here as we can't do internal logging in the constructor
310 ALIB_WARNING( "ALOX", "Syntax error in variable \"{}\".", var )
311 } } }
312
313}
314
315void LI::Reset(LoxImpl* impl) {
316 #if ALOX_DBG_LOG
317 if( impl == Log::Get()->impl && Log::DEBUG_LOGGER != nullptr ) {
321 }
322 #endif
323
325 999999, // code for clearing
327
328 // clear the monotonic allocator and rebuild the impl
329 MonoAllocator* loxMA = &impl->monoAllocator;
330 auto snapshot = impl->beforeLox;
331 NString128 name( impl->scopeInfo.loxName);
332 (*loxMA)().Delete(impl);
333 loxMA->Reset(snapshot);
334 ALIB_DBG( auto* dbgNewAddress= )
335 (*loxMA)().New<LoxImpl>(loxMA, name ); // creates the impl at the same position, therefore, it does not need
336 // to be stored (and passed back)
337 ALIB_ASSERT_ERROR( impl == dbgNewAddress, "ALOX", "Internal error. This must never happen." )
338 impl->beforeLox= snapshot;
339}
340
341void LI::SetFileNameCacheCapacity( LoxImpl* impl, integer numberOfLists, integer entriesPerList )
342{ impl->scopeInfo.SetFileNameCacheCapacity( numberOfLists, entriesPerList ); }
343
344#if ALIB_DEBUG_MEMORY
346#endif
347
349 const NCString& path,
350 lang::Inclusion includeString ,
351 int trimOffset ,
352 lang::Case sensitivity ,
353 const NString& trimReplacement,
354 lang::Reach reach ,
355 Priority priority )
356{
357 impl->scopeInfo.SetSourcePathTrimRule( path, includeString, trimOffset, sensitivity,
358 trimReplacement, reach, priority );
359}
360
361void LI::SetDomain( LoxImpl* impl , const NString& scopeDomain,
362 Scope scope, threads::Thread* thread ) {
363 if ( !isThreadRelatedScope( impl, scope ) )
364 return;
365 setDomain( impl, scopeDomain, scope, false, thread );
366}
367
368//##################################################################################################
369// Methods
370//##################################################################################################
371Logger* LI::GetLogger(LoxImpl* impl, const NString& loggerName ) {
372 ASSERT_ACQUIRED
373
374 // search logger
375 Logger* logger;
376 if ( (logger= impl->domains ->GetLogger( loggerName ) ) != nullptr ) return logger;
377 if ( (logger= impl->internalDomains->GetLogger( loggerName ) ) != nullptr ) return logger;
378
379 // not found
380 BoxesMA& logables= acquireInternalLogables(impl);
381 logables.Add( "No logger named {!Q} found.", loggerName );
382 logInternal( impl, Verbosity::Warning, "LGR", logables );
383 return nullptr;
384}
385
386//! @cond NO_DOX
387namespace {
388void writeVerbVarRecursive( Domain& domain, int loggerNo, CVVerbosities& verbosities,
389 Verbosity parentVerbosity ) {
390 auto verbosity= domain.GetVerbosity( loggerNo );
391 if( parentVerbosity != verbosity || verbosities.ExportAll )
392 verbosities.Add(String256(domain.FullPath) << '=' << verbosity );
393
394 // loop over all subdomains (recursion)
395 for ( Domain& subDomain : domain.SubDomains )
396 writeVerbVarRecursive( subDomain, loggerNo, verbosities, verbosity );
397}
398} // anonymous namespace
399//! @endcond
400
402DOX_MARKER([DOX_VARIABLES_REPLACEMENTS2])
404{ALIB_LOCK_WITH(ALOX.GetConfig())
405 // a local array of boxes of size two, to fill variable placeholders
406 Box replacements[2]=
407 {
408 GetName( impl ), // name of this Lox
409 logger->GetName() // name of the Logger
410 };
411
412 // declare the individually named variable
413 var.Declare( Variables::VERBOSITY, replacements );
414}
415DOX_MARKER( [DOX_VARIABLES_REPLACEMENTS2])
416 // we do not care about the writing rights.
417 (void) var.Define();
418 auto& cvVerb= var.Get<CVVerbosities>();
419 cvVerb.Clear();
420
421 // collect verbosities
422 {
423 int loggerNoMainDom= impl->domains ->GetLoggerNo( logger );
424 int loggerNoIntDom= impl->internalDomains->GetLoggerNo( logger );
425
426 if ( loggerNoMainDom >= 0 ) writeVerbVarRecursive( *impl->domains , loggerNoMainDom, cvVerb, Verbosity(-1) );
427 if ( loggerNoIntDom >= 0 ) writeVerbVarRecursive( *impl->internalDomains, loggerNoIntDom , cvVerb, Verbosity(-1) );
428 }
429
430 // internal logging
431 {
432 // get variable name. Needs shared acquisition
433 String256 varName;
434 { ALIB_LOCK_SHARED_WITH(ALOX.GetConfig())
435 varName << var; // this is needed because we are logging the name of a variable!
436 }
437 BoxesMA& logables= acquireInternalLogables(impl);
438 logables.Add( "Verbosities for logger {!Q} written to variable {!Q}",
439 logger->GetName(), varName );
440 logInternal( impl, Verbosity::Info, "VAR", logables );
441 }
442
443 // verbose logging of the value written
444 {
445 BoxesMA& logables= acquireInternalLogables(impl);
446 logables.Add(" Value:");
447 for( auto& it : cvVerb )
448 logables.Add( "\n ", it );
449 logInternal( impl, Verbosity::Verbose, "VAR", logables );
450} }
451
454 return;
456
459 GetName( impl )
460 #else
461 String128( GetName( impl ) )
462 #endif
463 );
464 if( !variable.IsDefined() )
465 return;
466 NString64 domain;
467 Verbosity verbosity= Verbosity::Info;
468 Substring tok;
469 bool error= false;
471 Tokenizer tknzr;
472 tknzr.Set(variable, ',', true);
473 while( tknzr.HasNext() ) {
474 tok= tknzr.Next();
475
476 // read log domain and verbosity
477 if( tok.IndexOf( '=' ) > 0 ) {
478 if( tok.ConsumePartOf<lang::Case::Ignore, lang::Whitespaces::Trim>( A_CHAR("verbosity"), 1) ) {
480 enumrecords::Parse<Verbosity>( tok, verbosity );
481 continue;
482 }
485 domain= tok.Trim();
486 continue;
487 }
488 error= true;
489 break;
490 }
491
492 // read and add state
493 StateInfo stateInfo;
494 if( !enumrecords::Parse<StateInfo>( tok, stateInfo ) ) {
495 error= true;
496 break;
497 }
498
499 // None clears all, others are added
500 if( stateInfo == StateInfo::NONE )
501 flags= StateInfo::NONE;
502 else
503 flags|= stateInfo;
504 }
505 if( error ) {
506 BoxesMA& logables= acquireInternalLogables(impl);
507 logables.Add( "Unknown argument {!Q} in variable {} = {!Q}.",
508 tok, variable, variable.GetString() );
509 logInternal( impl, Verbosity::Error, "VAR", logables);
510 }
511
512 if ( flags != StateInfo::NONE ) {
513 State( impl, domain, verbosity, A_CHAR("Auto dump state on exit requested: "), flags );
514} }
515
516
517bool LI::RemoveLogger( LoxImpl* impl, Logger* logger ) {
518 ASSERT_ACQUIRED
519
520 int noMainDom= impl->domains ->GetLoggerNo( logger );
521 int noIntDom= impl->internalDomains->GetLoggerNo( logger );
522
523 if( noMainDom >= 0 || noIntDom >= 0 ) {
525 writeVerbositiesOnLoggerRemoval( impl, logger );
526
527 if( noMainDom >= 0 )
528 impl->domains->RemoveLogger( noMainDom );
529
530 if( noIntDom >= 0 )
531 impl->internalDomains->RemoveLogger( noIntDom );
532
534
535 return true;
536 }
537
538 // not found
539 BoxesMA& logables= acquireInternalLogables(impl);
540 logables.Add( "Logger {!Q} not found. Nothing removed.", logger );
541 logInternal( impl, Verbosity::Warning, "LGR", logables );
542 return false;
543}
544
545Logger* LI::RemoveLogger(LoxImpl* impl, const NString& loggerName ) {
546 ASSERT_ACQUIRED
547
548 int noMainDom= impl->domains ->GetLoggerNo( loggerName );
549 int noIntDom= impl->internalDomains->GetLoggerNo( loggerName );
550
551 if( noMainDom >= 0 || noIntDom >= 0 ) {
552 Logger* logger= impl->domains->GetLogger( noMainDom );
553 if( logger == nullptr ) logger= impl->internalDomains->GetLogger( noIntDom );
554
556 writeVerbositiesOnLoggerRemoval( impl, logger );
557
558 if( noMainDom >= 0 )
559 impl->domains->RemoveLogger( noMainDom );
560
561 if( noIntDom >= 0 )
562 impl->internalDomains->RemoveLogger( noIntDom );
563
565
566 BoxesMA& logables= acquireInternalLogables(impl);
567 logables.Add( "Logger {!Q} removed.", logger );
568 logInternal( impl, Verbosity::Info, "LGR", logables );
569 return logger;
570 }
571
572 // not found
573 BoxesMA& logables= acquireInternalLogables(impl);
574 logables.Add( "Logger {!Q} not found. Nothing removed.", loggerName );
575 logInternal( impl, Verbosity::Warning, "LGR", logables );
576
577 return nullptr;
578}
579
580void LI::SetVerbosity(LoxImpl* impl, Logger* logger, Verbosity verbosity, const NString& domain, Priority priority )
581{ ASSERT_ACQUIRED
582
583 // check
584 if ( logger == nullptr ) {
585 BoxesMA& logables= acquireInternalLogables(impl);
586 logables.Add( "Given Logger is \"null\". Verbosity not set." );
587 logInternal( impl, Verbosity::Error, "LGR", logables );
588 return;
589 }
590
591 // this might create the (path of) domain(s) and set the \e Logger's verbosities like their
592 // first parent's or as given in configuration
593 Domain* dom= evaluateResultDomain( impl, domain );
594
595 // search logger, insert if not found
596 bool isNewLogger= false;
597 int no= dom->GetLoggerNo( logger );
598 if( no < 0 ) {
599 no= dom->AddLogger( logger );
600
601 // error, logger with same name already exists
602 if( no < 0 ) {
603 logInternal( impl, Verbosity::Error, "LGR", acquireInternalLogables(impl)
604 .Add( "Unable to add logger {!Q}. Logger with same name exists.", logger ) );
605
606
607 logInternal( impl, Verbosity::Verbose, "LGR",
608 acquireInternalLogables(impl).Add(
609 " Request was: SetVerbosity({!Q}, {!Q}, Verbosity::{}, {}). ",
610 logger, dom->FullPath, verbosity, priority ) );
611
612 Logger* existingLogger= dom->GetLogger( logger->GetName() );
613 logInternal( impl, Verbosity::Verbose, "LGR", acquireInternalLogables(impl)
614 .Add( " Existing Logger: {!Q}.", existingLogger ) );
615
616 return;
617 }
618
619 // We have to tell the logger that it got inserted, but only if we have not done this yet,
620 // via the 'other' root domain tree.
621 if ( ( dom->GetRoot() == impl->domains ? impl->internalDomains->GetLoggerNo( logger )
622 : impl->domains->GetLoggerNo( logger )
623 ) < 0 )
624 {
626 }
627
628 // store size of name to support tabular internal log output
629 if ( impl->maxLoggerNameLength < logger->GetName().Length() )
630 impl->maxLoggerNameLength= logger->GetName().Length();
631
632 // for internal log
633 isNewLogger= true;
634
635 // remember that a logger was set after the last removal
636 // (for variable LOXNAME_DUMP_STATE_ON_EXIT)
638 }
639
640 // get verbosities from configuration
641 if( isNewLogger ) {
642 BoxesMA& logables= acquireInternalLogables(impl);
643 logables.Add( "Logger {!Q}.", logger );
644 if( domain.StartsWith(Lox::InternalDomains) )
645 logables.Add(" added for internal log messages.");
646 else
647 logables.Add(" added.");
648 logInternal( impl, Verbosity::Info, "LGR", logables );
649
650 // we have to get all verbosities of already existing domains
651 Box replacements[2]= { GetName( impl ), logger->GetName() };
652 Variable varVerbosities= variables::CampVariable(ALOX, Variables::VERBOSITY, replacements );
653 if( varVerbosities.IsDefined() ) {
654 getAllVerbosities( impl, varVerbosities, logger, *impl->domains );
655 getAllVerbosities( impl, varVerbosities, logger, *impl->internalDomains );
656 } }
657
658 // do
659 dom->SetVerbosity( no, verbosity, priority );
660
661 BoxesMA& logables= acquireInternalLogables(impl);
662
663 logables.Add( "Logger {!Q}: {!Fill}{!Q'}{!Fill}= Verbosity::{}.",
664 logger->GetName(),
665 impl->maxLoggerNameLength - logger->GetName().Length(),
666 dom->FullPath,
667 impl->maxDomainPathLength - dom->FullPath.Length() + 1,
668 boxing::MakePair(verbosity, priority) );
669
670 Verbosity actVerbosity= dom->GetVerbosity( no );
671 if( actVerbosity != verbosity )
672 logables.Add( " Lower priority ({} < {}). Remains {}.",
673 priority, dom->GetPriority(no), actVerbosity );
674
675 logInternal( impl, Verbosity::Info, "LGR", logables );
676}
677
678void LI::SetVerbosity(LoxImpl* impl , const NString& loggerName,
679 Verbosity verbosity, const NString& domain , Priority priority ) {
680 // get logger
681 Logger* logger;
682 {
683 ASSERT_ACQUIRED
684
685 Domain* dom= evaluateResultDomain( impl, domain );
686
687 int no= dom->GetLoggerNo( loggerName );
688 if( no >= 0 )
689 logger= dom->GetLogger( no );
690 else {
691 // we have to check if the logger was added in the 'other' tree
692 Domain* otherTree= dom->GetRoot() == impl->domains ? impl->internalDomains
693 : impl->domains;
694 no= otherTree->GetLoggerNo( loggerName );
695 if ( no < 0 ) {
696 // error
697 BoxesMA& logables= acquireInternalLogables(impl);
698 logables.Add( "Logger not found. Request was: SetVerbosity({!Q}, {!Q}, Verbosity::{}, {}).",
699 loggerName, dom->FullPath, verbosity, priority );
700 logInternal( impl, Verbosity::Warning, "LGR", logables );
701 return;
702 }
703
704 logger= otherTree->GetLogger( no );
705 } }
706 // use the overloaded method
707 SetVerbosity( impl, logger, verbosity, domain, priority );
708}
709
710void LI::SetVerbosityExport(LoxImpl* impl, Logger* logger, bool value, Priority priority) {
711 ALIB_LOCK_WITH(ALOX.GetConfig())
712 Variable verbVar(*ALOX.GetConfig());
713
714 Box replacements[2] { impl->scopeInfo.loxName, logger->GetName() };
715
716 if ( !verbVar.Declare( lox::Variables::VERBOSITY, replacements ).IsDeclared()
717 || !verbVar.Define(priority) )
718 return;
719
720 auto& varValue= verbVar.Get<lox::CVVerbosities>();
721 varValue.ExportAll= value;
722 if ( value )
723 varValue.WriteBack= true;
724}
725
727 const NString& loggerName,
728 bool value,
729 Priority priority ) {
730 Logger* logger= LI::GetLogger( impl, loggerName );
731 if (logger)
732 SetVerbosityExport(impl, logger, value, priority);
733}
734
736 const NString& scopeDomain,
737 Scope scope,
738 bool removeNTRSD,
739 threads::Thread* thread ) {
740 //note: the public class interface ensures that \p{removeNTRSD} (named thread related scope
741 // domain) only evaluates true for thread related scopes.
742 ASSERT_ACQUIRED
743
744 // check
745 int pathLevel= checkScopeInformation( impl, scope, "DMN" );
746 if( pathLevel < 0 )
747 return;
748
749 #if !ALIB_SINGLE_THREADED
750 ThreadID threadID= thread != nullptr ? thread->GetID() : UNDEFINED_THREAD;
751 #else
752 threads::ThreadID threadID= UNDEFINED_THREAD;
753 (void) thread;
754 #endif
755
756 NString previousScopeDomain;
757
758 impl->scopeDomains.InitAccess( scope, pathLevel, threadID );
759 if ( removeNTRSD ) {
760 previousScopeDomain= impl->scopeDomains.Remove( scopeDomain );
761 } else {
762 if ( scopeDomain.IsNotEmpty() ) {
763 NString128 trimmable( scopeDomain );
764 previousScopeDomain= impl->scopeDomains.Store( NString(impl->poolAllocator,
765 trimmable.Trim() ) );
766 }
767 else
768 previousScopeDomain= impl->scopeDomains.Remove( nullptr );
769 }
770
771 // log info on this
772 BoxesMA& logables= acquireInternalLogables(impl);
773 if ( !removeNTRSD && scopeDomain.IsNotEmpty() ) {
774 logables.Add("{!Q'} set as default for {}.", scopeDomain, (scope + pathLevel) );
775
776 if ( previousScopeDomain.IsNull() )
777 logInternal( impl, Verbosity::Info, "DMN", logables );
778 else {
779 if ( previousScopeDomain.Equals<NC>( scopeDomain ) ) {
780 logables.Add( "(Wasalreadyset.)");
781 logInternal( impl,Verbosity::Verbose,"DMN",logables);
782 } else {
783 logables.Add( " Replacing previous default {!Q'}.", previousScopeDomain );
784 logInternal( impl, Verbosity::Warning, "DMN", logables );
785 } }
786
787 } else {
788 if ( previousScopeDomain.IsNotNull() ) {
789 logables.Add("{!Q'} removed from {}.", previousScopeDomain, (scope + pathLevel) );
790 logInternal( impl, Verbosity::Info, "DMN", logables );
791 } else {
792 if ( removeNTRSD )
793 logables.Add("{!Q'} not found. Nothing removed for {}.", scopeDomain );
794 else
795 logables.Add("Empty Scope Domain given, nothing registered for {}.", scopeDomain);
796
797 logables.Add( scope + pathLevel);
798 logInternal( impl, Verbosity::Warning, "DMN", logables );
799 } }
800
801 // it is on us to delete the previous one
802 if ( previousScopeDomain.IsNotNull() )
803 previousScopeDomain.Free(impl->poolAllocator);
804}
805
806void LI::RemoveThreadDomain( LoxImpl* impl, const NString& scopeDomain,
807 Scope scope, threads::Thread* thread ) {
808 if ( !isThreadRelatedScope( impl, scope ) )
809 return;
810
811 // check
812 if ( scopeDomain.IsEmpty() ) {
813 BoxesMA& logables= acquireInternalLogables(impl);
814 logables.Add( "Illegal parameter. No scope domain path given. Nothing removed for {}.",
815 scope );
816 logInternal( impl, Verbosity::Warning, "DMN", logables );
817
818 // do nothing
819 return;
820 }
821
822 // invoke internal master
823 setDomain( impl, scopeDomain, scope, true, thread);
824}
825
826void LI::SetDomainSubstitutionRule(LoxImpl* impl, const NString& domainPath,
827 const NString& replacement ) {
828 // check null param: clears all rules
829 if ( domainPath.IsEmpty() ) {
830 impl->oneTimeWarningCircularDS= false;
831 impl->domainSubstitutions.Clear();
832 logInternal( impl, Verbosity::Info, "DMN", "Domain substitution rules removed.");
833 return;
834 }
835
836
837 // create rule
838 DomainSubstitutionRule newRule( domainPath, replacement );
839 if ( newRule.Search.IsEmpty() ) {
840 logInternal( impl, Verbosity::Warning, "DMN",
841 "Illegal domain substitution rule. Nothing stored." );
842 return;
843 }
844
845 // search existing rule
847 for( it= impl->domainSubstitutions.begin(); it != impl->domainSubstitutions.end() ; ++it ) {
848 if ( (*it).type == newRule.type
849 && (*it).Search.Equals<NC>( newRule.Search ) )
850 break;
851 }
852
853 // no replacement given?
854 if ( replacement.IsEmpty() ) {
855 BoxesMA& logables= acquireInternalLogables(impl);
856 if ( it == impl->domainSubstitutions.end() ) {
857 logables.Add("Domain substitution rule {!Q} not found. Nothing to remove.", domainPath);
858 logInternal( impl, Verbosity::Warning, "DMN", logables );
859 return;
860 }
861
862 logables.Add("Domain substitution rule {!Q} -> {!Q} removed.",domainPath,(*it).Replacement);
863 logInternal( impl, Verbosity::Info, "DMN", logables );
864 (void) impl->domainSubstitutions.erase( it );
865 return;
866 }
867
868 BoxesMA& logables= acquireInternalLogables(impl);
869 logables.Add("Domain substitution rule {!Q} -> {!Q} set.", domainPath, newRule.Replacement );
870
871 // change of rule
872 NString256 msg;
873 if ( it != impl->domainSubstitutions.end() ) {
874 msg << " Replacing previous -> \"" << (*it).Replacement << "\".";
875 logables.Add( msg );
876 (*it).Replacement.Reset( newRule.Replacement );
877 }
878 else
879 impl->domainSubstitutions.emplace_back( newRule );
880
881 if( ALOX.IsBootstrapped() ) // this function might be called very early.
882 logInternal( impl, Verbosity::Info, "DMN", logables );
883}
884
885void LI::setPrefix(LoxImpl* impl, const Box& prefix, Scope scope, threads::Thread* thread ) {
886 ASSERT_ACQUIRED
887
888 // check
889 int pathLevel= checkScopeInformation( impl, scope, "PFX" );
890 if( pathLevel < 0 )
891 return;
892
893 #if !ALIB_SINGLE_THREADED
894 ThreadID threadID= thread != nullptr ? thread->GetID() : UNDEFINED_THREAD;
895 #else
896 threads::ThreadID threadID= UNDEFINED_THREAD;
897 (void) thread;
898 #endif
899
900 impl->scopePrefixes.InitAccess( scope, pathLevel, threadID );
901 bool isVoidOrEmpty= prefix.IsType<void>()
902 || prefix.IsNull()
903 || ( prefix.IsArray() && !prefix.UnboxLength() );
904
905 Box* previousLogable= !isVoidOrEmpty ? impl->scopePrefixes.Store( impl->newPO<PrefixLogable>( impl->poolAllocator, prefix ) )
906 : impl->scopePrefixes.Remove( nullptr );
907
908
909 BoxesMA& logables= acquireInternalLogables(impl);
910 logables.Add( "Object ");
911 Verbosity intMsgVerbosity= Verbosity::Info;
912 if ( !isVoidOrEmpty ) {
913 logables.Add( prefix, " added as prefix logable for {}.", (scope + pathLevel) );
914
915 if ( previousLogable != nullptr ) {
916 if ( previousLogable->Call<FEquals>( prefix ) ) {
917 logables.Add(" (Same as before.)");
918 intMsgVerbosity= Verbosity::Verbose;
919 }
920 else
921 logables.Add(" Replacing previous {}.", *previousLogable );
922 }
923 } else {
924 if ( previousLogable != nullptr )
925 logables.Add( "{!Q} removed from list of prefix logables for {}.", *previousLogable);
926 else {
927 logables.Add( "<nullptr> given but no prefix logable to remove for {}.");
928 intMsgVerbosity= Verbosity::Warning;
929 }
930 logables.Add( scope + pathLevel );
931 }
932
933 logInternal( impl, intMsgVerbosity, "PFX", logables );
934
935 // it is on us to delete the previous one
936 if ( previousLogable != nullptr )
937 impl->deletePO(static_cast<PrefixLogable*>( previousLogable ));
938}
939
940
941void LI::SetPrefix( LoxImpl* impl , const Box& prefix,
942 const NString& domain, lang::Inclusion otherPLs ) {
943
944 ASSERT_ACQUIRED
945
946 Domain* dom= evaluateResultDomain( impl, domain );
947
948 bool isVoidOrEmpty= prefix.IsType<void>()
949 || prefix.IsNull()
950 || ( prefix.IsArray() && !prefix.UnboxLength() );
951
952 BoxesMA& logables= acquireInternalLogables(impl);
953 Verbosity intLogVerbosity= Verbosity::Info;
954 PrefixLogable* removedLogable= nullptr;
955
956 if ( !isVoidOrEmpty ) {
957 // create logable: if String* type, then copy the string. We are responsible, then.
958 logables.Add( "Object {} added as prefix logable for ", prefix );
959
960 dom->PrefixLogables.emplace_back( impl->newPO<PrefixLogable>( impl->poolAllocator, prefix ), otherPLs );
961 } else {
962 auto cntPLs= dom->PrefixLogables.size();
963 if ( cntPLs > 0 ) {
964 removedLogable= dom->PrefixLogables.back().first;
965 dom->PrefixLogables.pop_back();
966 logables.Add( "Object {} removed from list of prefix logables for",
967 *static_cast<Box*>(removedLogable) );
968 } else {
969 logables.Add( "No prefix logables to remove for" );
970 intLogVerbosity= Verbosity::Warning;
971 } }
972
973 logables.Add(" domain {!Q'}.", dom->FullPath);
974 logInternal( impl, intLogVerbosity, "PFX", logables );
975
976 if( removedLogable )
977 impl->deletePO(removedLogable);
978}
979
980
981#if defined (__GLIBCXX__) || defined(_LIBCPP_VERSION) || defined(__APPLE__) || defined(__ANDROID_NDK__)
982void LI::SetStartTime(LoxImpl* impl, time_t startTime, const NString& loggerName )
983{
984 TickConverter converter;
985 SetStartTime( impl, converter.ToTicks( DateTime::FromEpochSeconds( startTime ) ), loggerName );
986}
987
988#elif defined( _WIN32 )
989 void LI::SetStartTime(LoxImpl* impl, const FILETIME& startTime, const NString& loggerName )
990 {
991 TickConverter converter;
992 SetStartTime( impl, converter.ToTicks( DateTime::FromFileTime( startTime ) ), loggerName );
993 }
994#else
995 #pragma message "Unknown Platform in file: " __FILE__ )
996#endif
997
998void LI::SetStartTime(LoxImpl* impl, Ticks startTime, const NString& loggerName ) {
999 ASSERT_ACQUIRED
1000
1001 bool foundOne= false;
1002 for( int loggerNo= 0; loggerNo < impl->domains->CountLoggers(); ++loggerNo ) {
1003 // request logger only from main domain tree
1004 Logger* logger= impl->domains->GetLogger( loggerNo );
1005 if( loggerName.IsNotEmpty() && !loggerName.Equals<NC, lang::Case::Ignore>( logger->GetName()) )
1006 continue;
1007 foundOne= true;
1008
1009 // log info on this
1010 BoxesMA& logables= acquireInternalLogables(impl);
1011 logables.Add( "Logger {!Q}: Start time set to ", logger->GetName() );
1012 if ( !startTime.IsSet() ) {
1013 startTime= Ticks::Now();
1014 logables.Add( "'now'" );
1015 } else {
1016 DateTime asDateTime;
1017 TextLogger* asTextLogger= dynamic_cast<TextLogger*>(logger);
1018 if( asTextLogger != nullptr )
1019 asDateTime= asTextLogger->DateConverter.ToDateTime( startTime );
1020 else
1021 asDateTime= TickConverter().ToDateTime( startTime );
1022 logables.Add( "{:yyyy-MM-dd HH:mm:ss}", asDateTime );
1023 }
1024 // do
1025 logger->TimeOfCreation.SetAs( startTime );
1026 logger->TimeOfLastLog .SetAs( startTime );
1027
1028 logInternal( impl, Verbosity::Info, "LGR", logables );
1029 }
1030
1031 if ( loggerName.IsNotEmpty() && !foundOne ) {
1032 BoxesMA& logables= acquireInternalLogables(impl);
1033 logables.Add( "Logger {!Q}: not found. Start time not set.", loggerName );
1034 logInternal( impl, Verbosity::Error, "LGR", logables );
1035 return;
1036} }
1037
1038
1039void LI::MapThreadName(LoxImpl* impl, const String& threadName, threads::ThreadID id ) {
1040 #if !ALIB_SINGLE_THREADED
1041
1042 ASSERT_ACQUIRED
1043
1044 // get current thread id
1045 String origThreadName;
1046 if ( id == 0 ) {
1048 id= t->GetID();
1049 origThreadName= t->GetName();
1050 }
1051 else
1052 origThreadName= nullptr;
1053
1054 // add entry
1055 impl->scopeInfo.threadDictionary.EmplaceOrAssign(id, threadName);
1056
1057 // log info on this
1058 BoxesMA& logables= acquireInternalLogables(impl);
1059 logables.Add( "Mapped thread ID {} to {!Q}.", id, threadName);
1060 if ( origThreadName.IsNotEmpty() )
1061 logables.Add(" Original thread name: {!Q}.", origThreadName );
1062 logInternal( impl, Verbosity::Info, "THR", logables );
1063 #else
1064 (void) impl;
1065 (void) threadName;
1066 (void) id;
1067 #endif
1068}
1069
1070void LI::once( LoxImpl* impl,
1071 const NString& domain, Verbosity verbosity,
1072 const Box& logable,
1073 const String& pGroup,
1074 Scope scope,
1075 int quantity ) {
1076 int pathLevel= checkScopeInformation( impl, scope, "DMN" );
1077 if( pathLevel < 0 )
1078 return;
1079
1080 // We need a group. If none is given, there are two options:
1081 NString512 group(pGroup);
1082 bool groupWasEmtpy= group.IsEmpty();
1083 if ( groupWasEmtpy ) {
1084 // GLOBAL scope: exact code line match
1085 if ( scope == Scope::Global ) {
1086 scope= Scope::Filename;
1087 group._('#')._( impl->scopeInfo.GetLineNumber() );
1088 }
1089
1090 // not GLOBAL scope: Unique group per Scope
1091 else
1092 group._( impl->noKeyHashKey );
1093 }
1094
1095 // get the store
1096 impl->scopeLogOnce.InitAccess( scope, pathLevel, UNDEFINED_THREAD );
1097
1098 SSMap<int>* map= impl->scopeLogOnce.Get();
1099 if( map == nullptr ) {
1100 map= impl->newPO<SSMap<int>>(impl->poolAllocator);
1101 impl->scopeLogOnce.Store( map );
1102 }
1103
1104 // create map entry (if not created yet)
1105 auto it= map->Find( group );
1106 if (it == map->end() )
1107 it= map->InsertUnique( std::make_pair( NString(impl->poolAllocator, group), 0) );
1108
1109 // log Once
1110 if ( quantity >= 0 ) {
1111 if ( it->second < quantity ) {
1112 ++it->second;
1113
1114 // do the log
1115 GetLogableContainer(impl) .Add( std::forward<const Box&>( logable ) );
1116 Entry( impl, domain, verbosity );
1117
1118 // log info if this was the last time
1119 if( it->second == quantity ) {
1120 BoxesMA& logables= acquireInternalLogables(impl);
1121 logables.Add( "Once() reached limit of {} logs. No further logs for ", quantity );
1122
1123 if ( groupWasEmtpy )
1124 logables.Add( scope == Scope::Global ? Box( "this line" )
1125 : Box(scope + pathLevel) );
1126 else {
1127 logables.Add( "group {!Q}", group );
1128 if ( scope != Scope::Global )
1129 logables.Add(" in ", (scope + pathLevel) );
1130 }
1131 logables.Add('.');
1132
1133 logInternal( impl, Verbosity::Info, "", logables );
1134 } } }
1135
1136 // log Nth
1137 else {
1138 if ( it->second++ % -quantity == 0 ) {
1139 GetLogableContainer(impl) .Add( std::forward<const Box&>( logable ) );
1140 Entry( impl, domain, verbosity );
1141} } }
1142
1143void LI::store( LoxImpl* impl, const Box& data, const NString& pKey, Scope scope ) {
1144 // We need a key. If none is given, we use a constant one indicating that storage is
1145 // associated exclusively with scope
1146 NString256 key(pKey);
1147 bool keyWasEmtpy= key.IsEmpty();
1148 if ( keyWasEmtpy )
1149 key= impl->noKeyHashKey;
1150
1151 // get path level
1152 int pathLevel= 0;
1153 if ( scope > Scope::Path ) {
1154 pathLevel= int( scope - Scope::Path );
1155 scope= Scope::Path;
1156 }
1157
1158 // get the store
1159 impl->scopeLogData.InitAccess( scope, pathLevel, UNDEFINED_THREAD );
1160 SSMap<Box>* map= impl->scopeLogData.Get();
1161 if( map == nullptr ) {
1162 map= impl->newPO<SSMap<Box>>(impl->poolAllocator);
1163 impl->scopeLogData.Store( map );
1164 }
1165
1166 BoxesMA& logables= acquireInternalLogables(impl);
1167
1168 // create map entry (if not created yet)
1169 auto it= map->Find( key );
1170 if ( !data.IsType<void>() ) {
1171 bool replacedPrevious= false;
1172 if ( it == map->end() )
1173 map->InsertUnique( std::make_pair( NString(impl->poolAllocator, key), data ) );
1174 else {
1175 replacedPrevious= true;
1176 it->second= data;
1177 }
1178
1179 // log info if this was the last time
1180 logables.Add( "Stored data " );
1181
1182 if ( !keyWasEmtpy )
1183 logables.Add( " with key {!Q} ", key );
1184 logables.Add( "in {}.", (scope + pathLevel) );
1185 if ( replacedPrevious )
1186 logables.Add( " (Replaced and deleted previous.)" );
1187 }
1188
1189 // delete
1190 else {
1191 if ( it != map->end() ) {
1192 auto keyString= it->first;
1193 map->erase( it );
1194 if ( map->Size() == 0 ) {
1195 impl->deletePO(map);
1196 impl->scopeLogData.Remove( nullptr );
1197 }
1198 keyString.Free(impl->poolAllocator);
1199 logables.Add( "Deleted map data " );
1200 }
1201 else
1202 logables.Add( "No map data found to delete " );
1203
1204 if ( !keyWasEmtpy )
1205 logables.Add( " with key {!Q} ", key );
1206 logables.Add( "in {}.", (scope + pathLevel) );
1207 }
1208
1209 LI::logInternal( impl, Verbosity::Info, "LGD", logables );
1210}
1211
1212
1213Box LI::retrieve( LoxImpl* impl, const NString& pKey, Scope scope ) {
1214 // We need a key. If none is given, we use a constant one indicating that storage is
1215 // associated exclusively with scope
1216 NString256 key= pKey;
1217 bool keyWasEmtpy= key.IsEmpty();
1218 if ( keyWasEmtpy )
1219 key= impl->noKeyHashKey;
1220
1221 int pathLevel= 0;
1222 if ( scope > Scope::Path ) {
1223 pathLevel= int( scope - Scope::Path );
1224 scope= Scope::Path;
1225 }
1226
1227 // get the data (create if not found)
1228 impl->scopeLogData.InitAccess( scope, pathLevel, UNDEFINED_THREAD );
1229 Box returnValue;
1230 SSMap<Box>* map= impl->scopeLogData.Get();
1231 if( map != nullptr ) {
1232 auto it= map->Find( key );
1233 if ( it != map->end() )
1234 returnValue= it->second;
1235 }
1236
1237 if ( returnValue.IsType<void>() )
1238 store( impl, Box(), pKey, scope + pathLevel );
1239
1240 // log info if this was the last time
1241 BoxesMA& logables= acquireInternalLogables(impl);
1242 logables.Add( "Data " );
1243
1244 if ( !keyWasEmtpy )
1245 logables.Add( " with key {!Q} ", key );
1246 logables.Add( "in ", (scope + pathLevel), ( !returnValue.IsType<void>() ? " received."
1247 : " not found." ) );
1248
1249 logInternal( impl, Verbosity::Info, "LGD", logables );
1250 return returnValue;
1251}
1252
1253
1254void LI::State( LoxImpl* impl,
1255 const NString& domain,
1256 Verbosity verbosity,
1257 const String& headLine,
1258 StateInfo flags ) {
1259 ASSERT_ACQUIRED
1260
1261 NAString buf;
1262 buf.SetBuffer( 2048 );
1263 if ( headLine.IsNotEmpty() )
1264 buf._<NC>( headLine ).NewLine();
1265
1266 GetState( impl, buf, flags );
1267
1268 GetLogableContainer(impl) .Add( buf );
1269 Entry( impl, domain, verbosity );
1270}
1271
1273 auto cntAcquirements= impl->CountAcquirements();
1274 ALIB_ASSERT_ERROR( cntAcquirements >= 1, "ALOX", "Lox not acquired." )
1275 ALIB_ASSERT_WARNING( cntAcquirements < 5, "ALOX", "Logging recursion depth >= 5" )
1276 while( int(impl->logableContainers.size()) < cntAcquirements )
1277 impl->logableContainers.emplace_back( impl->monoAllocator().New<BoxesMA>(impl->monoAllocator) );
1278 BoxesMA& logables= *impl->logableContainers[size_t(cntAcquirements - 1)];
1279 logables.clear();
1280 return logables;
1281}
1282
1283void LI::Entry(LoxImpl* impl, const NString& domain, Verbosity verbosity ) {
1284 ASSERT_ACQUIRED
1285
1286 // auto-initialization of debug loggers
1287 #if ALOX_DBG_LOG
1288 if( impl == Log::Get()->impl
1289 && impl->domains->CountLoggers() == 0
1290 && Log::DEBUG_LOGGER == nullptr )
1291 Log::AddDebugLogger( Log::Get() );
1292 #endif
1293
1294 ALIB_ASSERT_ERROR(ALOX.IsBootstrapped(), "ALOX", "ALox (ALib) was not properly bootstrapped." )
1295
1296 ++impl->CntLogCalls;
1297
1298 if ( impl->domains->CountLoggers() == 0 )
1299 return;
1300
1301 log( impl,
1302 evaluateResultDomain( impl, domain ),
1303 verbosity,
1304 *impl->logableContainers[size_t(impl->CountAcquirements() - 1)],
1305 lang::Inclusion::Include );
1306}
1307
1308int LI::IsActive(LoxImpl* impl, Verbosity verbosity, const NString& domain, NAString* resultDomain){
1309 ASSERT_ACQUIRED
1310
1311 // auto-initialization of debug loggers
1312 #if ALOX_DBG_LOG
1313 if( impl == Log::Get()->impl
1314 && impl->domains->CountLoggers() == 0
1315 && Log::DEBUG_LOGGER == nullptr )
1316 Log::AddDebugLogger( Log::Get() );
1317 #endif
1318
1319 ALIB_ASSERT_ERROR(ALOX.IsBootstrapped(), "ALOX", "ALox (ALib) was not properly bootstrapped." )
1320
1321 Domain* dom= evaluateResultDomain( impl, domain );
1322 if ( resultDomain != nullptr )
1323 resultDomain->_( dom->FullPath );
1324
1325 if ( impl->domains->CountLoggers() == 0 )
1326 return 0;
1327
1328 int result= 0;
1329 for ( int i= 0; i < dom->CountLoggers() ; ++i )
1330 if( dom->IsActive( i, verbosity ) )
1331 ++result;
1332 return result;
1333}
1334
1335Verbosity LI::GetVerbosity(LoxImpl* impl, const NString& domain, NAString* resultDomain){
1336 ASSERT_ACQUIRED
1337
1338 // auto-initialization of debug loggers
1339 #if ALOX_DBG_LOG
1340 if( impl == Log::Get()->impl
1341 && impl->domains->CountLoggers() == 0
1342 && Log::DEBUG_LOGGER == nullptr )
1343 Log::AddDebugLogger( Log::Get() );
1344 #endif
1345
1346 ALIB_ASSERT_ERROR(ALOX.IsBootstrapped(), "ALOX", "ALox (ALib) was not properly bootstrapped." )
1347
1348 Domain* dom= evaluateResultDomain( impl, domain );
1349 if ( resultDomain != nullptr )
1350 resultDomain->_( dom->FullPath );
1351
1352 if ( impl->domains->CountLoggers() == 0 )
1353 return Verbosity::Off;
1354
1355 std::array verbosities={ Verbosity::Verbose, Verbosity::Info,
1356 Verbosity::Warning, Verbosity::Error, Verbosity::Off };
1357
1358 for ( auto verbosity : verbosities ) {
1359 for ( int i= 0; i < dom->CountLoggers() ; ++i )
1360 if( dom->IsActive( i, verbosity ) )
1361 return verbosity;
1362 }
1363 return Verbosity::Off;
1364}
1365
1366void LI::IncreaseLogCounter( LoxImpl* impl) { ++impl->CntLogCalls; }
1367
1368void LI::entryDetectDomainImpl(LoxImpl* impl, Verbosity verbosity ) {
1369 BoxesMA& logables= *impl->logableContainers[size_t(impl->CountAcquirements() - 1)];
1370 if ( logables.Size() > 1 && logables[0].IsArrayOf<nchar>() ) {
1371 NString firstArg= logables[0].Unbox<NString>();
1372
1373 // accept internal domain at the start
1374 integer idx= 0;
1375 if( firstArg.StartsWith( Lox::InternalDomains ) )
1376 idx+= Lox::InternalDomains.Length();
1377
1378 // loop over domain and check for illegal characters
1379 bool illegalCharacterFound= false;
1380 for( ; idx< firstArg.Length() ; ++idx ) {
1381 char c= firstArg[idx];
1382 if (! ( isdigit( c )
1383 || ( c >= 'A' && c <= 'Z' )
1384 || c == '-'
1385 || c == '_'
1386 || c == '/'
1387 || c == '.'
1388 ) )
1389 {
1390 illegalCharacterFound= true;
1391 break;
1392 } }
1393
1394 if ( illegalCharacterFound ) {
1395 Entry( impl, nullptr, verbosity );
1396 return;
1397 }
1398
1399 logables.erase( logables.begin() );
1400 Entry( impl, firstArg, verbosity );
1401 return;
1402 }
1403
1404 Entry( impl, nullptr, verbosity );
1405}
1406
1407
1408//##################################################################################################
1409// internals
1410//##################################################################################################
1411Domain* LI::evaluateResultDomain(LoxImpl* impl, const NString& domainPath ) {
1412 NString128 resDomain;
1413
1414 // 0. internal domain tree?
1415 if ( domainPath.StartsWith( Lox::InternalDomains ) ) {
1416 // cut "$/" from the path
1417 resDomain._( domainPath, Lox::InternalDomains.Length() );
1418 return findDomain( impl, *impl->internalDomains, resDomain );
1419 }
1420
1421 // loop over scopes
1422 NString64 localPath; localPath.DbgDisableBufferReplacementWarning();
1423 impl->scopeDomains.InitWalk( Scope::ThreadInner,
1424 // we have to provide NULL_STRING if parameter is empty
1425 domainPath.IsNotEmpty() ? localPath._(domainPath)
1426 : NULL_NSTRING
1427 );
1428 NString nextDefault;
1429 while( (nextDefault= impl->scopeDomains.Walk() ).IsNotNull() ) {
1430 ALIB_ASSERT( nextDefault.IsNotEmpty(), "ALOX" )
1431
1432 if ( resDomain.IsNotEmpty() )
1433 resDomain.InsertAt( "/", 0);
1434 resDomain.InsertAt( nextDefault, 0 );
1435
1436 // absolute path? That's it
1437 if ( resDomain.CharAtStart() == Domain::Separator() )
1438 break;
1439 }
1440 return findDomain( impl, *impl->domains, resDomain );
1441}
1442
1443void LI::getVerbosityFromConfig(LoxImpl* impl, Variable& v, Logger* logger, Domain& dom ) {
1444 // get logger number. It may happen that the logger is not existent in this domain tree.
1445 int loggerNo= dom.GetLoggerNo( logger ) ;
1446 if ( loggerNo < 0 )
1447 return;
1448
1449 auto& cvVerb = v.Get<alib::lox::CVVerbosities>();
1450
1451 for (auto it : cvVerb) {
1452 Tokenizer verbosityTknzr( it, '=' );
1453
1454 NString256 domainStrBuf;
1455 Substring domainStrParser= verbosityTknzr.Next();
1456 if ( domainStrParser.ConsumeString<lang::Case::Ignore>( A_CHAR("INTERNAL_DOMAINS")) ) {
1457 while ( domainStrParser.ConsumeChar('/') )
1458 ;
1459 domainStrBuf << Lox::InternalDomains << domainStrParser;
1460 }
1461 else
1462 domainStrBuf._( domainStrParser );
1463
1464 NSubstring domainStr= domainStrBuf ;
1465
1466 Substring verbosityStr= verbosityTknzr.Next();
1467 if ( verbosityStr.IsEmpty() )
1468 continue;
1469
1470 int searchMode= 0;
1471 if ( domainStr.ConsumeChar ( '*' ) ) searchMode+= 2;
1472 if ( domainStr.ConsumeCharFromEnd( '*' ) ) searchMode+= 1;
1473 if( ( searchMode == 0 && dom.FullPath.Equals <NC ,lang::Case::Ignore>( domainStr ) )
1474 || ( searchMode == 1 && dom.FullPath.StartsWith<CHK,lang::Case::Ignore>( domainStr ) )
1475 || ( searchMode == 2 && dom.FullPath.EndsWith <CHK,lang::Case::Ignore>( domainStr ) )
1476 || ( searchMode == 3 && dom.FullPath.IndexOf <CHK,lang::Case::Ignore>( domainStr ) >=0 )
1477 )
1478 {
1479 Verbosity verbosity(Verbosity::Info);
1480 enumrecords::Parse<Verbosity>(verbosityStr, verbosity );
1481 dom.SetVerbosity( loggerNo, verbosity, v.GetPriority() );
1482
1483 // log info on this
1484 NString512 msg;
1485 msg._<NC>( "Logger \"" )._<NC>( logger->GetName() ) ._<NC>( "\":" )._(NTab(11 + impl->maxLoggerNameLength))
1486 ._<NC>( '\'' )._<NC>( dom.FullPath )
1487 ._( '\'' ).InsertChars(' ', impl->maxDomainPathLength - dom.FullPath.Length() + 1 )
1488 ._( "= Verbosity::" )
1489 ._( boxing::MakePair(verbosity, dom.GetPriority( loggerNo )) ).TrimEnd()
1490 ._<NC>( '.' );
1491
1492 logInternal( impl, Verbosity::Info, "LGR", msg );
1493} } }
1494
1497 {ALIB_LOCK_WITH(ALOX.GetConfig())
1499 decl= ALOX.GetConfig()->StoreDeclaration( decl,
1501 GetName( impl )
1502 #else
1503 String128( GetName( impl ) )
1504 #endif
1505 );
1506 if( !variable.Try(decl) )
1507 return;
1508 }
1509
1510 Tokenizer prefixTokOuter;
1511 prefixTokOuter.Set(variable, ';', true);
1512 while(prefixTokOuter.HasNext()) {
1513 Tokenizer prefixTok( prefixTokOuter.Next(), '=' );
1514
1515 NString128 domainStrBuf;
1516 Substring domainStrParser= prefixTok.Next();
1517 if ( domainStrParser.ConsumeString<lang::Case::Ignore>( A_CHAR("INTERNAL_DOMAINS")) ) {
1518 while ( domainStrParser.ConsumeChar('/') )
1519 ;
1520 domainStrBuf << Lox::InternalDomains << domainStrParser;
1521 }
1522 else
1523 domainStrBuf._( domainStrParser );
1524
1525 NSubstring domainStr= domainStrBuf ;
1526
1527 Tokenizer prefixTokInner( prefixTok.Next(), ',' );
1528 Substring prefixStr= prefixTokInner.Next();
1529 if ( prefixStr.IsEmpty() )
1530 continue;
1531 if ( prefixStr.ConsumeChar( '\"' ) )
1532 prefixStr.ConsumeCharFromEnd( '\"' );
1533
1535 prefixTokInner.Next();
1536 if ( prefixTokInner.Actual.IsNotEmpty() )
1538
1539 int searchMode= 0;
1540 if ( domainStr.ConsumeChar ( '*' ) ) searchMode+= 2;
1541 if ( domainStr.ConsumeCharFromEnd( '*' ) ) searchMode+= 1;
1542 if( ( searchMode == 0 && dom.FullPath.Equals <NC ,lang::Case::Ignore>( domainStr ) )
1543 || ( searchMode == 1 && dom.FullPath.StartsWith<CHK,lang::Case::Ignore>( domainStr ) )
1544 || ( searchMode == 2 && dom.FullPath.EndsWith <CHK,lang::Case::Ignore>( domainStr ) )
1545 || ( searchMode == 3 && dom.FullPath.IndexOf <CHK,lang::Case::Ignore>( domainStr ) >=0 )
1546 )
1547 {
1548 dom.PrefixLogables.emplace_back( impl->newPO<PrefixLogable>( impl->poolAllocator, prefixStr ), otherPLs );
1549
1550 // log info on this
1551 NString128 msg; msg._<NC>( "String \"" )._<NC>( prefixStr )._<NC>( "\" added as prefix logable for domain \'" )
1552 ._<NC>( dom.FullPath )
1553 ._<NC>( "\'. (Retrieved from configuration variable \'" )._<NC>(variable)._( "\'.)" );
1554
1555 logInternal( impl, Verbosity::Info, "PFX", msg );
1556} } }
1557
1558void LI::getAllVerbosities(LoxImpl* impl, Variable& varVerbosities, Logger* logger, Domain& dom) {
1559 // get verbosity for us
1560 getVerbosityFromConfig( impl, varVerbosities, logger, dom );
1561
1562 // loop over all subdomains (recursion)
1563 for ( Domain& subDomain : dom.SubDomains )
1564 getAllVerbosities( impl, varVerbosities, logger, subDomain );
1565}
1566
1567
1568Domain* LI::findDomain(LoxImpl* impl, Domain& rootDomain, NString domainPath ) {
1569 int maxSubstitutions= 10;
1570 NString128 substPath;
1571 for(;;) {
1572 // loop for creating domains, one by one
1573 Domain* dom= nullptr;
1574 for(;;) {
1575 bool wasCreated;
1576 dom= rootDomain.Find( domainPath, 1, &wasCreated );
1577 if ( wasCreated ) {
1578 // get maximum domain path length (for nicer State output only...)
1579 if ( impl->maxDomainPathLength < dom->FullPath.Length() )
1580 impl->maxDomainPathLength= dom->FullPath.Length();
1581
1582 // log info on new domain
1583 BoxesMA& logables= acquireInternalLogables(impl);
1584 logables.Add( "{!Q} registered.", dom->FullPath );
1585 logInternal( impl, Verbosity::Info, "DMN", logables );
1586 }
1587
1588 // read domain from config
1589 if ( !dom->ConfigurationAlreadyRead )
1590 { dom->ConfigurationAlreadyRead= true;
1591
1592 Box replacements[2];
1593 for ( int i= 0; i < dom->CountLoggers(); ++i ) {
1594 Logger* logger= dom->GetLogger(i);
1595 replacements[0]= GetName( impl );
1596 replacements[1]= logger->GetName();
1597 Variable varVerbosities= variables::CampVariable(ALOX, Variables::VERBOSITY, replacements );
1598 if ( varVerbosities.IsDefined() )
1599 getVerbosityFromConfig( impl, varVerbosities, logger, *dom );
1600 }
1601
1602 getDomainPrefixFromConfig( impl, *dom );
1603 }
1604
1605 if ( wasCreated ) {
1606 if ( dom->CountLoggers() == 0 )
1607 logInternal( impl, Verbosity::Verbose, "DMN", " No loggers set, yet." );
1608 else
1609 for ( int i= 0; i < dom->CountLoggers(); ++i ) {
1610 NString256 msg; msg._(" \"")._( dom->GetLogger(i)->GetName() )._("\": ");
1611 msg.InsertChars( ' ', impl->maxLoggerNameLength + 6 - msg.Length() );
1612 msg._( dom->FullPath )._(" = " )
1613 ._(boxing::MakePair(dom->GetVerbosity(i), dom->GetPriority(i)));
1614 logInternal( impl, Verbosity::Verbose, "DMN", msg );
1615 } }
1616 else
1617 break;
1618 }
1619
1620 // apply domain substitutions
1621 if( !impl->domainSubstitutions.empty() ) {
1622 substPath.Reset();
1623 NSubstring domFullPath= dom->FullPath;
1624 if ( domFullPath.CharAtStart<NC>() == '$' )
1625 domFullPath.ConsumeChar();
1626
1627 while( maxSubstitutions-- > 0 ) {
1628 // loop over rules
1629 bool substituted= false;
1630 for( auto& rule : impl->domainSubstitutions ) {
1631 switch( rule.type ) {
1633 if( substPath.IsEmpty() ) {
1634 if ( domFullPath.StartsWith( rule.Search ) ) {
1635 substPath._( rule.Replacement )._( domFullPath, rule.Search.Length() );
1636 substituted= true;
1637 continue;
1638 }
1639 } else {
1640 if ( substPath.StartsWith( rule.Search ) ) {
1641 substPath.ReplaceSubstring<NC>( rule.Replacement, 0, rule.Search.Length() );
1642 substituted= true;
1643 continue;
1644 } }
1645 break;
1646
1648 if( substPath.IsEmpty() ) {
1649 if ( domFullPath.EndsWith( rule.Search ) ) {
1650 substPath._( domFullPath, 0, domFullPath.Length() - rule.Search.Length() )._( rule.Replacement );
1651 substituted= true;
1652 continue;
1653 }
1654 } else {
1655 if ( substPath.EndsWith( rule.Search ) ) {
1656 substPath.DeleteEnd( rule.Search.Length() )._( rule.Replacement );
1657 substituted= true;
1658 continue;
1659 } }
1660 break;
1661
1662
1664 {
1665 if( substPath.IsEmpty() ) {
1666 integer idx= domFullPath.IndexOf( rule.Search );
1667 if ( idx >= 0 ) {
1668 substPath._( domFullPath, 0, idx )._( rule.Replacement)._( domFullPath, idx + rule.Search.Length() );
1669 substituted= true;
1670 continue; //next rule
1671 }
1672 } else {
1673 integer idx= substPath.IndexOf( rule.Search, 0 );
1674 if ( idx >= 0 ) {
1675 substPath.ReplaceSubstring<NC>( rule.Replacement, idx, rule.Search.Length() );
1676 substituted= true;
1677 continue; //next rule
1678 } } }
1679 break;
1680
1681
1683 {
1684 if( substPath.IsEmpty() ) {
1685 if ( domFullPath.Equals<NC>( rule.Search ) ) {
1686 substPath._( rule.Replacement);
1687 substituted= true;
1688 continue; //next rule
1689 }
1690 if ( domFullPath.CharAtStart<NC>() == '$' ) {
1691 substPath._( rule.Replacement);
1692 substituted= true;
1693 continue; //next rule
1694 }
1695 } else {
1696 if ( substPath.Equals<NC>( rule.Search) ) {
1697 substPath.Reset( rule.Replacement );
1698 substituted= true;
1699 continue; //next rule
1700 } } }
1701 break;
1702
1703 default: ALIB_ERROR("ALOX", "Illegal switch state." ) break;
1704 } // switch rule type
1705
1706 }//rules loop
1707
1708 // stop if non was found
1709 if( !substituted )
1710 break;
1711 }
1712
1713 // too many substitutions?
1714 if ( maxSubstitutions <= 0 && !impl->oneTimeWarningCircularDS ) {
1715 impl->oneTimeWarningCircularDS= true;
1716 logInternal( impl, Verbosity::Error, "DMN",
1717 "The Limit of 10 domain substitutions was reached. Circular substitution assumed!"
1718 " (This error is only reported once!)" );
1719 }
1720
1721 // anything substituted?
1722 if( substPath.Length() > 0 ) {
1723 domainPath= substPath;
1724 continue;
1725 } }
1726
1727 return dom;
1728} }
1729
1730int LI::checkScopeInformation(LoxImpl* impl, Scope& scope, const NString& internalDomain ) {
1731 int pathLevel= 0;
1732 if ( scope > Scope::Path ) {
1733 pathLevel= int( scope - Scope::Path );
1734 scope= Scope::Path;
1735 }
1736
1737 if ( ( scope == Scope::Path && impl->scopeInfo.GetFullPath().IsEmpty() )
1738 || ( scope == Scope::Filename && impl->scopeInfo.GetFileName().IsEmpty() )
1739 || ( scope == Scope::Method && impl->scopeInfo.GetMethod() .IsEmpty() ) )
1740 {
1741 BoxesMA& logables= acquireInternalLogables(impl);
1742 logables.Add( "Missing scope information. Cant use {}.", (scope + pathLevel) );
1743 logInternal( impl, Verbosity::Error, internalDomain, logables );
1744 return -1;
1745 }
1746 return pathLevel;
1747}
1748
1750 // check
1751 if ( scope == Scope::ThreadOuter
1752 || scope == Scope::ThreadInner )
1753 return true;
1754
1755 BoxesMA& logables= acquireInternalLogables(impl);
1756 logables.Add( "Illegal parameter, only Scope::ThreadOuter and Scope::ThreadInner allowed."
1757 " Given: {}.", scope );
1758 logInternal( impl, Verbosity::Error, "DMN", logables );
1759
1760 #if ALIB_DEBUG
1762 impl->scopeInfo.GetLineNumber(),
1763 impl->scopeInfo.GetMethod(),
1764 #if !ALIB_SINGLE_THREADED
1766 #elif ALIB_EXT_LIB_THREADS_AVAILABLE
1767 std::thread::id(),
1768 #endif
1769 impl->scopeInfo.GetTypeInfo()
1770 },
1771 0, "Illegal scope type \"{}\" given. Only Scope::ThreadOuter and "
1772 "Scope::ThreadInner allowed.", scope );
1773 #endif
1774
1775 return false;
1776}
1777
1778void LI::log( LoxImpl* impl , Domain* dom,
1779 Verbosity verbosity, BoxesMA& logables, lang::Inclusion includePrefixes ) {
1780 ++dom->CntLogCalls;
1781 bool logablesCollected= false;
1782 PrefixLogable marker(impl->poolAllocator, nullptr);
1783 for ( int i= 0; i < dom->CountLoggers() ; ++i )
1784 if( dom->IsActive( i, verbosity ) ) {
1785 // lazily collect objects once an active logger is found
1786 if ( !logablesCollected ) {
1787 logablesCollected= true;
1788 impl->scopePrefixes.InitWalk( Scope::ThreadInner, &marker );
1789 const Box* next;
1790 int userLogablesSize= int( logables.Size() );
1791 int threadInnersSize= -1;
1792
1793 while( (next= impl->scopePrefixes.Walk() ) != nullptr ) {
1794 if( next != &marker ) {
1795 // this is false for internal domains (only domain specific logables are added there)
1796 if ( includePrefixes == lang::Inclusion::Include ) {
1797 // after marker is read, logables need to be prepended. This is checked below
1798 // using "qtyThreadInners < 0"
1799 if ( next->IsType<BoxesMA*>() ) {
1800 auto* boxes= next->Unbox<BoxesMA*>();
1801 for (auto pfxI= boxes->Size() - 1 ; pfxI >= 0 ; --pfxI )
1802 logables.emplace( logables.begin() + ( threadInnersSize < 0 ? userLogablesSize : 0 ),
1803 (*boxes)[size_t(pfxI)] );
1804 }
1805 else if ( next->IsType<Boxes*>() ) {
1806 auto* boxes= next->Unbox<Boxes*>();
1807 for (auto pfxI= boxes->Size() - 1 ; pfxI >= 0 ; --pfxI )
1808 logables.emplace( logables.begin() + ( threadInnersSize < 0 ? userLogablesSize : 0 ),
1809 (*boxes)[size_t(pfxI)] );
1810 }
1811 else if ( next->IsType<BoxesPA*>() ) {
1812 auto* boxes= next->Unbox<BoxesPA*>();
1813 for (auto pfxI= boxes->Size() - 1 ; pfxI >= 0 ; --pfxI )
1814 logables.emplace( logables.begin() + ( threadInnersSize < 0 ? userLogablesSize : 0 ),
1815 (*boxes)[size_t(pfxI)] );
1816 }
1817 else
1818 logables.emplace( logables.begin() + ( threadInnersSize < 0 ? userLogablesSize : 0 ), *next );
1819 } }
1820
1821 // was this the actual? then insert domain-associated logables now
1822 else {
1823 bool excludeOthers= false;
1824 threadInnersSize= int( logables.Size() ) - userLogablesSize;
1825 Domain* pflDom= dom;
1826 while ( pflDom != nullptr ) {
1827 for( auto it= pflDom->PrefixLogables.rbegin() ; it != pflDom->PrefixLogables.rend() ; ++it ) {
1828 // a list of logables? Copy them
1829 PrefixLogable& prefix= *it->first;
1830 if ( prefix.IsType<Boxes*>() ) {
1831 auto* boxes= prefix.Unbox<Boxes*>();
1832 for (auto pfxI= boxes->Size() - 1 ; pfxI >= 0 ; --pfxI )
1833 logables.emplace( logables.begin(),
1834 (*boxes)[size_t(pfxI)] );
1835 }
1836 else if ( prefix.IsType<BoxesMA*>() ) {
1837 auto* boxes= prefix.Unbox<BoxesMA*>();
1838 for (auto pfxI= boxes->Size() - 1 ; pfxI >= 0 ; --pfxI )
1839 logables.emplace( logables.begin(),
1840 (*boxes)[size_t(pfxI)] );
1841 }
1842 else if ( prefix.IsType<BoxesPA*>() ) {
1843 auto* boxes= prefix.Unbox<BoxesPA*>();
1844 for (auto pfxI= boxes->Size() - 1 ; pfxI >= 0 ; --pfxI )
1845 logables.emplace( logables.begin(),
1846 (*boxes)[size_t(pfxI)] );
1847 }
1848 else
1849 logables.emplace( logables.begin(), prefix );
1850
1851
1852 if ( it->second == lang::Inclusion::Exclude ) {
1853 excludeOthers= true;
1854 break;
1855 } }
1856
1857 pflDom= excludeOthers ? nullptr : pflDom->Parent;
1858 }
1859
1860 // found a stoppable one? remove those from thread inner and break
1861 if (excludeOthers) {
1862 for ( int ii= 0; ii < threadInnersSize ; ++ii )
1863 logables.pop_back();
1864 break;
1865 } } }
1866 } // end of collection
1867
1868 Logger* logger= dom->GetLogger(i);
1869 { ALIB_LOCK_RECURSIVE_WITH(*logger)
1870 ++logger->CntLogs;
1871 logger->Log( *dom, verbosity, logables, impl->scopeInfo );
1872 logger->TimeOfLastLog= Ticks::Now();
1873} } }
1874
1876 if( integer(impl->internalLogables.size()) == impl->internalLogRecursionCounter ) {
1877 BoxesMA* newLogables= impl->monoAllocator().New<BoxesMA>(impl->monoAllocator);
1878 impl->internalLogables.emplace_back( newLogables );
1879 }
1880
1881 return *impl->internalLogables[size_t(impl->internalLogRecursionCounter++)];
1882}
1883
1884void LI::logInternal(LoxImpl* impl, Verbosity verbosity, const NString& subDomain, BoxesMA& msg ) {
1885 ALIB_ASSERT_ERROR(ALOX.IsBootstrapped(), "ALOX", "ALox (ALib) was not properly bootstrapped." )
1886 log( impl, findDomain( impl, *impl->internalDomains, subDomain ), verbosity, msg, lang::Inclusion::Exclude );
1887
1888 impl->internalLogables[size_t(--impl->internalLogRecursionCounter)]->clear();
1889}
1890
1891void LI::logInternal( LoxImpl* impl , Verbosity verbosity,
1892 const NString& subDomain, const NString& msg ) {
1893 BoxesMA& logables= acquireInternalLogables(impl);
1894 logables.Add( msg );
1895 logInternal( impl, verbosity, subDomain, logables );
1896}
1897
1898#if !DOXYGEN
1899
1900namespace {
1901void getStateDomainRecursive( Domain& domain, integer maxDomainPathLength, NAString& buf );
1902void getStateDomainRecursive( Domain& domain, integer maxDomainPathLength, NAString& buf ) {
1903 integer reference= buf.Length();
1904 buf._(" "); domain.ToString( buf );
1905 integer idx= buf.IndexOf( '[', reference );
1906 buf.InsertChars( ' ', maxDomainPathLength + 5 - idx + reference, idx);
1907 buf.NewLine();
1908
1909 // loop over all subdomains (recursion)
1910 for ( Domain& subDomain : domain.SubDomains )
1911 getStateDomainRecursive( subDomain, maxDomainPathLength, buf );
1912}
1913
1914void getStateDomainsWithDiffVerb( Domain& dom, int loggerNo, std::vector<Domain*>& results );
1915void getStateDomainsWithDiffVerb( Domain& dom, int loggerNo, std::vector<Domain*>& results ) {
1916 if ( dom.Parent == nullptr
1917 || dom.Parent->GetVerbosity(loggerNo) != dom.GetVerbosity(loggerNo) )
1918 results.emplace_back( &dom );
1919
1920 for( auto& it : dom.SubDomains )
1921 getStateDomainsWithDiffVerb( it, loggerNo, results );
1922}
1923
1924void getStateCollectPrefixes( Domain& dom, integer indentSpaces, NAString& target );
1925void getStateCollectPrefixes( Domain& dom, integer indentSpaces, NAString& target ) {
1926 AString buffer;
1927 for ( auto& pfl : dom.PrefixLogables ) {
1928 buffer.InsertChars( ' ', indentSpaces );
1929 buffer << '"';
1930 integer actLen= buffer.Length();
1931 buffer._( *static_cast<Box*>(pfl.first) );
1932 ESC::ReplaceToReadable( buffer, actLen );
1933 buffer << Escape( lang::Switch::On, actLen );
1934 buffer << '"';
1935 if ( pfl.second == lang::Inclusion::Exclude )
1936 buffer._<NC>( " (Excl.)" );
1937 buffer._<NC>( Tab( 25, -1 ) );
1938 buffer._<NC>( "<domain> [" )._<NC>( dom.FullPath )._<NC>(']').NewLine();
1939 }
1940 target << buffer;
1941
1942 for( auto& subDom : dom.SubDomains )
1943 getStateCollectPrefixes( subDom, indentSpaces, target );
1944}
1945
1946} // anonymous namespace
1947
1948#endif // !DOXYGEN
1949
1950
1951void LI::GetState( LoxImpl* impl, NAString& buf, StateInfo flags ) {
1952 ASSERT_ACQUIRED
1953
1955 impl->noKeyHashKey, buf );
1956
1957 if ( HasBits( flags, StateInfo::CompilationFlags ) ) {
1958 buf._<NC>( "ALib Version: " )._<NC>( alib::VERSION)
1959 ._<NC>(" (Rev. ") ._ ( alib::REVISION)._(')').NewLine();
1960 buf._<NC>( "ALib Configuration Macros:" ).NewLine();
1961 {
1962 for( auto& p : alib::COMPILATION_FLAG_MEANINGS ) {
1963 buf << " " << NField( p.Name, 41, lang::Alignment::Left ) << ':'
1964 << (alib::COMPILATION_FLAGS.bits[p.Flag/8] & (1 << p.Flag % 8) ? " On" : " Off")
1965 << NEW_LINE;
1966 }
1967
1968 }
1969
1970 buf.NewLine();
1971 }
1972
1973 // basic lox info
1974 if( alib::HasBits( flags, StateInfo::Basic ) )
1975 buf._<NC>( "Name: \"" )._( impl->scopeInfo.GetLoxName() )._('\"').NewLine();
1976
1977 if( HasBits( flags, StateInfo::Version ) ) {
1978 buf._<NC>( "Version: " )._<NC>( alib::VERSION)
1979 ._<NC>(" (Rev. " )._( alib::REVISION)._(')').NewLine();
1980 }
1981
1982 if( HasBits( flags, StateInfo::Basic ) )
1983 buf._<NC>( "#Log Calls: " )._<NC>( impl->CntLogCalls ).NewLine();
1984
1985 if( HasBits( flags, StateInfo::Basic )
1986 || HasBits( flags, StateInfo::Version ) )
1987 buf.NewLine();
1988
1989 // source path trim info
1990 if( HasBits( flags, StateInfo::SPTR ) ) {
1991 buf._<NC>( "Source Path Trimming Rules: " ).NewLine();
1992
1993 int cnt= 0;
1994 // do 2 times, 0== global list, 1 == local list
1995 for( int trimInfoNo= 0; trimInfoNo < 2 ; ++trimInfoNo ) {
1996 // choose local or global list
1997 std::vector<ScopeInfo::SourcePathTrimRule>* trimInfoList=
1998 trimInfoNo == 0 ? &ScopeInfo::GlobalSPTRs
1999 : &impl->scopeInfo.LocalSPTRs;
2000
2001
2002 // loop over trimInfo
2003 for ( auto& ti : *trimInfoList ) {
2004 ++cnt;
2005 buf._<NC>( trimInfoNo == 0 ? " Global: "
2006 : " Local: " );
2007 buf._<NC>( ti.IsPrefix ? "\"" : "\"*");
2008 buf._<NC>( ti.Path )._<NC>( "\", " );
2009 buf._<NC>( ti.IncludeString );
2010 if ( ti.TrimOffset != 0 )
2011 buf._<NC>( ti.Path )._<NC>( "\", Offset: " )._<NC>( ti.TrimOffset );
2012 buf._<NC>( ", Priority: " )._( ti.Priority );
2013 buf.NewLine();
2014 } }
2015
2016
2017 if ( cnt == 0 )
2018 buf._<NC>(" <no rules set>" ).NewLine();
2019 buf.NewLine();
2020 }
2021
2022 // domain substitutions
2023 if( HasBits( flags, StateInfo::DSR ) ) {
2024 buf._<NC>( "Domain Substitution Rules: " ).NewLine();
2025 if( !impl->domainSubstitutions.empty() ) {
2026 // get size
2027 integer maxWidth= 0;
2028 for ( auto& it : impl->domainSubstitutions )
2029 if ( maxWidth < it.Search.Length() )
2030 maxWidth = it.Search.Length();
2031 maxWidth+= 2;
2032
2033 // write
2034 for ( auto& it : impl->domainSubstitutions ) {
2035 buf._<NC>( " " );
2038 buf._<NC>( '*' );
2039
2040 buf._<NC>( it.Search );
2043 buf._<NC>( '*' );
2044
2045 buf._<NC>( NTab( maxWidth, -1, 0 ) )
2046 ._<NC>( " -> " )
2047 ._<NC>( it.Replacement );
2048 buf.NewLine();
2049 } }
2050 else
2051 buf._<NC>(" <no rules set>" ).NewLine();
2052 buf.NewLine();
2053 }
2054
2055 // Log Once Counters
2056 if( HasBits( flags, StateInfo::Once ) ) {
2057 buf._<NC>( "Once() Counters: " ).NewLine();
2058 if ( scopeDump.writeStoreMap( &impl->scopeLogOnce ) == 0 )
2059 buf._<NC>(" <no Once() counters set>" ).NewLine();
2060 buf.NewLine();
2061 }
2062
2063 // Log Data
2064 if( HasBits( flags, StateInfo::LogData ) ) {
2065 buf._<NC>( "Log Data: " ).NewLine();
2066 if ( scopeDump.writeStoreMap( &impl->scopeLogData ) == 0 )
2067 buf._<NC>(" <no data objects stored>" ).NewLine();
2068 buf.NewLine();
2069 }
2070
2071 // Prefix Logables
2072 if( HasBits( flags, StateInfo::PrefixLogables ) ) {
2073 buf._<NC>( "Prefix Logables: " ).NewLine();
2074 integer oldLength= buf.Length();
2075 scopeDump.writeStore( &impl->scopePrefixes, 2 );
2076 getStateCollectPrefixes( *impl->domains, 2, buf );
2077 if ( oldLength == buf.Length() )
2078 buf._<NC>(" <no prefix logables set>" ).NewLine();
2079 buf.NewLine();
2080 }
2081
2082 // thread mappings
2083 if( HasBits( flags, StateInfo::ThreadMappings ) ) {
2084 #if !ALIB_SINGLE_THREADED
2085 buf._<NC>( "Named Threads: " ).NewLine();
2086 if ( impl->scopeInfo.threadDictionary.Size() == 0 )
2087 buf._<NC>(" <no thread name mappings set>" ).NewLine();
2088 else
2089 for ( auto& pair : impl->scopeInfo.threadDictionary ) {
2090 buf._<NC>( " " ) << NField( String32() << '(' << pair.first << "):", 7, lang::Alignment::Left )
2091 << '\"' << pair.second << '\"';
2092 buf.NewLine();
2093 }
2094 buf.NewLine();
2095 #endif
2096 }
2097
2098 // Scope Domains
2099 if( HasBits( flags, StateInfo::ScopeDomains ) ) {
2100 buf._<NC>( "Scope Domains: " ).NewLine();
2101 if ( scopeDump.writeStore( &impl->scopeDomains, 2 ) == 0 )
2102 buf._<NC>(" <no scope domains set>" ).NewLine();
2103 buf.NewLine();
2104 }
2105
2106 // Loggers
2107 if( HasBits( flags, StateInfo::Loggers ) ) {
2108 TickConverter dateTimeConverter;
2109 std::vector<Domain*> domainsWithDiffVerb;
2110 for (int treeNo= 0; treeNo < 2; ++treeNo ) {
2111 int cnt= 0;
2112 Domain* domTree;
2113 if( treeNo==0 ) {
2114 domTree= impl->domains;
2115 buf._<NC>( "Loggers:" ).NewLine();
2116 } else {
2117 domTree= impl->internalDomains;
2118 buf._<NC>( "Loggers on Internal Domains:" ).NewLine();
2119 }
2120
2121 for ( int loggerNo= 0; loggerNo< domTree->CountLoggers(); ++loggerNo ) {
2122 ++cnt;
2123 String64 as64;
2125
2126 Logger* logger= domTree->GetLogger(loggerNo);
2127 buf._<NC>( " " )._<NC>( *logger ).NewLine();
2128 buf._<NC>( " Lines logged: " )._<NC>( logger->CntLogs ).NewLine();
2129
2130 ct.Set( dateTimeConverter.ToDateTime(logger->TimeOfCreation) );
2131 buf._<NC>( " Creation time: " )._<NC>( ct.Format( A_CHAR("yyyy-MM-dd HH:mm:ss"), as64.Reset()) ).NewLine();
2132
2133 ct.Set( dateTimeConverter.ToDateTime(logger->TimeOfLastLog) );
2134 buf._<NC>( " Last log time: " )._<NC>( ct.Format( A_CHAR("yyyy-MM-dd HH:mm:ss"), as64.Reset()) ).NewLine();
2135
2136 domainsWithDiffVerb.clear();
2137 getStateDomainsWithDiffVerb( *domTree, loggerNo, domainsWithDiffVerb);
2138 for ( Domain* dom : domainsWithDiffVerb ) {
2139 buf._<NC>(" ")
2140 ._( dom == *domainsWithDiffVerb.begin() ? "Verbosities: "
2141 : " " );
2142
2143 integer tabRef= buf.Length();
2144 buf << dom->FullPath << NTab( impl->maxDomainPathLength +1, tabRef);
2145
2146 buf << "= " << boxing::MakePair(dom->GetVerbosity( loggerNo ), dom->GetPriority(loggerNo) )
2147 << NEW_LINE;
2148 } }
2149 if ( cnt == 0 )
2150 buf._<NC>(" <no loggers attached>" ).NewLine();
2151 buf.NewLine();
2152 } }
2153
2154 // Internal Domains
2155 if( HasBits( flags, StateInfo::InternalDomains ) ) {
2156 buf._<NC>( "Internal Domains:" ).NewLine();
2157 getStateDomainRecursive( *impl->internalDomains, impl->maxDomainPathLength, buf );
2158 buf.NewLine();
2159 }
2160
2161 // Domains
2162 if( HasBits( flags, StateInfo::Domains ) ) {
2163 buf._<NC>( "Domains:" ).NewLine();
2164 getStateDomainRecursive( *impl->domains , impl->maxDomainPathLength, buf );
2165 buf.NewLine();
2166} }
2167
2168} // namespace alib::lox[::detail]
2169
2170
2171
2172}} // namespace [alib::lox]
2173# include "ALib.Lang.CIMethods.H"
2174
2175#undef UNDEFINED_THREAD
2176#undef ASSERT_ACQUIRED
#define ALIB_LOCK_SHARED_WITH(lock)
#define IF_ALIB_THREADS(...)
#define A_CHAR(STR)
#define ALIB_CHARACTERS_WIDE
#define ALIB_WARNING(domain,...)
#define ALIB_ASSERT_WARNING(cond, domain,...)
#define ALIB_ERROR(domain,...)
#define ALIB_LOCK_RECURSIVE_WITH(lock)
#define ALIB_DBG(...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define ALIB_CALLER_PRUNED
#define ALIB_COMMA
#define ALIB_LOCK_WITH(lock)
#define ALIB_REL_DBG(releaseCode,...)
#define LOG_RELEASE
#define LOG_ACQUIRE
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) Call(TArgs &&... args) const
Definition box.hpp:964
bool IsType() const
bool IsArray() const
Definition box.hpp:547
integer UnboxLength() const
Definition box.hpp:821
bool IsNull() const
Definition box.hpp:1107
TBoxes & Add()
Definition boxes.hpp:54
integer Size() const
Definition boxes.hpp:125
std::pair< Iterator, bool > EmplaceOrAssign(const KeyType &key, TArgs &&... args)
Iterator Find(const KeyType &key)
integer erase(const KeyType &key)
Iterator InsertUnique(const StoredType &value)
integer Size() const noexcept
static void ReplaceToReadable(AString &target, integer startIdx)
Definition aloxinit.cpp:9
static void RemoveDebugLogger(Lox *lox)
Definition alox.cpp:209
static textlogger::TextLogger * DEBUG_LOGGER
The debug logger created by AddDebugLogger.
Definition log.hpp:39
static Lox * Get()
Definition log.hpp:46
static constexpr NString InternalDomains
Definition lox.hpp:45
Domain * Find(NSubstring domainPath, int maxCreate, bool *wasCreated)
Definition domain.cpp:54
void ToString(NAString &target)
Definition domain.cpp:189
bool ConfigurationAlreadyRead
Flag which is set when verbosity configuration data was read.
Definition domain.hpp:100
void RemoveLogger(int loggerNo)
Definition domain.hpp:154
Domain * Parent
The parent domain. For root domains, this is nullptr.
Definition domain.hpp:78
bool IsActive(int loggerNo, Verbosity verbosity)
Definition domain.hpp:244
Verbosity GetVerbosity(int loggerNo)
Definition domain.hpp:225
ListMA< Domain, Recycling::None > SubDomains
A list of subdomains, sorted by name.
Definition domain.hpp:81
Verbosity SetVerbosity(int loggerNo, Verbosity verbosity, Priority priority)
Definition domain.cpp:165
NString FullPath
The full path of the domain (set in the constructor once) .
Definition domain.hpp:75
Priority GetPriority(int loggerNo)
Definition domain.hpp:230
ListPA< std::pair< PrefixLogable *, lang::Inclusion >, Recycling::None > PrefixLogables
Prefix Logables associated with this domain.
Definition domain.hpp:90
int GetLoggerNo(const NString &loggerName)
Definition domain.hpp:194
int AddLogger(detail::Logger *logger)
Definition domain.hpp:137
detail::Logger * GetLogger(const NString &loggerName)
Definition domain.hpp:174
const NString & GetName() const
Definition logger.hpp:143
virtual void Log(Domain &dom, Verbosity verbosity, BoxesMA &logables, ScopeInfo &scope)=0
time::Ticks TimeOfLastLog
Timestamp of the last log operation.
Definition logger.hpp:69
virtual void AcknowledgeLox(LoxImpl *lox, lang::ContainerOp op)
Definition logger.hpp:134
time::Ticks TimeOfCreation
The creation time of the Logger.
Definition logger.hpp:66
static std::vector< SourcePathTrimRule > GlobalSPTRs
List of trim definitions for portions of source paths to be ignored.
Definition scopeinfo.hpp:58
const NCString & GetOrigFile()
std::thread::id GetThreadNativeID()
void SetSourcePathTrimRule(const NCString &path, lang::Inclusion includeString, int trimOffset, lang::Case sensitivity, const NString &trimReplacement, lang::Reach reach, Priority priority)
NString loxName
The name of the Lox we are attached to.
void SetFileNameCacheCapacity(integer numberOfLists, integer entriesPerList)
ThreadDictionary threadDictionary
Definition scopeinfo.hpp:86
void PopNestedScope()
Releases latest scope information.
void Set(const lang::CallerInfo &ci)
Definition scopeinfo.cpp:85
std::vector< SourcePathTrimRule > LocalSPTRs
List of trim definitions for portions of source paths to be ignored.
Definition scopeinfo.hpp:61
const std::type_info * GetTypeInfo()
static TMonoAllocator * Create(const char *dbgName, lang::HeapAllocator &pAllocator, size_t initialBufferSizeInKB, unsigned bufferGrowthInPercent=200)
void Reset(Snapshot snapshot=Snapshot())
TAString & ReplaceSubstring(const TString< TChar > &src, integer regionStart, integer regionLength)
TAString & DeleteEnd(integer regionLength)
TAString & InsertChars(TChar c, integer qty)
TAString & _(const TAppendable &src)
TAString & Trim(const TCString< TChar > &trimChars=CStringConstantsTraits< TChar >::DefaultWhitespaces())
constexpr integer Length() const
Definition string.hpp:300
constexpr bool IsEmpty() const
Definition string.hpp:349
bool EndsWith(const TString &needle) const
Definition string.hpp:764
TChar CharAtStart() const
Definition string.hpp:417
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.hpp:799
constexpr bool IsNotNull() const
Definition string.hpp:339
constexpr bool IsNotEmpty() const
Definition string.hpp:353
TChar CharAtEnd() const
Definition string.hpp:436
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
Definition string.hpp:368
bool Equals(const TString< TChar > &rhs) const
Definition string.hpp:515
constexpr bool IsNull() const
Definition string.hpp:334
bool StartsWith(const TString &needle) const
Definition string.hpp:735
void Free(TAllocator &allocator)
Definition string.hpp:1756
bool ConsumeString(const TString< TChar > &consumable)
integer ConsumePartOf(const TString< TChar > &consumable, int minChars=1)
bool ConsumeCharFromEnd(TChar consumable)
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
void Set(const DateTime &timeStamp, lang::Timezone timezone=lang::Timezone::Local)
Definition calendar.cpp:49
AString & Format(Substring format, AString &target, lang::CurrentData targetData=lang::CurrentData::Keep) const
Definition calendar.cpp:268
void Set(const TString< TChar > &src, TChar delimiter, bool skipEmptyTokens=false)
TSubstring< TChar > Actual
Definition tokenizer.hpp:64
TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
Definition tokenizer.cpp:4
void AcquireRecursive(ALIB_DBG_TAKE_CI)
Definition locks.cpp:151
void ReleaseRecursive(ALIB_DBG_TAKE_CI)
Definition locks.cpp:184
static Thread * GetCurrent()
Definition thread.hpp:294
ThreadID GetID() const
Definition thread.hpp:223
virtual const character * GetName() const
Definition thread.hpp:237
static DateTime FromFileTime(const FILETIME &fileTime)
static DateTime FromEpochSeconds(time_t epochSeconds)
Definition datetime.hpp:62
DateTime ToDateTime(Ticks ticks)
Ticks ToTicks(DateTime dateTime)
void SetAs(const TDerived &other)
static const Declaration * Get(TEnum element)
bool Define(Priority requestedPriority=Priority::Standard)
Definition variable.cpp:237
bool Try(const String &name)
Variable & Declare(const String &name, const String &typeName, const String &defaultValue=NULL_STRING)
Definition variable.cpp:163
void Raise(const lang::CallerInfo &ci, int type, std::string_view domain, TArgs &&... args)
Definition assert.hpp:178
void SingleThreaded()
Definition assert.cpp:39
constexpr Pair< T1, T2 > MakePair(const T1 &t1, const T2 &t2)
bool ParseEnumOrTypeBool(strings::TSubstring< TChar > &input, TEnum &result, TEnum falseValue, TEnum trueValue)
bool Parse(strings::TSubstring< TChar > &input, TEnum &result)
Reach
Denotes the reach of something.
@ Global
Denotes global reach.
@ Left
Chooses left alignment.
@ Remove
Denotes removals.
@ Insert
Denotes insertions.
@ On
Switch it on, switched on, etc.
Case
Denotes upper and lower case character treatment.
void Destruct(T &object)
Definition tmp.hpp:82
@ Trim
Trim whitespaces away.
Inclusion
Denotes how members of a set something should be taken into account.
@ Exclude
Chooses exclusion.
@ Include
Chooses inclusion.
HashMap< PoolAllocator, NString, T, std::hash< NString >, std::equal_to< NString >, lang::Caching::Enabled, Recycling::None > SSMap
Shortcut to the ScopeStore's hashmap.
@ ScopeDomains
Scope domains.
@ CompilationFlags
ALib/ALox compilation flags
@ DSR
Domain substitution rules.
@ InternalDomains
Internal domains.
@ Version
Library Version and thread safeness.
@ PrefixLogables
Prefix logables.
@ Domains
Log domains currently registered.
@ LogData
Log data objects.
@ Basic
Name and number of log calls.
@ SPTR
Source path trim rules.
@ Once
Log once counters.
@ ThreadMappings
Named threads.
@ VERBOSITY
Denotes configuration variable #"alxcvALOX_LOGGERNAME_VERBOSITY_WITH_LOXNAME".
Definition aloxcamp.hpp:27
@ DOMAIN_SUBSTITUTION
Denotes configuration variable #"alxcvALOX_LOXNAME_DOMAIN_SUBSTITUTION" used by class #"Lox".
Definition aloxcamp.hpp:36
@ DUMP_STATE_ON_EXIT
Denotes configuration variable #"alxcvALOX_LOXNAME_DUMP_STATE_ON_EXIT" used by class #"Lox".
Definition aloxcamp.hpp:42
@ PREFIXES
Denotes configuration variable #"alxcvALOX_LOXNAME_PREFIXES" used by class #"Lox".
Definition aloxcamp.hpp:39
integer ThreadID
The ALib thread identifier type.
Definition thread.hpp:23
variables::Variable CampVariable(camp::Camp &camp)
Definition camp.hpp:283
Definition alox.cpp:14
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
threads::ThreadID ThreadID
Type to store thread identifiers.
Definition thread.hpp:390
strings::TString< nchar > NString
Type alias in namespace #"%alib".
Definition string.hpp:2174
lox::textlogger::TextLogger TextLogger
Type alias in namespace #"%alib".
strings::TField< nchar > NField
Type alias in namespace #"%alib".
NLocalString< 32 > NString32
Type alias name for #"TLocalString;TLocalString<nchar,32>".
constexpr NString NULL_NSTRING
A nulled string of the narrow character type.
Definition string.hpp:2256
variables::Priority Priority
Type alias in namespace #"%alib".
threads::Thread Thread
Type alias in namespace #"%alib".
Definition thread.hpp:387
strings::TCString< nchar > NCString
Type alias in namespace #"%alib".
Definition cstring.hpp:408
variables::Variable Variable
Type alias in namespace #"%alib".
strings::TTab< nchar > NTab
Type alias in namespace #"%alib".
Definition format.hpp:514
CompilationFlagMeaningsEntry COMPILATION_FLAG_MEANINGS[40]
Definition bootstrap.cpp:12
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace #"%alib".
containers::List< T, MonoAllocator, TRecycling > ListMA
Type alias in namespace #"%alib".
Definition list.hpp:689
strings::TEscape< character > Escape
Type alias in namespace #"%alib".
Definition format.hpp:531
LocalString< 64 > String64
Type alias name for #"TLocalString;TLocalString<character,64>".
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.hpp:536
lox::ALoxCamp ALOX
The singleton instance of ALib Camp class #"ALoxCamp".
Definition aloxcamp.cpp:5
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace #"%alib".
boxing::TBoxes< lang::HeapAllocator > Boxes
Type alias in namespace #"%alib".
Definition boxes.hpp:188
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
monomem::TPoolAllocator< MonoAllocator > PoolAllocator
boxing::Box Box
Type alias in namespace #"%alib".
Definition box.hpp:1128
TCompilationFlags COMPILATION_FLAGS
Definition bootstrap.cpp:10
boxing::TBoxes< PoolAllocator > BoxesPA
Type alias in namespace #"%alib".
Definition boxes.hpp:195
int VERSION
Definition bootstrap.cpp:8
strings::TString< character > String
Type alias in namespace #"%alib".
Definition string.hpp:2165
strings::TSubstring< character > Substring
Type alias in namespace #"%alib".
strings::TSubstring< nchar > NSubstring
Type alias in namespace #"%alib".
strings::util::CalendarDateTime CalendarDateTime
Type alias in namespace #"%alib".
Definition calendar.hpp:509
LocalString< 128 > String128
Type alias name for #"TLocalString;TLocalString<character,128>".
boxing::TBoxes< MonoAllocator > BoxesMA
Type alias in namespace #"%alib".
Definition boxes.hpp:192
NLocalString< 256 > NString256
Type alias name for #"TLocalString;TLocalString<nchar,256>".
LocalString< 256 > String256
Type alias name for #"TLocalString;TLocalString<character,256>".
time::Ticks Ticks
Type alias in namespace #"%alib".
Definition ticks.hpp:86
boxing::FEquals FEquals
Type alias in namespace #"%alib".
NLocalString< 128 > NString128
Type alias name for #"TLocalString;TLocalString<nchar,128>".
NLocalString< 512 > NString512
Type alias name for #"TLocalString;TLocalString<nchar,512>".
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
variables::Declaration Declaration
Type alias in namespace #"%alib".
time::TickConverter TickConverter
Type alias in namespace #"%alib".
std::vector< T, StdMA< T > > StdVectorMA
Type alias in namespace #"%alib".
NLocalString< 64 > NString64
Type alias name for #"TLocalString;TLocalString<nchar,64>".
LocalString< 32 > String32
Type alias name for #"TLocalString;TLocalString<character,32>".
threads::RecursiveLock RecursiveLock
Type alias in namespace #"%alib".
time::DateTime DateTime
Type alias in namespace #"%alib".
Definition datetime.hpp:188
unsigned char REVISION
Definition bootstrap.cpp:9
strings::TTab< character > Tab
Type alias in namespace #"%alib".
Definition format.hpp:511
See sibling type #"NC".
Definition chk_nc.hpp:30
void Clear()
Frees all allocated strings and clears vector.
Definition aloxcamp.hpp:110
integer Add(const strings::TString< character > &src)
Definition vector.hpp:81
NString32 Search
The path to search.
Definition loxpimpl.cpp:30
DomainSubstitutionRule(const NString &s, const NString &r)
Definition loxpimpl.cpp:36
NString32 Replacement
The replacement.
Definition loxpimpl.cpp:31
static BoxesMA & GetLogableContainer(LoxImpl *impl)
static const NString & GetName(LoxImpl *impl)
Definition loxpimpl.cpp:241
static void getVerbosityFromConfig(LoxImpl *impl, variables::Variable &variable, detail::Logger *logger, detail::Domain &dom)
static BoxesMA & acquireInternalLogables(LoxImpl *impl)
static void SetFileNameCacheCapacity(LoxImpl *impl, integer numberOfLists, integer entriesPerList)
Definition loxpimpl.cpp:341
static detail::Domain * evaluateResultDomain(LoxImpl *impl, const NString &domainPath)
static void logInternal(LoxImpl *impl, Verbosity verbosity, const NString &subDomain, BoxesMA &msg)
static void SetStartTime(LoxImpl *impl, Ticks startTime, const NString &loggerName)
Definition loxpimpl.cpp:998
static integer & GetLogCounter(LoxImpl *impl)
Definition loxpimpl.cpp:243
static int checkScopeInformation(LoxImpl *impl, Scope &scope, const NString &internalDomain)
static void init(LoxImpl *impl)
Definition loxpimpl.cpp:272
static void Destruct(LoxImpl *lox)
Definition loxpimpl.cpp:235
static void store(LoxImpl *impl, const Box &data, const NString &pKey, Scope scope)
static void RemoveThreadDomain(LoxImpl *impl, const NString &scopeDomain, Scope scope, threads::Thread *thread)
Definition loxpimpl.cpp:806
static bool RemoveLogger(LoxImpl *impl, detail::Logger *logger)
Definition loxpimpl.cpp:517
static void SetVerbosity(LoxImpl *impl, detail::Logger *logger, Verbosity verbosity, const NString &domain, Priority priority)
Definition loxpimpl.cpp:580
static void SetDomain(LoxImpl *impl, const NString &scopeDomain, Scope scope, threads::Thread *thread)
Definition loxpimpl.cpp:361
static detail::Domain * findDomain(LoxImpl *impl, detail::Domain &domainSystem, NString domainPath)
static void SetDomainSubstitutionRule(LoxImpl *impl, const NString &domainPath, const NString &replacement)
Definition loxpimpl.cpp:826
static void SetPrefix(LoxImpl *impl, const Box &prefix, const NString &domain, lang::Inclusion otherPLs)
Definition loxpimpl.cpp:941
static void Release(LoxImpl *impl)
Definition loxpimpl.cpp:264
static void writeVerbositiesOnLoggerRemoval(LoxImpl *impl, Logger *logger)
Definition loxpimpl.cpp:401
static void setPrefix(LoxImpl *impl, const Box &prefix, Scope scope, threads::Thread *thread)
Definition loxpimpl.cpp:885
static void SetVerbosityExport(LoxImpl *impl, detail::Logger *logger, bool value, Priority priority=Priority::Standard)
Definition loxpimpl.cpp:710
static void log(LoxImpl *impl, detail::Domain *dom, Verbosity verbosity, BoxesMA &logables, lang::Inclusion prefixes)
static void getAllVerbosities(LoxImpl *impl, variables::Variable &variable, detail::Logger *logger, detail::Domain &dom)
static void once(LoxImpl *impl, const NString &domain, Verbosity verbosity, const Box &logables, const String &pGroup, Scope scope, int quantity)
static void SetSourcePathTrimRule(LoxImpl *impl, const NCString &path, lang::Inclusion includeString, int trimOffset, lang::Case sensitivity, const NString &trimReplacement, lang::Reach reach, Priority priority)
Definition loxpimpl.cpp:348
static void Entry(LoxImpl *impl, const NString &domain, Verbosity verbosity)
static void getDomainPrefixFromConfig(LoxImpl *impl, detail::Domain &dom)
static LoxImpl * Construct(const NString &name)
Definition loxpimpl.cpp:225
static void Acquire(LoxImpl *impl, const lang::CallerInfo &ci)
Definition loxpimpl.cpp:253
static void GetState(LoxImpl *impl, NAString &buf, StateInfo flags)
static MonoAllocator & DbgGetMonoAllocator(LoxImpl *impl)
Definition loxpimpl.cpp:345
static Box retrieve(LoxImpl *impl, const NString &pKey, Scope scope)
static void setDomain(LoxImpl *impl, const NString &scopeDomain, Scope scope, bool removeNTRSD, threads::Thread *thread)
Definition loxpimpl.cpp:735
static void dumpStateOnLoggerRemoval(LoxImpl *impl)
Definition loxpimpl.cpp:452
static detail::Logger * GetLogger(LoxImpl *impl, const NString &loggerName)
Definition loxpimpl.cpp:371
static threads::RecursiveLock & getLock(LoxImpl *impl)
Definition loxpimpl.cpp:246
static bool isThreadRelatedScope(LoxImpl *impl, Scope scope)
static void State(LoxImpl *impl, const NString &domain, Verbosity verbosity, const String &headLine, StateInfo flags)
static void MapThreadName(LoxImpl *impl, const String &threadName, threads::ThreadID id)
monomem::Snapshot beforeLox
Snapshot taken before embedding the lox in the #"monoAllocator".
Definition loxpimpl.cpp:91
ScopeStore< SSMap< int > *, false > scopeLogOnce
Log once counters.
Definition loxpimpl.cpp:132
Domain * internalDomains
The root domain for internal Log Domains.
Definition loxpimpl.cpp:123
T * newPO(TArgs &&... args)
Definition loxpimpl.cpp:208
ScopeInfo scopeInfo
Information about the source code, method, thread, etc. invoking a log call.
Definition loxpimpl.cpp:115
ScopeStore< NString, true > scopeDomains
Scope Domains.
Definition loxpimpl.cpp:126
PoolAllocator poolAllocator
A pool allocator that uses #"monoAllocator" as its source.
Definition loxpimpl.cpp:88
integer maxLoggerNameLength
Used for tabular output of logger lists.
Definition loxpimpl.cpp:138
int CountAcquirements() const noexcept
Definition loxpimpl.cpp:199
const NString noKeyHashKey
A key value used in stores if no key is given (global object).
Definition loxpimpl.cpp:144
bool oneTimeWarningCircularDS
Flag if a warning on circular rule detection was logged.
Definition loxpimpl.cpp:151
StdVectorMA< BoxesMA * > internalLogables
A list of a list of logables used for (recursive) internal logging.
Definition loxpimpl.cpp:109
integer maxDomainPathLength
Used for tabular output of logger lists.
Definition loxpimpl.cpp:141
StdVectorMA< BoxesMA * > logableContainers
A list of a list of logables used for (recursive) logging.
Definition loxpimpl.cpp:106
ListMA< DomainSubstitutionRule > domainSubstitutions
The list of domain substitution rules.
Definition loxpimpl.cpp:148
MonoAllocator & monoAllocator
The self-contained monotonic allocator, that also contains this struct itself.
Definition loxpimpl.cpp:85
bool loggerAddedSinceLastDebugState
Flag used with configuration variable LOXNAME_DUMP_STATE_ON_EXIT.
Definition loxpimpl.cpp:154
int AcquirementsCount
Counts the number of nested (recursive) acquirements.
Definition loxpimpl.cpp:99
LoxImpl(MonoAllocator *ma, const NString &name)
Definition loxpimpl.cpp:160
ScopeStore< SSMap< Box > *, false > scopeLogData
Log data store.
Definition loxpimpl.cpp:135
ScopeStore< PrefixLogable *, true > scopePrefixes
Prefix logables store.
Definition loxpimpl.cpp:129
integer internalLogRecursionCounter
The recursion counter for internal logging.
Definition loxpimpl.cpp:112
threads::RecursiveLock Lock
A mutex to control parallel access.
Definition loxpimpl.cpp:95