SimpleSystemSetting: Controller für die ganzen trivialen CRUD-Masken im System-Menü
[kivitendo-erp.git] / SL / LXDebug.pm
index 6517d9c..e0b7cca 100644 (file)
@@ -11,19 +11,21 @@ use constant REQUEST_TIMER      =>  1 << 6;
 use constant REQUEST            =>  1 << 7;
 use constant WARN               =>  1 << 8;
 use constant TRACE2             =>  1 << 9;
-use constant ALL                => (1 << 10) - 1;
+use constant SHOW_CALLER        =>  1 << 10;
+use constant ALL                => (1 << 11) - 1;
 use constant DEVEL              => INFO | DEBUG1 | QUERY | TRACE | BACKTRACE_ON_ERROR | REQUEST_TIMER;
 
 use constant FILE_TARGET   => 0;
 use constant STDERR_TARGET => 1;
 
 use Data::Dumper;
-use POSIX qw(strftime getppid);
+use POSIX qw(strftime getpid);
 use Time::HiRes qw(gettimeofday tv_interval);
 use YAML;
 use SL::Request ();
 
 use strict;
+use utf8;
 
 my ($text_diff_available);
 
@@ -129,10 +131,10 @@ sub show_backtrace {
 
   return 1 unless ($force || ($global_level & BACKTRACE_ON_ERROR));
 
-  $self->message(BACKTRACE_ON_ERROR, "Starting full caller dump:");
+  $self->message(0, "Starting full caller dump:");
   my $level = 0;
   while (my ($dummy, $filename, $line, $subroutine) = caller $level) {
-    $self->message(BACKTRACE_ON_ERROR, "  ${subroutine} from ${filename}:${line}");
+    $self->message(0, "  ${subroutine} from ${filename}:${line}");
     $level++;
   }
 
@@ -143,7 +145,10 @@ sub message {
   no warnings;
   my ($self, $level, $message) = @_;
 
-  $self->_write(level2string($level), $message) if (($self->{"level"} | $global_level) & $level || !$level);
+  my $show_caller = ($level | $global_level) & SHOW_CALLER();
+  $level         &= ~SHOW_CALLER();
+
+  $self->_write(level2string($level), $message, show_caller => $show_caller) if (($self->{"level"} | $global_level) & $level || !$level);
 }
 sub warn {
   no warnings;
@@ -213,6 +218,17 @@ sub dump_sql_result {
   $self->message($level, $prefix . sprintf('(%d row%s)', scalar @{ $results }, scalar @{ $results } > 1 ? 's' : ''));
 }
 
+sub dump_object {
+  my ($self, $level, $text, $object) = @_;
+
+  my $copy;
+  if ($object) {
+    $copy->{$_} = $object->$_ for $object->meta->columns;
+  }
+
+  $self->dump($level, $text, $copy);
+}
+
 sub show_diff {
   my ($self, $level, $item1, $item2, %params) = @_;
 
@@ -248,8 +264,29 @@ sub is_tracing_enabled {
 
 sub _write {
   no warnings;
-  my ($self, $prefix, $message) = @_;
-  my $date = strftime("%Y-%m-%d %H:%M:%S $$ [" . getppid() . "] ${prefix}: ", localtime(time()));
+  my ($self, $prefix, $message, %options) = @_;
+
+  my @prefixes = ($prefix);
+
+  if ($options{show_caller}) {
+    my $level = 1;
+    while (1) {
+      my ($package, $filename, $line, $subroutine) = caller($level);
+
+      if (($filename // '') =~ m{LXDebug\.pm$}) {
+        $level++;
+        next;
+      }
+
+      push @prefixes, "${filename}:${line}";
+      last;
+    }
+  }
+
+  $prefix = join ' ', grep { $_ } @prefixes;
+
+  my @now  = gettimeofday();
+  my $date = strftime("%Y-%m-%d %H:%M:%S." . sprintf('%03d', int($now[1] / 1000)) . " $$ [" . getpid() . "] ${prefix}: ", localtime($now[0]));
   local *FILE;
 
   chomp($message);
@@ -261,6 +298,7 @@ sub _write_raw {
   local *FILE;
   if ((FILE_TARGET == $self->{"target"})
       && open(FILE, ">>", $self->{"file"})) {
+    binmode FILE, ":utf8";
     print FILE $message;
     close FILE;
 
@@ -282,9 +320,10 @@ sub begin_request {
 }
 
 sub end_request {
-  my $self = shift;
+  my ($self, %params) = @_;
   return 1 unless want_request_timer();
-  $self->_write("time", $self->get_request_time);
+
+  $self->_write("time", sprintf('%f (%s/%s)', $self->get_request_time, $params{script_name}, $params{action}));
 
   $self->{calldepth} = 0;
 }
@@ -292,7 +331,12 @@ sub end_request {
 sub log_time {
   my ($self, @slurp) = @_;
   return 1 unless want_request_timer();
-  $self->_write("time", $self->get_request_time() . (@slurp ? " (@slurp)" : ''));
+
+  my $now                    = $self->get_request_time;
+  my $diff                   = int((($now - ($self->{previous_log_time} // 0)) * 10_000 + 5) / 10);
+  $self->{previous_log_time} = $now;
+
+  $self->_write("time", "${now}s Δ ${diff}ms" . (@slurp ? " (@slurp)" : ''));
 }
 
 sub get_request_time {