in reply to Re^3: Graceful handling of Log::Log4perl errors
in thread Graceful handling of Log::Log4perl errors

I incorporated a few of your changes. In particular, I like the $init_done mechanic; it's much cleaner than what I was doing.

my %paths = (); my $init_done = 0; my $base_path = "/my/base/path/"; INIT: while ( !$init_done ) { $init_done = eval { Log::Log4perl->init($LOGGER_CONF_FILE); 1; }; if ($@) { warn "Logger error was: $@"; # if we get a missing directory error, try some (sane) recover +y if ( $@ =~ m{Can't\sopen\s$base_path(.+)/[^/]+\s\(No such file + or directory\)} ) { my $path = $1; $path = $base_path . $path; warn "log directory $path does not exist, attempting to cr +eate it"; if ( $paths{$path}++ ) { warn "alredy tried to create this path"; last INIT; } eval { mkpath($path) }; warn "unable to create path $path" if ( !-d $path ); } # for other config file errors, throw our hands up in disgust +and move on else { last INIT; } } } # if we couldn't get the config file to initlize, load a blank one and + move on without logging if ( ! $init_done ) { warn "Couldn't initilize logger, defaulting to blank config file"; Log::Log4perl::init(\''); # this will throw a warning, but that's +not really a bad thing }

One thing I learned while doing this: Log4perl sets its initialized flag at the beginning of its initialization, not at the end (on line 113 of Log::Log4perl::Config, in _init, on my install at least), so using init_once here is problematic, as it will not reload after the directory is created. I switched over to using init and relying on the $init_done to guard against unintentional reinitialization. Once I did that, it was necessary to put back in the two level error message check (the else last bit), otherwise it infinite loops because it is dieing on an unrecognized message.

Thanks for all your help!