<commit_before># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

package PBot::Logger;

use warnings;
use strict;

use feature 'unicode_strings';

use File::Basename;
use Carp ();

sub new {
  if (ref($_[1]) eq 'HASH') {
    Carp::croak("Options to Logger should be key/value pairs, not hash reference");
  }

  my ($class, %conf) = @_;

  my $pbot = $conf{pbot} // Carp::croak "Missing pbot reference to " . __FILE__;
  my $logfile = $conf{filename} // Carp::croak "Missing logfile parameter in " . __FILE__;

  my $path = dirname $logfile;
  if (not -d $path) {
    print "Creating new logfile path: $path\n";
    mkdir $path or Carp::croak "Couldn't create logfile path: $!\n";
  }

  open LOGFILE, ">>$logfile" or Carp::croak "Couldn't open logfile $logfile: $!\n";
  LOGFILE->autoflush(1);

  my $self = bless {
    logfile => $logfile,
    pbot => $pbot,
    start => time,
  }, $class;

  $self->{pbot}->{atexit}->register(sub { $self->rotate_log; return; });

  return $self;
}

sub log {
  my ($self, $text) = @_;
  my $time = localtime;

  $text =~ s/(\P{PosixGraph})/my $ch = $1; if ($ch =~ m{[\s]}) { $ch } else { sprintf "\\x%02X", ord $ch }/ge;

  if (defined $self->{logfile}) {
    print LOGFILE "$time :: $text";
  }

  print "$time :: $text";
}

sub rotate_log {
  my ($self) = @_;
  my $time = localtime $self->{start};
  $time =~ s/\s+/_/g;
  close LOGFILE;
  rename $self->{logfile}, $self->{logfile} . '-' . $time;
}

1;<commit_msg>Logger: reopen logfile after rotation to log final messages<commit_after># This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

package PBot::Logger;

use warnings;
use strict;

use feature 'unicode_strings';

use Scalar::Util qw/openhandle/;
use File::Basename;
use Carp ();

sub new {
  if (ref($_[1]) eq 'HASH') {
    Carp::croak("Options to Logger should be key/value pairs, not hash reference");
  }

  my ($class, %conf) = @_;

  my $pbot = $conf{pbot} // Carp::croak "Missing pbot reference to " . __FILE__;
  my $logfile = $conf{filename} // Carp::croak "Missing logfile parameter in " . __FILE__;

  my $path = dirname $logfile;
  if (not -d $path) {
    print "Creating new logfile path: $path\n";
    mkdir $path or Carp::croak "Couldn't create logfile path: $!\n";
  }

  open LOGFILE, ">>$logfile" or Carp::croak "Couldn't open logfile $logfile: $!\n";
  LOGFILE->autoflush(1);

  my $self = bless {
    logfile => $logfile,
    pbot => $pbot,
    start => time,
  }, $class;

  $self->{pbot}->{atexit}->register(sub { $self->rotate_log; return; });

  return $self;
}

sub log {
  my ($self, $text) = @_;
  my $time = localtime;

  $text =~ s/(\P{PosixGraph})/my $ch = $1; if ($ch =~ m{[\s]}) { $ch } else { sprintf "\\x%02X", ord $ch }/ge;

  if (openhandle *LOGFILE) {
    print LOGFILE "$time :: $text";
  }

  print "$time :: $text";
}

sub rotate_log {
  my ($self) = @_;
  my $time = localtime $self->{start};
  $time =~ s/\s+/_/g;

  # logfile has to be closed first for maximum compatibility with `rename`
  close LOGFILE;
  rename $self->{logfile}, $self->{logfile} . '-' . $time;

  # reopen renamed logfile to resume any needed logging
  open LOGFILE, ">>$self->{logfile}-$time" or Carp::carp "Couldn't re-open logfile $self->{logfile}-$time: $!\n";
  LOGFILE->autoflush(1) if openhandle *LOGFILE;
}

1;
{'fraction_non_alphanumeric': 0.1789208834218619, 'fraction_numerical': 0.005870841487279843, 'mean_word_length': 3.3901840490797546, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4688274', 'n_tokens_mistral': 1378, 'n_tokens_neox': 1328, 'n_words': 409}