1111#include " base/atomic.hpp"
1212#include " base/defer.hpp"
1313#include " base/logger.hpp"
14+ #include " base/streamlogger.hpp"
1415#include " base/application.hpp"
1516#include " base/process.hpp"
1617#include " base/timer.hpp"
2526#include < boost/program_options.hpp>
2627#include < iostream>
2728#include < fstream>
29+ #include < sstream>
2830
2931#ifdef _WIN32
3032#include < windows.h>
@@ -222,6 +224,10 @@ static double GetDebugWorkerDelay()
222224
223225static String l_ObjectsPath;
224226
227+ #ifndef _WIN32
228+ static bool l_WorkerLoadedConfig = false ;
229+ #endif /* _WIN32 */
230+
225231/* *
226232 * Do the actual work (config loading, ...)
227233 *
@@ -246,6 +252,13 @@ int RunWorker(const std::vector<std::string>& configs, bool closeConsoleLog = fa
246252 }
247253#endif /* I2_DEBUG */
248254
255+ std::ostringstream oss;
256+ StreamLogger::Ptr sl = new StreamLogger ();
257+
258+ sl->BindStream (&oss, false );
259+ sl->Start (true );
260+ sl->SetActive (true );
261+
249262 Log (LogInformation, " cli" , " Loading configuration file(s)." );
250263 NotifyStatus (" Loading configuration file(s)..." );
251264
@@ -255,14 +268,24 @@ int RunWorker(const std::vector<std::string>& configs, bool closeConsoleLog = fa
255268 if (!DaemonUtility::LoadConfigFiles (configs, newItems, l_ObjectsPath, Configuration::VarsPath)) {
256269 Log (LogCritical, " cli" , " Config validation failed. Re-run with 'icinga2 daemon -C' after fixing the config." );
257270 NotifyStatus (" Config validation failed." );
271+
272+ sl->Stop (true );
273+ sl = nullptr ;
274+ Application::SetLastReloadFailed (Utility::GetTime (), oss.str ());
275+
258276 return EXIT_FAILURE;
259277 }
260278
279+ sl->Stop (true );
280+ sl = nullptr ;
281+ oss = decltype (oss)();
282+
261283#ifndef _WIN32
262284 Log (LogNotice, " cli" )
263285 << " Notifying umbrella process (PID " << l_UmbrellaPid << " ) about the config loading success" ;
264286
265287 (void )kill (l_UmbrellaPid, SIGUSR2);
288+ l_WorkerLoadedConfig = true ;
266289
267290 Log (LogNotice, " cli" )
268291 << " Waiting for the umbrella process to let us doing the actual work" ;
@@ -489,6 +512,7 @@ static pid_t StartUnixWorker(const std::vector<std::string>& configs, bool close
489512 }
490513
491514 (void )sigprocmask (SIG_UNBLOCK, &l_UnixWorkerSignals, nullptr );
515+ Application::SetLastReloadFailed (Utility::GetTime (), " fork(2) failed" );
492516 return -1 ;
493517
494518 case 0 :
@@ -531,6 +555,12 @@ static pid_t StartUnixWorker(const std::vector<std::string>& configs, bool close
531555 } catch (const std::exception& ex) {
532556 Log (LogCritical, " cli" )
533557 << " Failed to re-initialize thread pool after forking (child): " << DiagnosticInformation (ex);
558+
559+ Application::SetLastReloadFailed (
560+ Utility::GetTime (),
561+ " Failed to re-initialize thread pool after forking (child): " + DiagnosticInformation (ex)
562+ );
563+
534564 _exit (EXIT_FAILURE);
535565 }
536566
@@ -539,14 +569,29 @@ static pid_t StartUnixWorker(const std::vector<std::string>& configs, bool close
539569 } catch (const std::exception& ex) {
540570 Log (LogCritical, " cli" )
541571 << " Failed to initialize process spawn helper after forking (child): " << DiagnosticInformation (ex);
572+
573+ Application::SetLastReloadFailed (
574+ Utility::GetTime (),
575+ " Failed to initialize process spawn helper after forking (child): " + DiagnosticInformation (ex)
576+ );
577+
542578 _exit (EXIT_FAILURE);
543579 }
544580
545581 _exit (RunWorker (configs, closeConsoleLog, stderrFile));
546582 } catch (const std::exception& ex) {
547583 Log (LogCritical, " cli" ) << " Exception in main process: " << DiagnosticInformation (ex);
584+
585+ if (!l_WorkerLoadedConfig) {
586+ Application::SetLastReloadFailed (Utility::GetTime (), " Exception in main process: " + DiagnosticInformation (ex));
587+ }
588+
548589 _exit (EXIT_FAILURE);
549590 } catch (...) {
591+ if (!l_WorkerLoadedConfig) {
592+ Application::SetLastReloadFailed (Utility::GetTime (), " Exception in main process" );
593+ }
594+
550595 _exit (EXIT_FAILURE);
551596 }
552597
@@ -813,15 +858,14 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
813858 break ;
814859 case -2 :
815860 Log (LogCritical, " Application" , " Found error in config: reloading aborted" );
816- Application::SetLastReloadFailed (Utility::GetTime ());
817861 break ;
818862 default :
819863 Log (LogInformation, " Application" )
820864 << " Reload done, old process shutting down. Child process with PID '" << nextWorker << " ' is taking over." ;
821865
822866 NotifyStatus (" Shutting down old instance..." );
823867
824- Application::SetLastReloadFailed (0 );
868+ Application::SetLastReloadFailed (0 , " " );
825869 (void )kill (currentWorker, SIGTERM);
826870
827871 {
0 commit comments