Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / newznab / nn_ @ ed77c82d

Historique | Voir | Annoter | Télécharger (9,36 ko)

1
#!/usr/bin/perl
2

    
3
=encoding utf8
4

    
5
=head1 NAME
6

    
7
nn_ - Munin plugin to display misc newznab stats.
8

    
9
=head1 CONFIGURATION
10

    
11
This script is used to generate data for several graphs. To generate
12
data for one specific graph, you need to create a symbolic link with a
13
name like nn_<GRAPH> to this script.
14

    
15
To get a graph over numbers of users use nn_users
16
=head1 APPLICABLE SYSTEMS
17

    
18
Any MySQL platform, tested by the author on MySQL 5.1.29 and 5.0.51
19

    
20
=head1 CONFIGURATION
21

    
22
This script is used to generate data for several graphs. To generate
23
data for one specific graph, you need to create a symbolic link with a
24
name like nn_<GRAPH> to this script.
25

    
26
connection parameters - use this in your plugin configuration file.
27

    
28
[nn_*]
29
env.mysqlconnection DBI:mysql:<yourdatabase>;host=127.0.0.1;port=3306
30
env.mysqluser <user>
31
env.mysqlpassword <password>
32

    
33

    
34
=head1 DEPENDENCIES
35

    
36
=over
37

    
38
=item DBD::mysql
39

    
40
=back
41

    
42
=head1 THANKS
43
A special thanks to Kjell-Magne Øierud for the mysql_ plugin in munin which
44
gave me the inspiration and reusable code to create this plugin.
45

    
46
=head1 LICENSE
47

    
48
Copyright (C) 2012 Jan Astrup (cryzeck@synIRC)
49

    
50
This program is free software; you can redistribute it and/or modify
51
it under the terms of the GNU General Public License as published by
52
the Free Software Foundation; version 2 dated June, 1991.
53

    
54
This program is distributed in the hope that it will be useful, but
55
WITHOUT ANY WARRANTY; without even the implied warranty of
56
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
57
General Public License for more details.
58

    
59
You should have received a copy of the GNU General Public License
60
along with this program; if not, write to the Free Software
61
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
62
USA.
63

    
64
=cut
65

    
66
use warnings;
67
use strict;
68
use utf8;
69

    
70
use DBI;
71
use Data::Dumper;
72
use File::Basename;
73

    
74
use Munin::Plugin;
75

    
76
#-- CONFIG --#
77

    
78
my %config = (
79
    'dsn'        => $ENV{'mysqlconnection'} || 'dbi:mysql:newznab',
80
    'user'       => $ENV{'mysqluser'}       || 'test1',
81
    'password'   => $ENV{'mysqlpassword'}   || 'test',
82
);
83

    
84
my %defaults = (
85
	global_attrs => {
86
		args   => '--base 1000 -l 0',
87
		scale  => 'no',
88
	},
89
	data_source_attrs => {
90
		draw  => 'AREA',
91
	},
92
);
93

    
94
my %graphs = ();
95

    
96
$graphs{releases} = {
97
	config => {
98
		global_attrs => {
99
			title 	=> 'Releases',
100
			vlabel	=> 'Releases',
101
		},
102
		data_source_attrs => {
103
			min   => '0',
104
			
105
		},
106
	},
107
	data_sources => [
108
		{name => 'releases',		label => 'Releases'},
109
	],
110
};
111
$graphs{category} = {
112
	config => {
113
		global_attrs => {
114
			title 	=> 'Releases by category',
115
			vlabel	=> 'Releases by category',
116
		},
117
		data_source_attrs => {
118
			min   => '0',
119
			draw  => 'LINE2',
120
			type  => 'GAUGE',
121
		},
122
	},
123
	data_sources => [
124
		{name => '1000', label => 'Console'},
125
		{name => '1010', label => 'Console - NDS'},
126
		{name => '1020', label => 'Console - PSP'},
127
		{name => '1030', label => 'Console - Wii'},
128
		{name => '1040', label => 'Console - Xbox'},
129
		{name => '1050', label => 'Console - Xbox 360'},
130
		{name => '1060', label => 'Console - WiiWare/VC'},
131
		{name => '1070', label => 'Console - XBOX 360 DLC'},
132
		{name => '1080', label => 'Console - PS3'},
133
		{name => '2000', label => 'Movies'},
134
		{name => '2010', label => 'Movies - Foreign'},
135
		{name => '2020', label => 'Movies - Other'},
136
		{name => '2030', label => 'Movies - SD'},
137
		{name => '2040', label => 'Movies - HD'},
138
		{name => '2050', label => 'Movies - BluRay'},
139
		{name => '2060', label => 'Movies - 3D'},
140
		{name => '3000', label => 'Audio'},
141
		{name => '3010', label => 'Audio - MP3'},
142
		{name => '3020', label => 'Audio - Video'},
143
		{name => '3030', label => 'Audio - Audiobook'},
144
		{name => '3040', label => 'Audio - Lossless'},
145
		{name => '4000', label => 'PC'},
146
		{name => '4010', label => 'PC - 0day'},
147
		{name => '4020', label => 'PC - ISO'},
148
		{name => '4030', label => 'PC - Mac'},
149
		{name => '4040', label => 'PC - Mobile-Other'},
150
		{name => '4050', label => 'PC - Games'},
151
		{name => '4060', label => 'PC - Mobile-iOS'},
152
		{name => '4070', label => 'PC - Mobile-Android'},
153
		{name => '5000', label => 'TV'},
154
		{name => '5020', label => 'TV - Foreign'},
155
		{name => '5030', label => 'TV - SD'},
156
		{name => '5040', label => 'TV - HD'},
157
		{name => '5050', label => 'TV - Other'},
158
		{name => '5060', label => 'TV - Sport'},
159
		{name => '5070', label => 'TV - Anime'},
160
		{name => '5080', label => 'TV - Documentary'},
161
		{name => '6000', label => 'XXX'},
162
		{name => '6010', label => 'XXX - DVD'},
163
		{name => '6020', label => 'XXX - WMV'},
164
		{name => '6030', label => 'XXX - XviD'},
165
		{name => '6040', label => 'XXX - x264'},
166
		{name => '6050', label => 'XXX - Pack'},
167
		{name => '6060', label => 'XXX - ImgSet'},
168
		{name => '7000', label => 'Other'},
169
		{name => '7010', label => 'Other - Magazines'},
170
		{name => '7020', label => 'Other - Ebook'},
171
		{name => '7030', label => 'Other - Comics'},
172
		{name => '8010', label => 'Other - Misc'},
173
		{name => '7900', label => 'Unknown'},
174
	],
175
};
176

    
177
$graphs{api} = {
178
	config => {
179
		global_attrs => {
180
			title 	=> 'API Requests / Downloads',
181
			vlabel	=> 'API / DOWNLOAD',
182
		},
183
		data_source_attrs => {
184
			min   	=> '0',
185
			draw	=> 'LINE1',
186
			type	=> 'GAUGE',
187
		},
188
	},
189
	data_sources => [
190
		{name => 'request',		label => 'API Requests'},
191
		{name => 'download',		label => 'Downloads'},
192
	],
193
};
194

    
195
$graphs{users} = {
196
	config => {
197
		global_attrs => {
198
			title 	=> 'Registered Users',
199
			vlabel	=> 'Usercount',
200
		},
201
		data_source_attrs => {
202
			min   => '0',
203
		},
204
	},
205
	data_sources => [
206
		{name => 'users',		label => 'Users'},
207
	],
208
};
209
our $data;
210
sub config {
211
    my $graph_name = shift;
212
    die 'Unknown graph ' . ($graph_name ? $graph_name : '')
213
	unless $graphs{$graph_name};
214

    
215
    my $graph = $graphs{$graph_name};
216

    
217
    my %conf = (%{$defaults{global_attrs}}, %{$graph->{config}{global_attrs}});
218
    while (my ($k, $v) = each %conf) {
219
	print "graph_$k $v\n";
220
    }
221
    print "graph_category search\n";
222

    
223
    my $i = 0;
224
    for my $ds (@{$graph->{data_sources}}) {
225
	my %ds_spec = (
226
	    %{$defaults{data_source_attrs}},
227
	    %{$graph->{config}{data_source_attrs}},
228
	    %$ds,
229
	);
230
	while (my ($k, $v) = each %ds_spec) {
231
	    # 'name' is only used internally in this script, not
232
	    # understood by munin.
233
	    next if ($k eq 'name');
234

    
235
	    if ($k eq 'draw' && $v eq 'AREASTACK') {
236
		printf("%s.%s %s\n",
237
		       clean_fieldname($ds->{label}), $k, ($i ? 'STACK' : 'AREA'));
238
	    }
239
	    else {
240
		printf("%s.%s %s\n", clean_fieldname($ds->{label}), $k, $v);
241
	    }
242
	    $i++;
243
	}
244
    }
245

    
246
    return 0;
247
}
248

    
249
sub main {
250
	my $graph = substr(basename($0), length('nn_'));
251
	my $command = $ARGV[0] || 'show';
252

    
253
	my %commands = (
254
		'config'	=>	\&config,
255
		'show'		=>	\&show,
256
	);
257
	
258
	die "Unknown command: $command" unless exists $commands{$command};
259
	return $commands{$command}->($graph);
260
}
261

    
262
sub show {
263
	my $graph_name = shift;
264
	die 'Unknown graph ' . ($graph_name ? $graph_name : '')
265
		unless $graphs{$graph_name};
266

    
267
	my $graph = $graphs{$graph_name};
268
	run_queries($graph_name);	
269
	for my $ds (@{$graph->{data_sources}}) {
270
		printf "%s.value %s\n", clean_fieldname($ds->{label}), ($data->{$ds->{name}} ? $data->{$ds->{name}} : '0');
271
	}
272
	return 0;
273
}
274

    
275
sub db_connect {
276
	my $dsn = "$config{dsn};mysql_connect_timeout=5";
277

    
278
	return DBI->connect($dsn, $config{user}, $config{password}, {
279
		RaiseError       => 1,
280
		PrintError       => 0,
281
		FetchHashKeyName => 'NAME_lc',
282
	});
283

    
284
}
285

    
286
sub run_queries {
287
	my $updater = shift;
288
	$data = {};
289
	my $dbh = db_connect();
290
	my %updaters = (
291
		'releases'			=> \&update_releases,
292
		'users'				=> \&update_users,
293
		'api'				=> \&update_requests,
294
		'category'			=> \&update_category,
295
	);
296
	die "Unknown updater: $updater" unless exists $updaters{$updater};
297
	$updaters{$updater}->($dbh);
298
}
299

    
300
sub update_requests {
301
	my ($dbh) = @_;                                                                                         
302
	my %queries = (
303
		request => 'select count(*) as requests from userrequests where timestamp > now() - INTERVAL 5 MINUTE;',                 
304
		download => 'select count(*) as downloads from userdownloads where timestamp > now() - INTERVAL 5 MINUTE;',                                              
305
	); 
306
	for my $name ( qw(request download) ) {
307
		my $query = $queries{$name};                                                                              
308
		my $sth = $dbh->prepare($query);                                                                
309
		$sth->execute();                                                                                
310
		while (my $row = $sth->fetch) {                                                                 
311
			$data->{$name} = $row->[0];
312
		}
313
		$sth->finish();                                                                                 
314
	}       
315
}
316
      
317
sub update_category {
318
	my ($dbh) = @_;
319
	my $sth = $dbh->prepare('select count(*) as releases, category.title, category.id from releases LEFT JOIN category ON releases.categoryID = category.ID group by releases.categoryID');
320
	$sth->execute();
321
	if ($@) { die $@; }
322
	while (my $row = $sth->fetch) {
323
	$data->{$row->[2]} = $row->[0];
324
	}
325
	
326
}
327
sub update_releases {
328
	my ($dbh) = @_;
329
	my $sth = $dbh->prepare('SELECT count(*) as releases from releases');
330
	eval {
331
		$sth->execute();
332
	};
333
	if ($@) { die $@; }
334
	my $row = $sth->fetchrow_hashref();	
335
	$data->{releases} = $row->{'releases'};
336
	$sth->finish();
337
}
338

    
339
sub update_users {
340
	my ($dbh) = @_;
341
	my $sth = $dbh->prepare('SELECT count(*) as users from users');
342
	eval {
343
		$sth->execute();
344
	};
345
	if ($@) { die $@; }
346
	my $row = $sth->fetchrow_hashref();	
347
	$data->{users} = $row->{'users'};
348
	$sth->finish();
349
}
350

    
351
exit main() unless caller;
352

    
353

    
354
1;