summaryrefslogtreecommitdiff
path: root/FS/FS/Log.pm
blob: ac218a019b2a0ac3ad4e93110efa29210ce5cb8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package FS::Log;

use base 'Log::Dispatch';
use FS::Record qw(qsearch qsearchs);
use FS::Conf;
use FS::Log::Output;
use FS::log;
use vars qw(@STACK %LEVELS);

# override the stringification of @_ with something more sensible.
BEGIN {
  # subset of Log::Dispatch levels
  %LEVELS = (
    0 => 'debug',
    1 => 'info',
    3 => 'warning',
    4 => 'error',
    5 => 'critical'
  );

  foreach my $l (values %LEVELS) {
    my $sub = sub {
      my $self = shift;
      $self->log( level => $l, message => @_ );
    };
    no strict 'refs';
    *{$l} = $sub;
  }
}

=head1 NAME

FS::Log - Freeside event log

=head1 SYNOPSIS

use FS::Log;

sub do_something {
  my $log = FS::Log->new('do_something'); # set log context to 'do_something'

  ...
  if ( $error ) {
    $log->error('something is wrong: '.$error);
    return $error;
  }
  # at this scope exit, do_something is removed from context
}

=head1 DESCRIPTION

FS::Log provides an interface for logging errors and profiling information
to the database.  FS::Log inherits from L<Log::Dispatch>.

=head1 CLASS METHODS

=over 4

=item new CONTEXT

Constructs and returns a log handle.  CONTEXT must be a known context tag
indicating what activity is going on, such as the name of the function or
script that is executing.

Log context is a stack, and each element is removed from the stack when it
goes out of scope.  So don't keep log handles in persistent places (i.e. 
package variables or class-scoped lexicals).

=cut

sub new {
  my $class = shift;
  my $context = shift;

  my $min_level = FS::Conf->new->config('event_log_level') || 'info';

  my $self = $class->SUPER::new(
    outputs => [ [ '+FS::Log::Output', min_level => $min_level ] ],
  );
  $self->{'index'} = scalar(@STACK);
  push @STACK, $context;
  return $self;
}

=item context

Returns the current context stack.

=cut

sub context { @STACK };

=item log LEVEL, MESSAGE[, OPTIONS ]

Like L<Log::Dispatch::log>, but OPTIONS may include:

- agentnum
- object (an <FS::Record> object to reference in this log message)
- tablename and tablenum (an alternate way of specifying 'object')

=cut

# inherited

sub DESTROY {
  my $self = shift;
  splice(@STACK, $self->{'index'}, 1); # delete the stack entry
}

=item levelnums

Subroutine.  Returns ordered list of level nums.

=cut

sub levelnums {
  sort keys %LEVELS;
}

=item levelmap

Subroutine.  Returns ordered map of level num => level name.

=cut

sub levelmap {
  map { $_ => $LEVELS{$_} } levelnums;
}

=back

=head1 BUGS

Not yet used universally; being phased in over time.

Not well documented.  Should document the error levels we're using (debug,
info, warning, error, critical) and the methods to log them.

=head1 SEE ALSO

L<Log::Dispatch>

=cut

1;