├── .gitignore ├── config.json.template ├── README.md ├── LICENSE └── munin-irc-stats.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | profile 3 | node_modules 4 | -------------------------------------------------------------------------------- /config.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "server": "irc.freenode.net", 3 | "port": 6667, 4 | "nick": "StatsBot", 5 | "username": "StatsBot", 6 | "serverPassword": "" 7 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Munin IRC Stats 2 | =============== 3 | 4 | A plugin for Munin which graphs the number of connected clients and channels on an 5 | IRC server. 6 | 7 | Configure the IRC server settings in config.json, and symlink as `/etc/munin/plugins/irc` 8 | and Munin will begin drawing graphs. 9 | 10 | Sample config: 11 | 12 | { 13 | "server": "irc.freenode.net", 14 | "port": 6667, 15 | "nick": "munin", 16 | "username": "munin", 17 | "serverPassword": "" 18 | } 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD License 2 | ----------- 3 | 4 | Copyright (c) 2012 by Aaron Parecki. All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, 7 | are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, 10 | this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of Django nor the names of its contributors may be used 17 | to endorse or promote products derived from this software without 18 | specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 24 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /munin-irc-stats.js: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/node 2 | 3 | process.chdir(__dirname); 4 | 5 | if(process.argv[2] == 'config') { 6 | console.log("graph_category irc"); 7 | console.log("graph_title ircd status"); 8 | console.log("graph_order clients channels"); 9 | console.log("graph_args -l 0"); 10 | console.log("clients.label clients"); 11 | console.log("clients.draw LINE2"); 12 | console.log("channels.label channels"); 13 | console.log("channels.draw LINE2"); 14 | 15 | process.exit(); 16 | } 17 | 18 | var irc = require('irc'); 19 | var fs = require('fs'); 20 | 21 | var config = JSON.parse(fs.readFileSync("config.json", 'utf8')); 22 | 23 | var options = { 24 | userName: config.username, 25 | port: config.port, 26 | channels: [] 27 | }; 28 | if(config.serverPassword) { 29 | options.password = config.serverPassword; 30 | } 31 | 32 | var client = new irc.Client(config.server, config.nick, options); 33 | 34 | var collected = []; 35 | 36 | client.on('raw', function(msg){ 37 | var line; 38 | 39 | line = msg.args.join(' '); 40 | // console.log(line); 41 | 42 | if(match=line.match(/There are (\d+) users and (\d+) invisible on (\d+) servers/)) { 43 | console.log("clients.value " + (parseInt(match[1])+parseInt(match[2]))); 44 | collected.push('clients'); 45 | } 46 | if(match=line.match(/(\d+) channels formed/)) { 47 | console.log("channels.value " + match[1]); 48 | collected.push('channels'); 49 | } 50 | 51 | if(collected.length == 2) { 52 | process.exit(); 53 | } 54 | }); 55 | 56 | // Trap errors 57 | client.on('error', function(error){ 58 | console.log(error); 59 | }); 60 | 61 | // Kill the connection after a few seconds to prevent timeout errors 62 | setTimeout(function(){ 63 | client.disconnect(); 64 | }, 4000); 65 | 66 | --------------------------------------------------------------------------------