<commit_before>package Log::Dispatch::File;

use strict;

use Log::Dispatch::Output;

use base qw( Log::Dispatch::Output );
use fields qw( fh filename );

use vars qw[ $VERSION ];

$VERSION = sprintf "%d.%02d", q$Revision: 1.17 $ =~ /: (\d+)\.(\d+)/;

# Prevents death later on if IO::File can't export this constant.
BEGIN
{
    my $exists;
    eval { $exists = O_APPEND(); };

    *O_APPEND = \&APPEND unless defined $exists;
}

sub APPEND {;};

1;

sub new
{
    my $proto = shift;
    my $class = ref $proto || $proto;

    my %params = @_;

    my $self = bless {}, $class;

    $self->_basic_init(%params);
    $self->_make_handle(%params);

    return $self;
}

sub _make_handle
{
    my $self = shift;
    my %params = @_;

    $self->{filename} = $params{filename};

    my $mode;
    if ( exists $params{mode} &&
	 defined $params{mode} &&
	 ( $params{mode} =~ /^>>$|^append$/ ||
	   ( $params{mode} =~ /^\d+$/ &&
	     $params{mode} == O_APPEND() ) ) )
    {
	$mode = '>>';
    }
    else
    {
	$mode = '>';
    }

    my $fh = do { local *FH; *FH; };
    open $fh, "$mode$self->{filename}"
	or die "Can't write to '$self->{filename}': $!";

    # turn on autoflush
    my $oldfh = select $fh; $| = 1; select $oldfh;

    $self->{fh} = $fh;
}

sub log_message
{
    my $self = shift;
    my %params = @_;

    my $fh = $self->{fh};
    print $fh $params{message};
}

sub DESTROY
{
    my $self = shift;

    if ( $self->{fh} )
    {
	my $fh = $self->{fh};
	close $fh;
    }
}

__END__

=head1 NAME

Log::Dispatch::File - Object for logging to files

=head1 SYNOPSIS

  use Log::Dispatch::File;

  my $file = Log::Dispatch::File->new( name      => 'file1',
                                       min_level => 'info',
                                       filename  => 'Somefile.log',
                                       mode      => 'append' );

  $file->log( level => 'emerg', message => "I've fallen and I can't get up\n" );

=head1 DESCRIPTION

This module provides a simple object for logging to files under the
Log::Dispatch::* system.

=head1 METHODS

=over 4

=item * new(%PARAMS)

This method takes a hash of parameters.  The following options are
valid:

=item -- name ($)

The name of the object (not the filename!).  Required.

=item -- min_level ($)

The minimum logging level this object will accept.  See the
Log::Dispatch documentation for more information.  Required.

=item -- max_level ($)

The maximum logging level this obejct will accept.  See the
Log::Dispatch documentation for more information.  This is not
required.  By default the maximum is the highest possible level (which
means functionally that the object has no maximum).

=item -- filename ($)

The filename to be opened for writing.

=item -- mode ($)

The mode the file should be opened with.  Valid options are 'write',
'>', 'append', '>>', or the relevant constants from Fcntl.  The
default is 'write'.

=item -- callbacks( \& or [ \&, \&, ... ] )<commit_msg>use P::V add autoflush as parameter<commit_after>package Log::Dispatch::File;

use strict;

use Log::Dispatch::Output;

use base qw( Log::Dispatch::Output );

use Params::Validate qw(validate SCALAR BOOLEAN);
Params::Validate::validation_options( allow_extra => 1 );

use vars qw[ $VERSION ];

$VERSION = sprintf "%d.%02d", q$Revision: 1.18 $ =~ /: (\d+)\.(\d+)/;

# Prevents death later on if IO::File can't export this constant.
BEGIN
{
    my $exists;
    eval { $exists = O_APPEND(); };

    *O_APPEND = \&APPEND unless defined $exists;
}

sub APPEND {;};

1;

sub new
{
    my $proto = shift;
    my $class = ref $proto || $proto;

    my %p = @_;

    my $self = bless {}, $class;

    $self->_basic_init(%p);
    $self->_make_handle(%p);

    return $self;
}

sub _make_handle
{
    my $self = shift;

    my %p = validate( @_, { filename  => { type => SCALAR },
			    mode      => { type => SCALAR,
					   default => '>' },
			    autoflush => { type => BOOLEAN,
					   default => 1 }
			  } );

    $self->{filename} = $p{filename};

    my $mode;
    if ( exists $p{mode} &&
	 defined $p{mode} &&
	 ( $p{mode} =~ /^>>$|^append$/ ||
	   ( $p{mode} =~ /^\d+$/ &&
	     $p{mode} == O_APPEND() ) ) )
    {
	$mode = '>>';
    }
    else
    {
	$mode = '>';
    }

    my $fh = do { local *FH; *FH; };
    open $fh, "$mode$self->{filename}"
	or die "Can't write to '$self->{filename}': $!";

    if ( $p{autoflush} )
    {
	my $oldfh = select $fh; $| = 1; select $oldfh;
    }

    $self->{fh} = $fh;
}

sub log_message
{
    my $self = shift;
    my %p = @_;

    my $fh = $self->{fh};
    print $fh $p{message};
}

sub DESTROY
{
    my $self = shift;

    if ( $self->{fh} )
    {
	my $fh = $self->{fh};
	close $fh;
    }
}

__END__

=head1 NAME

Log::Dispatch::File - Object for logging to files

=head1 SYNOPSIS

  use Log::Dispatch::File;

  my $file = Log::Dispatch::File->new( name      => 'file1',
                                       min_level => 'info',
                                       filename  => 'Somefile.log',
                                       mode      => 'append' );

  $file->log( level => 'emerg', message => "I've fallen and I can't get up\n" );

=head1 DESCRIPTION

This module provides a simple object for logging to files under the
Log::Dispatch::* system.

=head1 METHODS

=over 4

=item * new(%params)

This method takes a hash of parameters.  The following options are
valid:

=item -- name ($)

The name of the object (not the filename!).  Required.

=item -- min_level ($)

The minimum logging level this object will accept.  See the
Log::Dispatch documentation for more information.  Required.

=item -- max_level ($)

The maximum logging level this obejct will accept.  See the
Log::Dispatch documentation for more information.  This is not
required.  By default the maximum is the highest possible level (which
means functionally that the object has no maximum).

=item -- filename ($)

The filename to be opened for writing.

=item -- mode ($)

The mode the file should be opened with.  Valid options are 'write',
'>', 'append', '>>', or the relevant constants from Fcntl.  The
default is 'write'.

=item -- callbacks( \& or [ \&, \&, ... ] )
{'fraction_non_alphanumeric': 0.1629040116940068, 'fraction_numerical': 0.004547669319473769, 'mean_word_length': 2.5248998282770465, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3777078', 'n_tokens_mistral': 2221, 'n_tokens_neox': 2070, 'n_words': 660}