Loggers in Log4perl control if a message gets logged or not (via categories and levels), while appenders control where a message gets logged, so in your case you'll want to adapt your appenders to the subdirectory you're currently processing, not your loggers.
Typically Log4perl sets up its configuration at the start and then keeps chugging unmodified, but you can't do that in your use case because you don't know the number of different directories you're going to encounter up front (or don't want to hard code them), so you need to adapt your Log4perl configuration dynamically as you step through the directories.
Here's a proof of concept, using add_appender() and remove_appender() to configure the same logger for the currently processed directory:
use warnings;
use strict;
use Log::Log4perl qw(get_logger :levels);
my @dirs = qw( foo bar baz foo bar baz );
my $logger = get_logger();
$logger->level( $INFO );
for my $dir ( @dirs ) {
if( ! -d $dir ) {
mkdir $dir or die "$dir: $!";
}
my $appender = Log::Log4perl::Appender->new(
"Log::Log4perl::Appender::File",
name => "file-$dir",
filename => "$dir/test.log",
layout => Log::Log4perl::Layout::SimpleLayout->new( ),
mode => "append",
);
$logger->add_appender( $appender );
$logger->info( "hello there in $dir" );
$logger->remove_appender( $appender->name( ) );
}
Hope that helps!