~ubuntu-branches/ubuntu/natty/otrs2/natty-updates

« back to all changes in this revision

Viewing changes to Kernel/Modules/SystemStats.pm

  • Committer: Package Import Robot
  • Author(s): Torsten Werner
  • Date: 2007-04-14 17:58:55 UTC
  • mto: (20.1.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 6.
  • Revision ID: package-import@ubuntu.com-20070414175855-9ne0w01yu1q44ch0
Tags: upstream-2.1.7
ImportĀ upstreamĀ versionĀ 2.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# --
2
 
# Kernel/Modules/SystemStats.pm - show stats of otrs
3
 
# Copyright (C) 2001-2005 Martin Edenhofer <martin+code@otrs.org>
4
 
# --
5
 
# $Id: SystemStats.pm,v 1.24 2005/08/26 15:55:29 martin Exp $
6
 
# --
7
 
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
8
 
# the enclosed file COPYING for license information (GPL). If you
9
 
# did not receive this file, see http://www.gnu.org/licenses/gpl.txt.
10
 
# --
11
 
 
12
 
package Kernel::Modules::SystemStats;
13
 
 
14
 
use strict;
15
 
 
16
 
use vars qw($VERSION);
17
 
$VERSION = '$Revision: 1.24 $ ';
18
 
$VERSION =~ s/^\$.*:\W(.*)\W.+?$/$1/;
19
 
 
20
 
# --
21
 
sub new {
22
 
    my $Type = shift;
23
 
    my %Param = @_;
24
 
 
25
 
    # allocate new hash for object
26
 
    my $Self = {};
27
 
    bless ($Self, $Type);
28
 
 
29
 
    # get common opjects
30
 
    foreach (keys %Param) {
31
 
        $Self->{$_} = $Param{$_};
32
 
    }
33
 
 
34
 
    # check all needed objects
35
 
    foreach (qw(ParamObject DBObject LayoutObject ConfigObject LogObject UserObject)) {
36
 
        die "Got no $_" if (!$Self->{$_});
37
 
    }
38
 
 
39
 
    # if we need to do a fultext search on an external mirror database
40
 
    if ($Self->{ConfigObject}->Get('Stats::DB::DSN')) {
41
 
        my $ExtraDatabaseObject = Kernel::System::DB->new(
42
 
            LogObject => $Param{LogObject},
43
 
            ConfigObject => $Param{ConfigObject},
44
 
            DatabaseDSN => $Self->{ConfigObject}->Get('Stats::DB::DSN'),
45
 
            DatabaseUser => $Self->{ConfigObject}->Get('Stats::DB::User'),
46
 
            DatabasePw => $Self->{ConfigObject}->Get('Stats::DB::Password'),
47
 
        ) || die $DBI::errstr;
48
 
        $Self->{TicketObject} = Kernel::System::Ticket->new(
49
 
            %Param,
50
 
            DBObject => $ExtraDatabaseObject,
51
 
        );
52
 
    }
53
 
 
54
 
    return $Self;
55
 
}
56
 
# --
57
 
sub Run {
58
 
    my $Self = shift;
59
 
    my %Param = @_;
60
 
    if ($Self->{Subaction} eq '' || !$Self->{Subaction}) {
61
 
        # print page ...
62
 
        my $Output = $Self->{LayoutObject}->Header();
63
 
        $Output .= $Self->{LayoutObject}->NavigationBar();
64
 
 
65
 
        my %Config = %{$Self->{ConfigObject}->Get('SystemStatsMap')};
66
 
        foreach my $Stats (sort keys %Config) {
67
 
          if ($Self->{MainObject}->Require($Config{$Stats}->{Module})) {
68
 
            my $StatsModule = $Config{$Stats}->{Module}->new(%{$Self});
69
 
            my $ParamString = '';
70
 
            my %OutputFormat = ();
71
 
            foreach (@{$Config{$Stats}->{Output}}) {
72
 
                $OutputFormat{$_} = $_;
73
 
            }
74
 
            $Param{OutputFormat} = $Self->{LayoutObject}->OptionStrgHashRef(
75
 
                    Data => \%OutputFormat,
76
 
                    Name => 'Format',
77
 
                    SelectedID => $Config{$Stats}->{OutputDefault} || '',
78
 
                );
79
 
            $Self->{LayoutObject}->Block(
80
 
                Name => 'Item',
81
 
                Data => {
82
 
                    %Param,
83
 
                    %{$Config{$Stats}},
84
 
                    Param => $ParamString,
85
 
                },
86
 
            );
87
 
            my @Params = $StatsModule->Param();
88
 
            foreach my $ParamItem (@Params) {
89
 
                $Self->{LayoutObject}->Block(
90
 
                    Name => 'ItemParam',
91
 
                    Data => {
92
 
                        Param => $ParamItem->{Frontend},
93
 
                        Field => $Self->{LayoutObject}->OptionStrgHashRef(
94
 
                            Data => $ParamItem->{Data},
95
 
                            Name => $ParamItem->{Name},
96
 
                            SelectedID => $Config{$Stats}->{"$ParamItem->{Name}Default"} || $ParamItem->{SelectedID} || '',
97
 
                            Multiple => $ParamItem->{Multiple} || 0,
98
 
                            Size => $ParamItem->{Size} || '',
99
 
                        ),
100
 
                        %Param,
101
 
                        %{$Config{$Stats}},
102
 
                    },
103
 
                );
104
 
            }
105
 
          }
106
 
          else {
107
 
              return $Self->{LayoutObject}->FatalError();
108
 
          }
109
 
        }
110
 
        # create output
111
 
        $Output .= $Self->{LayoutObject}->Output(
112
 
            TemplateFile => 'SystemStats',
113
 
            Data => \%Param,
114
 
        );
115
 
        $Output .= $Self->{LayoutObject}->Footer();
116
 
        return $Output;
117
 
    }
118
 
    elsif ($Self->{Subaction} eq 'Output') {
119
 
        my $Module = $Self->{ParamObject}->GetParam(Param => 'Module');
120
 
        my $Format = $Self->{ParamObject}->GetParam(Param => 'Format');
121
 
        my %Config = %{$Self->{ConfigObject}->Get('SystemStatsMap')};
122
 
        my %ConfigItem = ();
123
 
        foreach my $Stats (sort keys %Config) {
124
 
            if ($Config{$Stats}->{Module} eq $Module) {
125
 
                %ConfigItem = %{$Config{$Stats}};
126
 
            }
127
 
        }
128
 
        if (!%ConfigItem) {
129
 
            return $Self->{LayoutObject}->ErrorScreen(
130
 
                Message => "No Config found for '$Module'!",
131
 
                Comment => 'Please contact your admin'
132
 
            );
133
 
        }
134
 
        if ($Self->{MainObject}->Require($Module)) {
135
 
            my %GetParam = ();
136
 
            my $StatsModule = $Module->new(%{$Self});
137
 
            my @Params = $StatsModule->Param();
138
 
            foreach my $ParamItem (@Params) {
139
 
                if (!$ParamItem->{Multiple}) {
140
 
                    $GetParam{$ParamItem->{Name}} = $Self->{ParamObject}->GetParam(
141
 
                        Param => $ParamItem->{Name},
142
 
                    );
143
 
                }
144
 
                else {
145
 
                    $GetParam{$ParamItem->{Name}} = [$Self->{ParamObject}->GetArray(
146
 
                        Param => $ParamItem->{Name},
147
 
                    )];
148
 
                }
149
 
            }
150
 
            # get data
151
 
            my @Data = ();
152
 
            # use result cache if configured
153
 
            if ($ConfigItem{UseResultCache}) {
154
 
                @Data = $Self->ReadResultCache(
155
 
                    GetParam => \%GetParam,
156
 
                    Config => \%ConfigItem,
157
 
                );
158
 
            }
159
 
            # try to get data if noting is there
160
 
            if (!@Data) {
161
 
                @Data = $StatsModule->Run(%GetParam,
162
 
                    Format => $Format,
163
 
                    Module => $Module,
164
 
                );
165
 
                $Self->WriteResultCache(
166
 
                    GetParam => \%GetParam,
167
 
                    Config => \%ConfigItem,
168
 
                    Data => \@Data,
169
 
                );
170
 
            }
171
 
            my $TitleArrayRef = shift (@Data);
172
 
            my $Title = $TitleArrayRef->[0];
173
 
            my $HeadArrayRef = shift (@Data);
174
 
            if ($Format !~ /^Graph/) {
175
 
                # add sum y
176
 
                if ($ConfigItem{SumRow}) {
177
 
                    push (@{$HeadArrayRef}, 'Sum');
178
 
                    foreach my $Col (@Data) {
179
 
                        my $Sum = 0;
180
 
                        foreach (@{$Col}) {
181
 
                            if ($_ =~ /^[0-9]{1,7}$/) {
182
 
                                $Sum = $Sum + $_;
183
 
                            }
184
 
                        }
185
 
                        push (@{$Col}, $Sum);
186
 
                    }
187
 
                }
188
 
                # add sum x
189
 
                if ($ConfigItem{SumCol}) {
190
 
                    my @R1 = ();
191
 
                    foreach my $Col (@Data) {
192
 
                        my $Count = -1;
193
 
                        foreach my $Dig (@{$Col}) {
194
 
                            $Count++;
195
 
                            if ($Dig =~ /^[0-9]{1,7}$/) {
196
 
                                if ($R1[$Count]) {
197
 
                                    $R1[$Count] = $R1[$Count] + $Dig;
198
 
                                }
199
 
                                else {
200
 
                                    $R1[$Count] = $Dig;
201
 
                                }
202
 
                            }
203
 
                        }
204
 
                    }
205
 
                    # add sum
206
 
                    if (!defined($R1[0])) {
207
 
                        $R1[0] = 'Sum';
208
 
                    }
209
 
                    push (@Data, \@R1);
210
 
                }
211
 
            }
212
 
            # generate output
213
 
            if ($Format eq 'CSV') {
214
 
                $ConfigItem{Module} =~ s/^.*::(.+?)$/$1/;
215
 
                my $Output = "$ConfigItem{Name}: $Title\n";
216
 
                $Output .= $Self->{LayoutObject}->OutputCSV(
217
 
                    Head => $HeadArrayRef,
218
 
                    Data => \@Data,
219
 
                );
220
 
                # return csv to download
221
 
                my ($s,$m,$h, $D,$M,$Y) = $Self->{TimeObject}->SystemTime2Date(
222
 
                    SystemTime => $Self->{TimeObject}->SystemTime(),
223
 
                );
224
 
                $M = sprintf("%02d", $M);
225
 
                $D = sprintf("%02d", $D);
226
 
                $h = sprintf("%02d", $h);
227
 
                $m = sprintf("%02d", $m);
228
 
                return $Self->{LayoutObject}->Attachment(
229
 
                    Filename => "$ConfigItem{Module}"."_"."$Y-$M-$D"."_"."$h-$m.csv",
230
 
                    ContentType => "text/csv",
231
 
                    Content => $Output,
232
 
                );
233
 
            }
234
 
            # gd output
235
 
            elsif ($Format =~ /^Graph(|Line|Bars|Pie)$/) {
236
 
                # check @Data
237
 
                if (!@Data) {
238
 
                    my $Output = $Self->{LayoutObject}->Header();
239
 
                    $Output .= $Self->{LayoutObject}->Warning(
240
 
                        Message => 'No data for this time selection available!',
241
 
                        Comment => 'Please contact your admin'
242
 
                    );
243
 
                    $Output .= $Self->{LayoutObject}->Footer();
244
 
                    return $Output;
245
 
                }
246
 
                my $GDBackend = '';
247
 
                if ($1 eq 'Bars') {
248
 
                    $GDBackend = 'GD::Graph::bars';
249
 
                }
250
 
                elsif ($1 eq 'Pie') {
251
 
                    $GDBackend = 'GD::Graph::pie';
252
 
                }
253
 
                else {
254
 
                    $GDBackend = 'GD::Graph::lines';
255
 
                }
256
 
                # load gd modules
257
 
                foreach my $Module ('GD', 'GD::Graph', $GDBackend) {
258
 
                    if (!$Self->{MainObject}->Require($Module)) {
259
 
                        return $Self->{LayoutObject}->FatalError();
260
 
                    }
261
 
                }
262
 
                # remove first y/x position
263
 
                my $XLable = shift (@{$HeadArrayRef});
264
 
                # get first col for legend
265
 
                my @YLine = ();
266
 
                foreach my $Tmp (@Data) {
267
 
                    push (@YLine, $Tmp->[0]);
268
 
                    shift (@{$Tmp});
269
 
                }
270
 
                # build plot data
271
 
                my @PData = ($HeadArrayRef, @Data);
272
 
                my ($XSize, $YSize) = split(/x/, $GetParam{GraphSize});
273
 
                my $graph = $GDBackend->new($XSize || 550, $YSize || 350);
274
 
                $graph->set(
275
 
                    x_label            => $XLable,
276
 
#                    y_label            => 'YLable',
277
 
                    title              => "$ConfigItem{Name}: $Title",
278
 
#               y_max_value       => 20,
279
 
#            y_tick_number     => 16,
280
 
#               y_label_skip      => 4,
281
 
#            x_tick_number     => 8,
282
 
                    t_margin            => 10,
283
 
                    b_margin            => 10,
284
 
                    l_margin            => 10,
285
 
                    r_margin            => 20,
286
 
                    bgclr               => 'white',
287
 
                    transparent         => 0,
288
 
                    interlaced          => 1,
289
 
                    fgclr               => 'black',
290
 
                    boxclr              => 'white',
291
 
                    accentclr           => 'black',
292
 
                    shadowclr           => 'black',
293
 
                    legendclr           => 'black',
294
 
                    textclr             => 'black',
295
 
                    dclrs => [ qw(red green blue yellow black purple orange pink marine cyan lgray lblue lyellow lgreen lred lpurple lorange lbrown) ],
296
 
                    x_tick_offset       => 0,
297
 
                    x_label_position    => 1/2, y_label_position => 1/2,
298
 
                    x_labels_vertical   => 31,
299
 
 
300
 
                    line_width          => 1,
301
 
                    legend_placement    => 'BC', legend_spacing => 4,
302
 
                    legend_marker_width => 12, legend_marker_height => 8,
303
 
                );
304
 
                # set legend (y-line)
305
 
                if ($Format ne 'GraphPie') {
306
 
                    $graph->set_legend(@YLine);
307
 
                }
308
 
                # return csv to download
309
 
                my ($s,$m,$h, $D,$M,$Y) = $Self->{TimeObject}->SystemTime2Date(
310
 
                    SystemTime => $Self->{TimeObject}->SystemTime(),
311
 
                );
312
 
                $M = sprintf("%02d", $M);
313
 
                $D = sprintf("%02d", $D);
314
 
                $h = sprintf("%02d", $h);
315
 
                $m = sprintf("%02d", $m);
316
 
                $ConfigItem{Module} =~ s/^.*::(.+?)$/$1/;
317
 
                # plot graph
318
 
                my $Ext = '';
319
 
                if (!$graph->can('png')) {
320
 
                    $Ext = 'png';
321
 
                }
322
 
                else {
323
 
                    $Ext = $graph->export_format;
324
 
                    $Self->{LogObject}->Log(
325
 
                        Priority => 'notice',
326
 
                        Message => "Can't write png! Write: $Ext",
327
 
                    );
328
 
                }
329
 
                # return image to bowser
330
 
                return $Self->{LayoutObject}->Attachment(
331
 
                    Filename => "$ConfigItem{Module}"."_"."$Y-$M-$D"."_"."$h-$m.$Ext",
332
 
                    ContentType => "image/$Ext",
333
 
                    Content => $graph->plot(\@PData)->$Ext(),
334
 
                    Type => 'inline',
335
 
                );
336
 
            }
337
 
            # print output
338
 
            else {
339
 
                my $Output = $Self->{LayoutObject}->PrintHeader(Value => $ConfigItem{Name});
340
 
                $Output .= "$ConfigItem{Name}: $Title";
341
 
                $Output .= $Self->{LayoutObject}->OutputHTMLTable(
342
 
                    Head => $HeadArrayRef,
343
 
                    Data => \@Data,
344
 
                );
345
 
 
346
 
                $Output .= $Self->{LayoutObject}->PrintFooter();
347
 
                return $Output;
348
 
            }
349
 
        }
350
 
        else {
351
 
            return $Self->{LayoutObject}->FatalError();
352
 
        }
353
 
    }
354
 
    else {
355
 
        $Self->{LogObject}->Log(
356
 
            Message => 'No Subaction!!',
357
 
            Comment => 'Please contact your admin'
358
 
        );
359
 
        return $Self->{LayoutObject}->ErrorScreen(
360
 
            Message => 'No Subaction!!',
361
 
            Comment => 'Please contact your admin'
362
 
        );
363
 
    }
364
 
}
365
 
# --
366
 
sub WriteResultCache {
367
 
    my $Self = shift;
368
 
    my %Param = @_;
369
 
    my %GetParam = %{$Param{GetParam}};
370
 
    my %Config = %{$Param{Config}};
371
 
    my @Data = @{$Param{Data}};
372
 
    my $Cache = 0;
373
 
    # check if we should cache this result
374
 
    my ($s,$m,$h, $D,$M,$Y) = $Self->{TimeObject}->SystemTime2Date(
375
 
        SystemTime => $Self->{TimeObject}->SystemTime(),
376
 
    );
377
 
    if ($GetParam{Year} && $GetParam{Month}) {
378
 
        if ($Y > $GetParam{Year}) {
379
 
            $Cache = 1;
380
 
        }
381
 
        elsif ($GetParam{Year} == $Y && $GetParam{Month} <= $M) {
382
 
            if ($GetParam{Month} < $M) {
383
 
                $Cache = 1;
384
 
            }
385
 
            if ($GetParam{Month} == $M && $GetParam{Day} && $GetParam{Day} < $D) {
386
 
                $Cache = 1;
387
 
            }
388
 
        }
389
 
    }
390
 
    # format month and day params
391
 
    foreach (qw(Month Day)) {
392
 
        $GetParam{$_} = sprintf("%02d", $GetParam{$_}) if ($GetParam{$_});
393
 
    }
394
 
    # write cache file
395
 
    if ($Cache) {
396
 
        my $Path = $Self->{ConfigObject}->Get('TempDir');
397
 
        my $File = $Config{Module};
398
 
        $File =~ s/::/-/g;
399
 
        if ($GetParam{Year}) {
400
 
            $File .= "-$GetParam{Year}";
401
 
        }
402
 
        if ($GetParam{Month}) {
403
 
            $File .= "-$GetParam{Month}";
404
 
        }
405
 
        if ($GetParam{Day}) {
406
 
            $File .= "-$GetParam{Day}";
407
 
        }
408
 
        $File .= ".cache";
409
 
        # write cache file
410
 
        if (open (DATA, "> $Path/$File")) {
411
 
            foreach my $Row (@Data) {
412
 
                foreach (@{$Row}) {
413
 
                    print DATA "$_;;";
414
 
                }
415
 
                print DATA "\n";
416
 
            }
417
 
            close (DATA);
418
 
        }
419
 
        else {
420
 
            $Self->{LogObject}->Log(
421
 
                Priority => 'error',
422
 
                Message => "Can't write: $Path/$File: $!",
423
 
            );
424
 
        }
425
 
    }
426
 
    return $Cache;
427
 
}
428
 
# --
429
 
sub ReadResultCache {
430
 
    my $Self = shift;
431
 
    my %Param = @_;
432
 
    my %GetParam = %{$Param{GetParam}};
433
 
    my %Config = %{$Param{Config}};
434
 
    my @Data = ();
435
 
    # format month and day params
436
 
    foreach (qw(Month Day)) {
437
 
        $GetParam{$_} = sprintf("%02d", $GetParam{$_}) if ($GetParam{$_});
438
 
    }
439
 
    # read cache file
440
 
    my $Path = $Self->{ConfigObject}->Get('TempDir');
441
 
    my $File = $Config{Module};
442
 
    $File =~ s/::/-/g;
443
 
    if ($GetParam{Year}) {
444
 
        $File .= "-$GetParam{Year}";
445
 
    }
446
 
    if ($GetParam{Month}) {
447
 
        $File .= "-$GetParam{Month}";
448
 
    }
449
 
    if ($GetParam{Day}) {
450
 
        $File .= "-$GetParam{Day}";
451
 
    }
452
 
    $File .= ".cache";
453
 
    if (open (DATA, "< $Path/$File")) {
454
 
        while (<DATA>) {
455
 
            my @Row = split(/;;/, $_);
456
 
            push (@Data, \@Row);
457
 
        }
458
 
        close (DATA);
459
 
    }
460
 
    else {
461
 
        $Self->{LogObject}->Log(
462
 
            Priority => 'error',
463
 
            Message => "Can't open: $Path/$File: $!",
464
 
        );
465
 
    }
466
 
    return @Data;
467
 
}
468
 
# --
469
 
1;