@@ -2377,98 +2377,85 @@ static constexpr unsigned queueLenDefault = 512;
2377
2377
static constexpr unsigned queueDropDefault = 0 ; // disabled by default
2378
2378
static constexpr bool useSysLogDefault = false ;
2379
2379
2380
- static Singleton<bool > firstUpdateConfigHookCall;
2381
- static bool firstUpdateConfigHookCallValue{true };
2382
- bool queryFirstUpdateConfigHookCall ()
2380
+ struct LogFormatChangedDetails
2383
2381
{
2384
- return *firstUpdateConfigHookCall.query ([] () { return &firstUpdateConfigHookCallValue; });
2385
- }
2386
-
2387
- auto updateConfigFunc = [](const IPropertyTree *oldComponentConfiguration, const IPropertyTree *oldGlobalConfiguration)
2388
- {
2389
- setupContainerizedLogMsgHandler (true );
2382
+ StringBuffer logFormat{" " };
2383
+ bool formatChangeDetected{false };
2390
2384
};
2391
- static CConfigUpdateHook configUpdateHook;
2392
- // NOTE: The parameter updateConfigOnTheFly value of true signifies that the thread
2393
- // safe caller has completed setting up the logging configuration (normally
2394
- // from a main call).
2395
- // Any further configuration changes are from non-thread safe callers.
2396
- // EXCEPT: There are 2 calls to setupContainerizedLogMsgHandler that are
2397
- // thread-safe. In order to allow them to change the log format (if required)
2398
- // etc we need to allow the first config update hook call to update the config
2399
- // as if it was not called from the config update hook.
2400
- void setupContainerizedLogMsgHandler (bool updateConfigOnTheFly)
2385
+ LogFormatChangedDetails hasLogFormatChanged (const Owned<IPropertyTree> &logConfig)
2401
2386
{
2402
- // Allow the first config update hook call to update the config as if it was not
2403
- // called from the config update hook to allow log configuration changes.
2404
- if (updateConfigOnTheFly && queryFirstUpdateConfigHookCall ())
2387
+ UWARNLOG (" DJPS hasLogFormatChanged() called" );
2388
+ LogFormatChangedDetails logFormatChanged{};
2389
+
2390
+ if (logConfig->hasProp (logFormatAtt))
2405
2391
{
2406
- firstUpdateConfigHookCallValue = false ;
2407
- updateConfigOnTheFly = false ;
2392
+ StringAttr logConfigFormat (logConfig->queryProp (logFormatAtt));
2393
+ UWARNLOG (" DJPS hasLogFormatChanged() logConfigFormat=%s" , logConfigFormat.str ());
2394
+ logFormatChanged.logFormat .set (logConfigFormat.str ());
2395
+ if (streq (logConfigFormat, " xml" ))
2396
+ {
2397
+ UWARNLOG (" DJPS hasLogFormatChanged() xml" );
2398
+ if (theStderrHandler->queryFormatType () != LOGFORMAT_xml)
2399
+ {
2400
+ UWARNLOG (" DJPS hasLogFormatChanged() logFormatChanged.formatChangeDetected = true" );
2401
+ logFormatChanged.formatChangeDetected = true ;
2402
+ }
2403
+ }
2404
+ else if (streq (logConfigFormat, " json" ))
2405
+ {
2406
+ UWARNLOG (" DJPS hasLogFormatChanged() json" );
2407
+ if (theStderrHandler->queryFormatType () != LOGFORMAT_json)
2408
+ {
2409
+ UWARNLOG (" DJPS hasLogFormatChanged() logFormatChanged.formatChangeDetected = true" );
2410
+ logFormatChanged.formatChangeDetected = true ;
2411
+ }
2412
+ }
2413
+ else if (streq (logConfigFormat, " table" ))
2414
+ {
2415
+ UWARNLOG (" DJPS hasLogFormatChanged() table" );
2416
+ if (theStderrHandler->queryFormatType () != LOGFORMAT_table)
2417
+ {
2418
+ UWARNLOG (" DJPS hasLogFormatChanged() logFormatChanged.formatChangeDetected = true" );
2419
+ logFormatChanged.formatChangeDetected = true ;
2420
+ }
2421
+ }
2422
+ else
2423
+ LOG (MCoperatorWarning, " JLog: Invalid log format configuration detected '%s'!" , logConfigFormat.str ());
2408
2424
}
2409
2425
2426
+ return logFormatChanged;
2427
+ }
2428
+
2429
+ bool configureHandlers (bool rejectOnTheFlyChanges)
2430
+ {
2431
+ UWARNLOG (" DJPS configureHandlers(%s)" , boolToStr (rejectOnTheFlyChanges));
2410
2432
Owned<IPropertyTree> logConfig = getComponentConfigSP ()->getPropTree (" logging" );
2411
2433
if (logConfig)
2412
2434
{
2413
2435
if (logConfig->getPropBool (logDisabledAtt, false ))
2414
2436
{
2415
2437
removeLog ();
2416
-
2417
- configUpdateHook.installOnce (updateConfigFunc, false );
2418
- return ;
2438
+ UWARNLOG (" DJPS logging disabled" );
2439
+ return false ;
2419
2440
}
2420
2441
2421
- if (logConfig-> hasProp (logFormatAtt) )
2442
+ if (rejectOnTheFlyChanges )
2422
2443
{
2423
- if (updateConfigOnTheFly)
2424
- {
2444
+ UWARNLOG (" DJPS checking logformat change" );
2445
+ LogFormatChangedDetails logFormatChanged = hasLogFormatChanged (logConfig);
2446
+ if (logFormatChanged.formatChangeDetected )
2425
2447
UWARNLOG (" JLog: Ignoring log format configuration change on the fly is not supported in a containerized environment" );
2426
- }
2427
- else
2428
- {
2429
- const char *logFormat = logConfig->queryProp (logFormatAtt);
2430
- bool newFormatDetected = false ;
2431
- if (streq (logFormat, " xml" ))
2432
- {
2433
- if (theStderrHandler->queryFormatType () != LOGFORMAT_xml)
2434
- {
2435
- newFormatDetected = true ;
2436
- theStderrHandler = new HandleLogMsgHandlerXML (stderr, MSGFIELD_STANDARD);
2437
- }
2438
- }
2439
- else if (streq (logFormat, " json" ))
2440
- {
2441
- if (theStderrHandler->queryFormatType () != LOGFORMAT_json)
2442
- {
2443
- newFormatDetected = true ;
2444
- theStderrHandler = new HandleLogMsgHandlerJSON (stderr, MSGFIELD_STANDARD);
2445
- }
2446
- }
2447
- else if (streq (logFormat, " table" ))
2448
- {
2449
- if (theStderrHandler->queryFormatType () != LOGFORMAT_table)
2450
- {
2451
- newFormatDetected = true ;
2452
- theStderrHandler = new HandleLogMsgHandlerTable (stderr, MSGFIELD_STANDARD);
2453
- }
2454
- }
2455
- else
2456
- LOG (MCoperatorWarning, " JLog: Invalid log format configuration detected '%s'!" , logFormat);
2457
-
2458
- if (newFormatDetected)
2459
- theManager->resetMonitors ();
2460
- }
2461
2448
}
2462
2449
2463
2450
if (logConfig->hasProp (logFieldsAtt))
2464
2451
{
2465
- // Supported logging fields: TRC,SPN,AUD,CLS,DET,MID,TIM,DAT,PID,TID,NOD,JOB,USE,SES,COD,MLT,MCT,NNT,COM,QUO,PFX,ALL,STD
2452
+ // Supported logging fields: TRC,SPN,AUD,CLS,DET,MID,TIM,DAT,PID,TID,NOD,JOB,USE,SES,COD,MLT,MCT,NNT,COM,QUO,PFX,ALL,STD
2466
2453
const char *logFields = logConfig->queryProp (logFieldsAtt);
2467
2454
if (!isEmptyString (logFields))
2468
2455
theStderrHandler->setMessageFields (logMsgFieldsFromAbbrevs (logFields));
2469
2456
}
2470
2457
2471
- // Only recreate filter if at least one filter attribute configured
2458
+ // Only recreate filter if at least one filter attribute configured
2472
2459
if (logConfig->hasProp (logMsgDetailAtt) || logConfig->hasProp (logMsgAudiencesAtt) || logConfig->hasProp (logMsgClassesAtt))
2473
2460
{
2474
2461
LogMsgDetail logDetail = logConfig->getPropInt (logMsgDetailAtt, DefaultDetail);
@@ -2491,6 +2478,73 @@ static CConfigUpdateHook configUpdateHook;
2491
2478
Owned<ILogMsgFilter> filter = getCategoryLogMsgFilter (msgAudiences, msgClasses, logDetail, local);
2492
2479
theManager->changeMonitorFilter (theStderrHandler, filter);
2493
2480
}
2481
+ }
2482
+
2483
+ return true ;
2484
+ }
2485
+
2486
+ auto updateConfigFunc = [](const IPropertyTree *oldComponentConfiguration, const IPropertyTree *oldGlobalConfiguration)
2487
+ {
2488
+ configureHandlers (true );
2489
+ };
2490
+ static CConfigUpdateHook configUpdateHook;
2491
+ void setupContainerizedLogMsgHandler ()
2492
+ {
2493
+ UWARNLOG (" DJPS setupContainerizedLogMsgHandler() called" );
2494
+ configUpdateHook.installOnce (updateConfigFunc, false );
2495
+
2496
+ if (!configureHandlers (false )) // false return means that logging is disabled
2497
+ {
2498
+ UWARNLOG (" DJPS !configureHandlers(false)" );
2499
+ return ;
2500
+ }
2501
+
2502
+ Owned<IPropertyTree> logConfig = getComponentConfigSP ()->getPropTree (" logging" );
2503
+ if (logConfig)
2504
+ {
2505
+ LogFormatChangedDetails logFormatChanged = hasLogFormatChanged (logConfig);
2506
+ if (logFormatChanged.formatChangeDetected )
2507
+ {
2508
+ bool newFormatDetected = false ;
2509
+ if (streq (logFormatChanged.logFormat .str (), " xml" ))
2510
+ {
2511
+ UWARNLOG (" DJPS existing log format is xml" );
2512
+ if (theStderrHandler->queryFormatType () != LOGFORMAT_xml)
2513
+ {
2514
+ UWARNLOG (" DJPS set newFormatDetected = true" );
2515
+ newFormatDetected = true ;
2516
+ theStderrHandler = new HandleLogMsgHandlerXML (stderr, MSGFIELD_STANDARD);
2517
+ }
2518
+ }
2519
+ else if (streq (logFormatChanged.logFormat .str (), " json" ))
2520
+ {
2521
+ UWARNLOG (" DJPS existing log format is json" );
2522
+ if (theStderrHandler->queryFormatType () != LOGFORMAT_json)
2523
+ {
2524
+ UWARNLOG (" DJPS set newFormatDetected = true" );
2525
+ newFormatDetected = true ;
2526
+ theStderrHandler = new HandleLogMsgHandlerJSON (stderr, MSGFIELD_STANDARD);
2527
+ }
2528
+ }
2529
+ else if (streq (logFormatChanged.logFormat .str (), " table" ))
2530
+ {
2531
+ UWARNLOG (" DJPS existing log format is table" );
2532
+ if (theStderrHandler->queryFormatType () != LOGFORMAT_table)
2533
+ {
2534
+ UWARNLOG (" DJPS set newFormatDetected = true" );
2535
+ newFormatDetected = true ;
2536
+ theStderrHandler = new HandleLogMsgHandlerTable (stderr, MSGFIELD_STANDARD);
2537
+ }
2538
+ }
2539
+ else
2540
+ LOG (MCoperatorWarning, " JLog: Invalid log format configuration detected '%s'!" , logFormatChanged.logFormat .str ());
2541
+
2542
+ if (newFormatDetected)
2543
+ {
2544
+ UWARNLOG (" DJPS processing newFormatDetected = true" );
2545
+ theManager->resetMonitors ();
2546
+ }
2547
+ }
2494
2548
2495
2549
unsigned queueLen = logConfig->getPropInt (logQueueLenAtt, queueLenDefault);
2496
2550
if (queueLen)
@@ -2513,29 +2567,17 @@ static CConfigUpdateHook configUpdateHook;
2513
2567
UseSysLogForOperatorMessages ();
2514
2568
2515
2569
unsigned postMortemLines = logConfig->getPropInt (capturePostMortemAtt, 0 );
2516
- if (postMortemLines)
2570
+ if (postMortemLines && !thePostMortemHandler )
2517
2571
{
2518
- if (!thePostMortemHandler)
2519
- {
2520
- // augment postmortem files with <pid> to avoid clashes where multiple processes are running within
2521
- // same process space, e.g. hthor processes running in same k8s container
2522
- unsigned pid = GetCurrentProcessId ();
2523
- VStringBuffer portMortemFileBase (" /tmp/postmortem.%u.log" , pid);
2572
+ // augment postmortem files with <pid> to avoid clashes where multiple processes are running within
2573
+ // same process space, e.g. hthor processes running in same k8s container
2574
+ unsigned pid = GetCurrentProcessId ();
2575
+ VStringBuffer portMortemFileBase (" /tmp/postmortem.%u.log" , pid);
2524
2576
2525
- thePostMortemHandler = new PostMortemLogMsgHandler (portMortemFileBase, postMortemLines, MSGFIELD_STANDARD);
2526
- queryLogMsgManager ()->addMonitor (thePostMortemHandler, getCategoryLogMsgFilter (MSGAUD_all, MSGCLS_all, TopDetail));
2527
- }
2528
- else
2529
- {
2530
- if (thePostMortemHandler->queryMaxLinesToKeep () != postMortemLines)
2531
- {
2532
- thePostMortemHandler->setMaxLinesToKeep (postMortemLines);
2533
- }
2534
- }
2577
+ thePostMortemHandler = new PostMortemLogMsgHandler (portMortemFileBase, postMortemLines, MSGFIELD_STANDARD);
2578
+ queryLogMsgManager ()->addMonitor (thePostMortemHandler, getCategoryLogMsgFilter (MSGAUD_all, MSGCLS_all, TopDetail));
2535
2579
}
2536
2580
}
2537
-
2538
- configUpdateHook.installOnce (updateConfigFunc, false );
2539
2581
}
2540
2582
2541
2583
ILogMsgManager * queryLogMsgManager ()
0 commit comments