Мониторинг Inet-Radius через JMX
Материал из BiTel WiKi
Версия от 07:40, 7 июня 2013; Cromeshnic (Обсуждение | вклад)
Содержание |
Описание
Будем мониторить по JMX работу Radius-серверов в контексте BGInetAccess и BGInetAccounting:
- Счётчики пакетов в минуту по типам
- Количество сессий по статусу
- (ваши пожелания)
Howto
- Пишем свои Java MXBean для выдачи нужных данных
- Кладём jar-файл в либы Access и Accounting
- Прописываем bean-ы в inet_access.xml и inet_accounting.xml
- Включаем jmx для Access и Accounting
- Тестируем через jconsole
- Template для Zabbix 2.0
MXBeans
MXBeans tutorial:[1]
Обратите внимание, что механизм получения статистики по активным сессиям различается для Access и Accounting, поэтому нужно 2 реализации:
Готовый jar-файл для 5.2-сборка 1158 от 08.04.2013 : Файл:Mxradstatus.zip
Access
Интерфейс
package ru.dsi.bgbilling.modules.inet.mxbean; import javax.management.MXBean; /** * * MXBean для получения статистики радиуса BGInetAccess */ @MXBean public interface RadiusStatusAccessMXBean { public int getAuthenticationAcceptCounter(); public int getAuthenticationRejectCounter(); public int getAuthenticationIgnoreCounter(); public int getAntispamIgnoreCounter(); public Long getActiveParentConnectionCount(); public Long getSuspendedParentConnectionCount(); public Long getClosedParentConnectionCount(); public Long getFinishedParentConnectionCount(); public Long getActiveServiceConnectionCount(); public Long getSuspendedServiceConnectionCount(); public Long getClosedServiceConnectionCount(); public Long getFinishedServiceConnectionCount(); }
Реализация
package ru.dsi.bgbilling.modules.inet.mxbean; import org.apache.log4j.Logger; import ru.bitel.bgbilling.kernel.network.radius.RadiusListener; import ru.bitel.bgbilling.modules.inet.access.Access; import ru.bitel.bgbilling.modules.inet.access.InetConnectionRuntime; import javax.management.*; import java.beans.ConstructorProperties; import java.lang.management.ManagementFactory; import java.util.List; import java.util.Map; /** * @see ru.dsi.bgbilling.modules.inet.mxbean.RadiusStatusAccessMXBean */ public class RadiusStatusAccess implements RadiusStatusAccessMXBean { private Access access; private static final Logger logger = Logger.getLogger(RadiusStatusAccess.class); @ConstructorProperties({"access"}) public RadiusStatusAccess(Access access){ this.access = access; //Регистрируем mxbean try { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName mxbeanName = new ObjectName("ru.dsi.bgbilling.modules.inet.mxbean:type=RadiusStatusAccess"); mbs.registerMBean(this, mxbeanName); } catch (InstanceAlreadyExistsException e) { logger.error("error on registering MXBean RadiusStatusAccess", e); } catch (MBeanRegistrationException e) { logger.error("error on registering MXBean RadiusStatusAccess", e); } catch (NotCompliantMBeanException e) { logger.error("error on registering MXBean RadiusStatusAccess", e); } catch (MalformedObjectNameException e) { logger.error("error on registering MXBean RadiusStatusAccess", e); } } @Override public Long getActiveParentConnectionCount(){ long count = 0; for (Map.Entry<Integer, List<InetConnectionRuntime>> entry : this.access.connectionManager.inetServEntrySet()) { for (InetConnectionRuntime connectionRuntime : entry.getValue()) { if(connectionRuntime.connection.getConnectionStatus()==1 && connectionRuntime.connection.getParentConnectionId()<=0L){ count++; } } } return count; } @Override public Long getSuspendedParentConnectionCount(){ long count = 0; for (Map.Entry<Integer, List<InetConnectionRuntime>> entry : this.access.connectionManager.inetServEntrySet()) { for (InetConnectionRuntime connectionRuntime : entry.getValue()) { if(connectionRuntime.connection.getConnectionStatus()==2 && connectionRuntime.connection.getParentConnectionId()<=0L){ count++; } } } return count; } @Override public Long getClosedParentConnectionCount(){ long count = 0; for (Map.Entry<Integer, List<InetConnectionRuntime>> entry : this.access.connectionManager.inetServEntrySet()) { for (InetConnectionRuntime connectionRuntime : entry.getValue()) { if(connectionRuntime.connection.getConnectionStatus()==3 && connectionRuntime.connection.getParentConnectionId()<=0L){ count++; } } } return count; } @Override public Long getFinishedParentConnectionCount(){ long count = 0; for (Map.Entry<Integer, List<InetConnectionRuntime>> entry : this.access.connectionManager.inetServEntrySet()) { for (InetConnectionRuntime connectionRuntime : entry.getValue()) { if(connectionRuntime.connection.getConnectionStatus()==4 && connectionRuntime.connection.getParentConnectionId()<=0L){ count++; } } } return count; } @Override public Long getActiveServiceConnectionCount(){ long count = 0; for (Map.Entry<Integer, List<InetConnectionRuntime>> entry : this.access.connectionManager.inetServEntrySet()) { for (InetConnectionRuntime connectionRuntime : entry.getValue()) { if(connectionRuntime.connection.getConnectionStatus()==1 && connectionRuntime.connection.getParentConnectionId()>0L){ count++; } } } return count; } @Override public Long getSuspendedServiceConnectionCount(){ long count = 0; for (Map.Entry<Integer, List<InetConnectionRuntime>> entry : this.access.connectionManager.inetServEntrySet()) { for (InetConnectionRuntime connectionRuntime : entry.getValue()) { if(connectionRuntime.connection.getConnectionStatus()==2 && connectionRuntime.connection.getParentConnectionId()>0L){ count++; } } } return count; } @Override public Long getClosedServiceConnectionCount(){ long count = 0; for (Map.Entry<Integer, List<InetConnectionRuntime>> entry : this.access.connectionManager.inetServEntrySet()) { for (InetConnectionRuntime connectionRuntime : entry.getValue()) { if(connectionRuntime.connection.getConnectionStatus()==3 && connectionRuntime.connection.getParentConnectionId()>0L){ count++; } } } return count; } @Override public Long getFinishedServiceConnectionCount(){ long count = 0; for (Map.Entry<Integer, List<InetConnectionRuntime>> entry : this.access.connectionManager.inetServEntrySet()) { for (InetConnectionRuntime connectionRuntime : entry.getValue()) { if(connectionRuntime.connection.getConnectionStatus()==4 && connectionRuntime.connection.getParentConnectionId()>0L){ count++; } } } return count; } @Override public int getAuthenticationAcceptCounter(){ try { return RadiusListener.authenticationAcceptCounter.getCount(); }catch (Exception e){ return -1; } } @Override public int getAuthenticationRejectCounter(){ try { return RadiusListener.authenticationRejectCounter.getCount(); }catch (Exception e){ return -1; } } @Override public int getAuthenticationIgnoreCounter(){ try { return RadiusListener.authenticationIgnoreCount.getCount(); }catch (Exception e){ return -1; } } @Override public int getAntispamIgnoreCounter(){ try { return RadiusListener.antispamIgnoreCount.getCount(); }catch (Exception e){ return -1; } } }
Accounting
Интерфейс
package ru.dsi.bgbilling.modules.inet.mxbean; import javax.management.MXBean; /** * MXBean для получения статистики радиуса BGInetAccounting */ @MXBean public interface RadiusStatusAccountingMXBean { public int getAccountingStartCounter(); public int getAccountingUpdateCounter(); public int getAccountingStopCounter(); public int getAccountingUpdateIgnoreCounter(); public int getAntispamIgnoreCounter(); public Long getActiveParentConnectionCount(); public Long getSuspendedParentConnectionCount(); public Long getClosedParentConnectionCount(); public Long getFinishedParentConnectionCount(); public Long getActiveServiceConnectionCount(); public Long getSuspendedServiceConnectionCount(); public Long getClosedServiceConnectionCount(); public Long getFinishedServiceConnectionCount(); }
Реализация
package ru.dsi.bgbilling.modules.inet.mxbean; import org.apache.log4j.Logger; import ru.bitel.bgbilling.kernel.network.radius.RadiusListener; import ru.bitel.bgbilling.modules.inet.accounting.Accounting; import ru.bitel.bgbilling.modules.inet.accounting.InetConnectionCallRuntime; import javax.management.*; import java.beans.ConstructorProperties; import java.lang.management.ManagementFactory; import java.util.Map; /** * @see RadiusStatusAccountingMXBean */ public class RadiusStatusAccounting implements RadiusStatusAccountingMXBean { private Accounting accounting; private static final Logger logger = Logger.getLogger(RadiusStatusAccounting.class); @ConstructorProperties({"accounting"}) public RadiusStatusAccounting(Accounting accounting){ this.accounting = accounting; //Регистрируем mxbean try { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName mxbeanName = new ObjectName("ru.dsi.bgbilling.modules.inet.mxbean:type=RadiusStatusAccounting"); mbs.registerMBean(this, mxbeanName); } catch (InstanceAlreadyExistsException e) { logger.error("error on registering MXBean RadiusStatusAccounting", e); } catch (MBeanRegistrationException e) { logger.error("error on registering MXBean RadiusStatusAccounting", e); } catch (NotCompliantMBeanException e) { logger.error("error on registering MXBean RadiusStatusAccounting", e); } catch (MalformedObjectNameException e) { logger.error("error on registering MXBean RadiusStatusAccounting", e); } } @Override public Long getActiveParentConnectionCount(){ long count = 0; for (Map.Entry<Long, InetConnectionCallRuntime> entry : this.accounting.connectionMapCall.getSessionMap().entrySet()) { if(entry.getValue().connection.getConnectionStatus()==1 && !entry.getValue().isServiceSession()){ count++; } } return count; } @Override public Long getSuspendedParentConnectionCount(){ long count = 0; for (Map.Entry<Long, InetConnectionCallRuntime> entry : this.accounting.connectionMapCall.getSessionMap().entrySet()) { if(entry.getValue().connection.getConnectionStatus()==2 && !entry.getValue().isServiceSession()){ count++; } } return count; } @Override public Long getClosedParentConnectionCount(){ long count = 0; for (Map.Entry<Long, InetConnectionCallRuntime> entry : this.accounting.connectionMapCall.getSessionMap().entrySet()) { if(entry.getValue().connection.getConnectionStatus()==3 && !entry.getValue().isServiceSession()){ count++; } } return count; } @Override public Long getFinishedParentConnectionCount(){ long count = 0; for (Map.Entry<Long, InetConnectionCallRuntime> entry : this.accounting.connectionMapCall.getSessionMap().entrySet()) { if(entry.getValue().connection.getConnectionStatus()==4 && !entry.getValue().isServiceSession()){ count++; } } return count; } @Override public Long getActiveServiceConnectionCount(){ long count = 0; for (Map.Entry<Long, InetConnectionCallRuntime> entry : this.accounting.connectionMapCall.getSessionMap().entrySet()) { if(entry.getValue().connection.getConnectionStatus()==1 && entry.getValue().isServiceSession()){ count++; } } return count; } @Override public Long getSuspendedServiceConnectionCount(){ long count = 0; for (Map.Entry<Long, InetConnectionCallRuntime> entry : this.accounting.connectionMapCall.getSessionMap().entrySet()) { if(entry.getValue().connection.getConnectionStatus()==2 && entry.getValue().isServiceSession()){ count++; } } return count; } @Override public Long getClosedServiceConnectionCount(){ long count = 0; for (Map.Entry<Long, InetConnectionCallRuntime> entry : this.accounting.connectionMapCall.getSessionMap().entrySet()) { if(entry.getValue().connection.getConnectionStatus()==3 && entry.getValue().isServiceSession()){ count++; } } return count; } @Override public Long getFinishedServiceConnectionCount(){ long count = 0; for (Map.Entry<Long, InetConnectionCallRuntime> entry : this.accounting.connectionMapCall.getSessionMap().entrySet()) { if(entry.getValue().connection.getConnectionStatus()==4 && entry.getValue().isServiceSession()){ count++; } } return count; } @Override public int getAccountingStartCounter(){ try { return RadiusListener.accountingStartCounter.getCount(); }catch (Exception e){ return -1; } } @Override public int getAccountingStopCounter(){ try { return RadiusListener.accountingStopCounter.getCount(); }catch (Exception e){ return -1; } } @Override public int getAccountingUpdateCounter(){ try { return RadiusListener.accountingUpdateCounter.getCount(); }catch (Exception e){ return -1; } } @Override public int getAccountingUpdateIgnoreCounter(){ try { return RadiusListener.accountingUpdateIgnoreCount.getCount(); }catch (Exception e){ return -1; } } @Override public int getAntispamIgnoreCounter(){ try { return RadiusListener.antispamIgnoreCount.getCount(); }catch (Exception e){ return -1; } } }
Установка
- Копируем mxradstatus.jar в lib/ext для Access и Accounting
- Прописываем в inet_access.xml:
... <context name="radius"> <!-- Создание MXBean для мониторинга радиуса --> <bean name="radiusStatusAccess" class="ru.dsi.bgbilling.modules.inet.mxbean.RadiusStatusAccess"> <param name="access">access</param> </bean> ...
- Прописываем в inet_accounting.xml:
<context name="radius"> <!-- Создание MXBean для мониторинга радиуса --> <bean name="radiusStatusAccounting" class="ru.dsi.bgbilling.modules.inet.mxbean.RadiusStatusAccounting"> <param name="accounting">accounting</param> </bean> ...
Включаем JMX
- Создаём файлы jmx.access:
admin readwrite monitor readonly
- и jmx.password:
admin 12345 monitor qwerty
- Помещаем их в корень Access и Accounting
- Задаём права:
chown bill:bill jmx.* chmod 600 jmx.*
- Выбираем свободные порты для jmx. Например, 1616 и 1617
- Прописываем в access.sh
... JMX="-Dcom.sun.management.jmxremote.port=1616 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=${APP_HOME}/jmx.password -Dcom.sun.management.jmxremote.access.file=${APP_HOME}/jmx.access -Dcom.sun.management.jmxremote.ssl=false" if [ "$1" = "start" ]; then nohup ${JAVA_HOME}|>/bin/java ${COMMON_PARAMS}|> ${LOG_PARAMS}|> ${MEMORY}|> ${JMX}|> -Dadmin.port=$ADMIN_PORT -cp ${CLASSPATH}|> ru.bitel.common.bootstrap.Boot ru.bitel.bgbilling.kernel.application.server.Application ${NAME}|> > ./log/${NAME_SHORT}|>.out 2>&1 & echo $! > .run/${NAME_SHORT}|>.pid & else ...
- Прописываем в accounting.sh:
... JMX="-Dcom.sun.management.jmxremote.port=1617 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=${APP_HOME}/jmx.password -Dcom.sun.management.jmxremote.access.file=${APP_HOME}/jmx.access -Dcom.sun.management.jmxremote.ssl=false" if [ "$1" = "start" ]; then nohup ${JAVA_HOME}|>/bin/java ${COMMON_PARAMS}|> ${LOG_PARAMS}|> ${MEMORY}|> ${JMX}|> -Dadmin.port=$ADMIN_PORT -cp ${CLASSPATH}|> ru.bitel.common.bootstrap.Boot ru.bitel.bgbilling.kernel.application.server.Application ${NAME}|> > ./log/${NAME_SHORT}|>.out 2>&1 & echo $! > .run/${NAME_SHORT}|>.pid & else ...
- Рестартуем Access и Accounting, убеждаемся, что ничего не упало.
Подключаемся через Jconsole
- Запускаем на клиентском компе jconsole (ищем в директории с JDK - в bin).
- Указываем ip, порт 1616 или 1617, логин и пароль из jmx.password
- Смотрим показания приборов на вкладке MBeans:
Настраиваем Zabbix
- Шаблоны для Zabbix 2.0.4: Файл:Templates.zip
- Настройки хоста: