Permalink
Browse files

initial source drop

  • Loading branch information...
1 parent 23944c7 commit b8b8d2b2bad931a2a626df1af9961ba0209295c9 @epicads-scott epicads-scott committed Jan 19, 2010
View
19 LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Epic Advertising
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
View
13 Makefile
@@ -0,0 +1,13 @@
+PACKAGE=rabbitmq-snmp
+DEPS=
+EXTRA_PACKAGE_DIRS=snmp
+
+include ../include.mk
+
+
+ebin/rabbit_snmp.beam: include/RABBITMQ-MIB.hrl snmp/RABBITMQ-MIB.bin
+
+snmp/RABBITMQ-MIB.bin: snmp/RABBITMQ-MIB.mib
+ erlc -o snmp/ $<
+include/RABBITMQ-MIB.hrl: snmp/RABBITMQ-MIB.bin
+ erlc -o include/ $<
View
49 README
@@ -1 +1,48 @@
-This is an experimental RabbitMQ plugin to provide SNMP statistics.
+This is an experimental RabbitMQ plugin to provide SNMP statistics. It has yet to see production use.
+
+
+BUILD INSTRUCTIONS:
+
+based off of: http://www.rabbitmq.com/plugin-development.html
+
+1: Setup your rabbitmq build environment
+ $ hg clone http://hg.rabbitmq.com/rabbitmq-public-umbrella
+ $ make co
+
+2: Switch to the rabbitmq_v1_7_0 tag for rabbitmq-server(a dependency for rabbit_snmp)
+ $ cd rabbitmq-server
+ $ hg checkout -r rabbitmq_v1_7_0
+
+3: Make the server
+ $ make
+
+4: Build the rabbitmq_snmp_plugin
+ $ cd ../rabbitmq-snmp-plugin
+ $ make
+
+5: Install the dist/rabbitmq-snmp.ez plugin into your server.
+
+ {snmp, [
+ {agent, [
+ % db_dir will be set by the snmp plugin before it starts snmp so leave this commented out
+ %{db_dir, ""},
+ {versions, [v1, v2]},
+ % dir will be added by the snmp plugin before it starts snmp, so dont add it to the config block below
+ {config, [{verbosity, silence}]},
+ {net_if, [{verbosity, silence}]}
+ ]},
+ {verbosity, silence}
+ ]}
+
+Test instructions.
+
+1: snmp walk
+ $ snmpwalk -v 1 -c public 127.0.0.1:4001 1.3.6.1.4
+
+Notes:
+ The oids are named off the vhost/name combo so you can add/remove them without worrying about changing their indexes.
+
+
+Contact:
+Scott Brooks <scott.brooks@epic-advertising.com>
+
View
12 ebin/rabbit_snmp.app
@@ -0,0 +1,12 @@
+{application, rabbit_snmp,
+ [{description, "Embedded SNMP Agent"},
+ {vsn, "0.0.1"},
+ {modules, [
+ rabbit_snmp,
+ rabbit_snmp_sup,
+ rabbit_snmp_worker
+ ]},
+ {registered, []},
+ {mod, {rabbit_snmp, []}},
+ {env, []},
+ {applications, [kernel, stdlib, rabbit]}]}.
View
1 include/records.hrl
@@ -0,0 +1 @@
+-record(rabbit_snmp_queue, {index, name, vhost, messages}).
View
1 snmp/.index
@@ -0,0 +1 @@
+RABBITMQ-MIB RABBITMQ-MIB.mib
View
3 snmp/RABBITMQ-MIB.funcs
@@ -0,0 +1,3 @@
+{vhostTable, {snmp_generic, table_func, [vhostTable]}}.
+{queueTable, {snmp_generic, table_func, [queueTable]}}.
+{exchangeTable, {snmp_generic, table_func, [exchangeTable]}}.
View
238 snmp/RABBITMQ-MIB.mib
@@ -0,0 +1,238 @@
+RABBITMQ-MIB DEFINITIONS ::= BEGIN
+
+--
+-- Top-level infrastructure of the Epic Ads enterprise MIB tree
+--
+
+IMPORTS
+ MODULE-IDENTITY, OBJECT-TYPE, Gauge32, Counter64, enterprises FROM SNMPv2-SMI
+
+ OBJECT-GROUP FROM SNMPv2-CONF
+
+ DisplayString, TruthValue FROM SNMPv2-TC;
+
+ rabbitMQ MODULE-IDENTITY
+ LAST-UPDATED "200911040000Z"
+ ORGANIZATION "www.epicadvertising.com"
+ CONTACT-INFO
+ "e-mail: scott.brooks@epicadvertising.com"
+ DESCRIPTION
+ "RabbitMQ snmp mib"
+ REVISION "200911040000Z"
+ DESCRIPTION
+ "First draft"
+ ::= { enterprises 12346}
+
+rabbitGroups OBJECT IDENTIFIER ::= { rabbitMQ 1 }
+vhosts OBJECT IDENTIFIER ::= { rabbitMQ 2 }
+queues OBJECT IDENTIFIER ::= { rabbitMQ 3 }
+exchanges OBJECT IDENTIFIER ::= { rabbitMQ 4 }
+
+vhostTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF VhostEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "list of vhosts"
+ ::= { vhosts 1 }
+
+vhostTableEntry OBJECT-TYPE
+ SYNTAX VhostEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "vhost entry"
+ INDEX { vhostName }
+ ::= { vhostTable 1 }
+
+VhostEntry ::= SEQUENCE {
+ vhostName DisplayString
+}
+
+vhostName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Vhost name"
+ ::= { vhostTableEntry 1 }
+
+queueTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF QueueStatisticsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "A list of all the queues for a specific vhost"
+ ::= { queues 1 }
+
+queueTableEntry OBJECT-TYPE
+ SYNTAX QueueStatisticsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "A queue"
+ INDEX { queueVhost, queueName }
+ ::= { queueTable 1 }
+
+QueueStatisticsEntry ::= SEQUENCE {
+ queueVhost DisplayString,
+ queueName DisplayString,
+ queueDurable TruthValue,
+ queueAutoDelete TruthValue,
+ queueMessages Gauge32,
+ queueUnAcknowledged Gauge32,
+ queueUnCommitted Gauge32,
+ queueReady Gauge32,
+ queueAcksUncommitted Gauge32,
+ queueConsumers Gauge32,
+ queueTransactions Gauge32,
+ queueMemory Counter64
+}
+
+queueVhost OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Queue Vhost"
+ ::= { queueTableEntry 1 }
+
+queueName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Queue name"
+ ::= { queueTableEntry 2 }
+
+queueDurable OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "True if the queue is durable"
+ ::= { queueTableEntry 3 }
+
+queueAutoDelete OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "True if the queue is set to auto_delete"
+ ::= { queueTableEntry 4 }
+
+queueMessages OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of messages"
+ ::= { queueTableEntry 5 }
+
+queueUnAcknowledged OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of unacknowledged messages"
+ ::= { queueTableEntry 6 }
+
+queueUnCommitted OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of uncommitted messages"
+ ::= { queueTableEntry 7 }
+
+queueReady OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of ready messages"
+ ::= { queueTableEntry 8 }
+
+queueAcksUncommitted OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of uncommitted acks"
+ ::= { queueTableEntry 9 }
+
+queueConsumers OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of consumers"
+ ::= { queueTableEntry 10 }
+
+queueTransactions OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of transactions"
+ ::= { queueTableEntry 11 }
+
+queueMemory OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Amount of memory used"
+ ::= { queueTableEntry 12 }
+
+exchangeTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF ExchangeEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "list of exchanges"
+ ::= { exchanges 1 }
+
+exchangeTableEntry OBJECT-TYPE
+ SYNTAX ExchangeEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "exchange entry"
+ INDEX { exchangeVhost, exchangeName }
+ ::= { exchangeTable 1 }
+
+ExchangeEntry ::= SEQUENCE {
+ exchangeVhost DisplayString,
+ exchangeName DisplayString,
+ exchangeType DisplayString,
+ exchangeDurable TruthValue,
+ exchangeAutoDelete TruthValue
+}
+
+exchangeVhost OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Exchange Vhost"
+ ::= { exchangeTableEntry 1 }
+
+exchangeName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Exchange name"
+ ::= { exchangeTableEntry 2 }
+
+exchangeType OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Exchange Type"
+ ::= { exchangeTableEntry 3 }
+
+exchangeDurable OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "True if the queue is set to durable"
+ ::= { exchangeTableEntry 4 }
+
+exchangeAutoDelete OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "True if the queue is set to auto_delete"
+ ::= { exchangeTableEntry 5 }
+
+
+rabbitGroup OBJECT-GROUP
+ OBJECTS {
+ queueVhost, queueName, queueDurable, queueAutoDelete, queueMessages, queueUnAcknowledged, queueUnCommitted, queueReady, queueAcksUncommitted, queueConsumers, queueTransactions, queueMemory, vhostName, exchangeVhost, exchangeType, exchangeName, exchangeDurable, exchangeAutoDelete
+ }
+ STATUS current
+ DESCRIPTION "Groups"
+ ::= { rabbitGroups 1 }
+
+END
View
20 snmp/agent/conf/agent.conf
@@ -0,0 +1,20 @@
+%% This file was generated by snmp_config (version-4.13.1) 2009-06-10 10:12:05
+%% This file defines the Agent local configuration info
+%% The data is inserted into the snmpEngine* variables defined
+%% in SNMP-FRAMEWORK-MIB, and the intAgent* variables defined
+%% in OTP-SNMPEA-MIB.
+%% Each row is a 2-tuple:
+%% {AgentVariable, Value}.
+%% For example
+%% {intAgentUDPPort, 4000}.
+%% The ip address for the agent is sent as id in traps.
+%% {intAgentIpAddress, [127,42,17,5]}.
+%% {snmpEngineID, "agentEngine"}.
+%% {snmpEngineMaxMessageSize, 484}.
+%%
+
+
+{intAgentUDPPort, 4001}.
+{intAgentIpAddress, [127,0,0,1]}.
+{snmpEngineID, "RabbitMQ Stats"}.
+{snmpEngineMaxMessageSize, 484}.
View
1 snmp/agent/conf/community.conf
@@ -0,0 +1 @@
+{"public", "public", "initial", "", ""}.
View
4 snmp/agent/conf/context.conf
@@ -0,0 +1,4 @@
+%% This file was automatically generated by snmp_config v4.13.1 2009-06-15 19:22:50
+
+%% The default context
+"".
View
22 snmp/agent/conf/standard.conf
@@ -0,0 +1,22 @@
+%% This file was generated by snmp_config (version-4.13.1) 2009-06-10 10:12:05
+%% This file defines the STANDARD-MIB info.
+%% Each row is a 2-tuple:
+%% {StandardVariable, Value}.
+%% For example
+%% {sysDescr, "Erlang SNMP agent"}.
+%% {sysObjectID, [1,2,3]}.
+%% {sysContact, "{mbj,eklas}@erlang.ericsson.se"}.
+%% {sysName, "test"}.
+%% {sysLocation, "erlang"}.
+%% {sysServices, 72}.
+%% {snmpEnableAuthenTraps, enabled}.
+%%
+
+
+{sysDescr, "RabbitMQ Stats"}.
+{sysObjectID, [1,3,6,1,4,1,12346,1]}.
+{sysContact, "sample@example.com"}.
+{sysLocation, "Location"}.
+{sysServices, 72}.
+{snmpEnableAuthenTraps, enabled}.
+{sysName, "rabbitmq"}.
View
0 snmp/agent/conf/usm.conf
No changes.
View
30 snmp/agent/conf/vacm.conf
@@ -0,0 +1,30 @@
+%% This file was generated by snmp_config (version-4.13.1) 2009-06-10 10:12:05
+%% This file defines the Mib Views.
+%% The data is inserted into the vacm* tables defined
+%% in SNMP-VIEW-BASED-ACM-MIB.
+%% Each row is one of 3 tuples; one for each table in the MIB:
+%% {vacmSecurityToGroup, SecModel, SecName, GroupName}.
+%% {vacmAccess, GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}.
+%% {vacmViewTreeFamily, ViewIndex, ViewSubtree, ViewStatus, ViewMask}.
+%% For example
+%% {vacmSecurityToGroup, v2c, "initial", "initial"}.
+%% {vacmSecurityToGroup, usm, "initial", "initial"}.
+%% read/notify access to system
+%% {vacmAccess, "initial", "", any, noAuthNoPriv, exact,
+%% "system", "", "system"}.
+%% {vacmViewTreeFamily, "system", [1,3,6,1,2,1,1], included, null}.
+%% {vacmViewTreeFamily, "exmib", [1,3,6,1,3], included, null}. % for EX1-MIB
+%% {vacmViewTreeFamily, "internet", [1,3,6,1], included, null}.
+%%
+
+
+{vacmSecurityToGroup, v2c, "initial", "initial"}.
+{vacmSecurityToGroup, v2c, "all-rights", "all-rights"}.
+{vacmSecurityToGroup, v1, "initial", "initial"}.
+{vacmSecurityToGroup, v1, "all-rights", "all-rights"}.
+{vacmAccess, "initial", "", any, noAuthNoPriv, exact, "restricted", "", "restricted"}.
+{vacmAccess, "initial", "", usm, authNoPriv, exact, "internet", "internet", "internet"}.
+{vacmAccess, "initial", "", usm, authPriv, exact, "internet", "internet", "internet"}.
+{vacmAccess, "all-rights", "", any, noAuthNoPriv, exact, "internet", "internet", "internet"}.
+{vacmViewTreeFamily, "restricted", [1,3,6,1], included, null}.
+{vacmViewTreeFamily, "internet", [1,3,6,1], included, null}.
View
34 src/rabbit_snmp.erl
@@ -0,0 +1,34 @@
+-module(rabbit_snmp).
+
+-export([start/0, stop/0, start/2, stop/1]).
+
+-include("RABBITMQ-MIB.hrl").
+
+load_snmp_environment() ->
+ Path = code:lib_dir(rabbitmq,snmp),
+
+ ok = application:load(snmp),
+ {ok, Agent} = application:get_env(snmp, agent),
+ Config = proplists:get_value(config, Agent),
+ NewConfig = lists:keystore(dir, 1, Config, {dir, Path ++ "/agent/conf"}),
+ NewAgent = lists:keystore(db_dir, 1, (lists:keystore(config, 1, Agent, {config, NewConfig})), {db_dir, Path ++ "/agent/db"}),
+ application:set_env(snmp, agent, NewAgent),
+
+ ok = application:start(snmp),
+ ok = snmpa:load_mibs(snmp_master_agent, [Path ++ "/RABBITMQ-MIB"]),
+ ok.
+
+start() ->
+ load_snmp_environment(),
+ rabbit_snmp_sup:start_link(),
+ ok.
+
+stop() ->
+ ok.
+
+start(normal, []) ->
+ load_snmp_environment(),
+ rabbit_snmp_sup:start_link().
+
+stop(_State) ->
+ ok.
View
17 src/rabbit_snmp_sup.erl
@@ -0,0 +1,17 @@
+-module(rabbit_snmp_sup).
+-behaviour(supervisor).
+
+-export([start_link/0, init/1]).
+
+start_link() ->
+ supervisor:start_link({local, ?MODULE}, ?MODULE, _Arg = []).
+
+init([]) ->
+ {ok, {{one_for_one, 3, 10},
+ [{rabbit_snmp_worker,
+ {rabbit_snmp_worker, start_link, []},
+ permanent,
+ 10000,
+ worker,
+ [rabbit_snmp_worker]}
+ ]}}.
View
108 src/rabbit_snmp_worker.erl
@@ -0,0 +1,108 @@
+-module(rabbit_snmp_worker).
+-behaviour(gen_server).
+
+-export([start/0, start/2, stop/0, stop/1, start_link/0]).
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
+
+
+-record(state, {update_interval}).
+
+start() ->
+ start_link(),
+ ok.
+
+start(normal, []) ->
+ start_link().
+
+stop() ->
+ ok.
+
+stop(_State) ->
+ stop().
+
+start_link() ->
+ gen_server:start_link({global, ?MODULE}, ?MODULE, [], []).
+
+init([]) ->
+ application:start(snmp),
+ io:format("Started snmp state poller~n", []),
+ UpdateInterval = 10000,
+ erlang:send_after(1, self(), update_stats),
+ {ok, #state{update_interval = UpdateInterval}}.
+
+create_exchange_row([]) ->
+ ok;
+create_exchange_row([Row|Rest]) ->
+ {exchange, {resource, Vhost, exchange, ExchangeName}, ExchangeType, ExchangeDurability, ExchangeAutoDelete, _Args} = Row,
+ ListVhost = binary_to_list(Vhost),
+ ListExchange = binary_to_list(ExchangeName),
+
+ SnmpRow = {ListVhost, ListExchange,
+ atom_to_list(ExchangeType),
+ ExchangeDurability,
+ ExchangeAutoDelete
+ },
+ snmpa_local_db:table_create_row(exchangeTable, ListVhost ++ ListExchange, SnmpRow),
+ create_exchange_row(Rest).
+
+create_vhost_row([]) ->
+ ok;
+create_vhost_row([Row|Rest]) ->
+ SnmpRow = {binary_to_list(Row)},
+ snmpa_local_db:table_create_row(vhostTable, binary_to_list(Row), SnmpRow),
+ create_vhost_row(Rest).
+
+create_queue_row([]) ->
+ ok;
+create_queue_row([Row|Rest]) ->
+ {resource, Vhost, queue, QueueName} = proplists:get_value(name, Row),
+ ListVhost = binary_to_list(Vhost),
+ ListQueue = binary_to_list(QueueName),
+
+ SnmpRow = {ListVhost, ListQueue,
+ proplists:get_value(durable, Row),
+ proplists:get_value(auto_delete, Row),
+ proplists:get_value(messages, Row),
+ proplists:get_value(messages_unacknowledged, Row),
+ proplists:get_value(messages_uncommitted, Row),
+ proplists:get_value(messages_ready, Row),
+ proplists:get_value(acks_uncommitted, Row),
+ proplists:get_value(consumers, Row),
+ proplists:get_value(transactions, Row),
+ proplists:get_value(memory, Row)
+ },
+
+ snmpa_local_db:table_create_row(queueTable, ListVhost ++ ListQueue, SnmpRow),
+ create_queue_row(Rest).
+
+
+update_stats() ->
+ Vhosts = rabbit_access_control:list_vhosts(),
+ create_vhost_row(Vhosts),
+ Queues = lists:append([rabbit_amqqueue:info_all(X) || X <- Vhosts]),
+ create_queue_row(Queues),
+ Exchanges = lists:append([rabbit_exchange:list(X) || X <- Vhosts]),
+ create_exchange_row(Exchanges),
+ ok.
+
+handle_call(_Msg,_From,State) ->
+ {reply, unknown_command, State}.
+
+handle_cast(_,State) ->
+ {noreply, State}.
+
+handle_info(update_stats, State) ->
+ update_stats(),
+ erlang:send_after(State#state.update_interval, self(), update_stats),
+ {noreply, State};
+
+handle_info(Info, State) ->
+ io:format("Info: ~p~nState: ~p~n", [Info, State]),
+ {noreply, State}.
+
+terminate(_,_State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+

0 comments on commit b8b8d2b

Please sign in to comment.