unstable-Zweig als Kopie des "alten" trunks erstellt.
[kivitendo-erp.git] / SL / LXDebug.pm
1 package LXDebug;
2
3 use constant {
4   NONE => 0,
5   INFO => 1,
6   DEBUG1 => 2,
7   DEBUG2 => 3,
8
9   FILE_TARGET => 0,
10   STDERR_TARGET => 1
11   };
12
13 use POSIX qw(strftime);
14
15 my $data_dumper_available;
16
17 BEGIN {
18   eval("use Data::Dumper");
19   $data_dumper_available = $@ ? 0 : 1;
20
21   $global_level = NONE;
22   $global_trace_subs = 0;
23 }
24
25 sub new {
26   my $type = shift;
27   my $self = {};
28
29   $self->{"calldepth"} = 0;
30   $self->{"file"} = "/tmp/lx-office-debug.log";
31   $self->{"target"} = FILE_TARGET;
32   $self->{"level"} = 0;
33   $self->{"trace_subs"} = 0;
34
35   while ($_[0]) {
36     $self->{$_[0]} = $_[1];
37     shift;
38     shift;
39   }
40
41   bless($self, $type);
42 }
43
44 sub set_target {
45   my ($self, $target, $file) = @_;
46
47   if ((FILE_TARGET == $target) && $file) {
48     $self->{"file"} = $file;
49     $self->{"target"} = FILE_TARGET;
50
51   } elsif (STDERR_TARGET == $target) {
52     $self->{"target"} = STDERR_TARGET;
53   }
54 }
55
56 sub enter_sub {
57   my ($self) = @_;
58
59   if (!$self->{"trace_subs"} && !$global_trace_subs) {
60     return;
61   }
62
63   my ($package, $filename, $line, $subroutine) = caller(1);
64   my ($dummy1, $self_filename, $self_line) = caller(0);
65
66   my $indent = "  " x $self->{"calldepth"};
67   $self->{"calldepth"} += 1;
68
69   if (!defined($package)) {
70     $self->_write("enter_sub", $indent . "top-level?\n");
71   } else {
72     $self->_write("enter_sub", $indent . "${subroutine} in " .
73                   "${self_filename}:${self_line} called from " .
74                   "${filename}:${line}\n");
75   }
76 }
77
78 sub leave_sub {
79   my ($self) = @_;
80
81   if (!$self->{"trace_subs"} && !$global_trace_subs) {
82     return;
83   }
84
85   my ($package, $filename, $line, $subroutine) = caller(1);
86   my ($dummy1, $self_filename, $self_line) = caller(0);
87
88   $self->{"calldepth"} -= 1;
89   my $indent = "  " x $self->{"calldepth"};
90
91   if (!defined($package)) {
92     $self->_write("leave_sub", $indent . "top-level?\n");
93   } else {
94     $self->_write("leave_sub", $indent . "${subroutine} in " .
95                   "${self_filename}:${self_line}\n");
96   }
97 }
98
99 sub message {
100   my ($self, $level, $message) = @_;
101   my ($log_level) = $self->{"level"};
102
103   if ($global_level && ($global_level > $log_level)) {
104     $log_level = $global_level;
105   }
106
107   if ($log_level >= $level) {
108     $self->_write(INFO == $level ? "info" :
109                   DEBUG1 == $level ? "debug1" : "debug2",
110                   $message);
111   }
112 }
113
114 sub dump {
115   my ($self, $level, $name, $variable) = @_;
116
117   if ($data_dumper_available) {
118     $self->message($level, "dumping ${name}:\n" . Dumper($variable));
119   } else {
120     $self->message($level, "dumping ${name}: Data::Dumper not available; " .
121                    "variable cannot be dumped");
122   }
123 }
124
125 sub enable_sub_tracing {
126   my ($self) = @_;
127   $self->{"trace_subs"} = 1;
128 }
129
130 sub disable_sub_tracing {
131   my ($self) = @_;
132   $self->{"trace_subs"} = 1;
133 }
134
135 sub _write {
136   my ($self, $prefix, $message) = @_;
137   my $date = strftime("%Y-%m-%d %H:%M:%S $$ ${prefix}: ", localtime(time()));
138   local *FILE;
139
140   chomp($message);
141
142   if ((FILE_TARGET == $self->{"target"}) &&
143       open(FILE, ">>" . $self->{"file"})) {
144     print(FILE "${date}${message}\n");
145     close(FILE);
146
147   } elsif (STDERR_TARGET == $self->{"target"}) {
148     print(STDERR "${date}${message}\n");
149   }
150 }
151
152 1;