Мониторинг Inet-Radius через JMX
Материал из BiTel WiKi
(Различия между версиями)
(Новая страница: «= Описание = <p> Будем мониторить по JMX работу Radius-серверов в контексте BGInetAccess и BGInetAccounting: * Сч…») |
|||
(16 промежуточных версий не показаны.) | |||
Строка 4: | Строка 4: | ||
* Счётчики пакетов в минуту по типам | * Счётчики пакетов в минуту по типам | ||
* Количество сессий по статусу | * Количество сессий по статусу | ||
+ | * (ваши пожелания) | ||
</p> | </p> | ||
[[Файл:chart1.png]] | [[Файл:chart1.png]] | ||
Строка 9: | Строка 10: | ||
[[Файл:chart2.png]] | [[Файл:chart2.png]] | ||
- | = | + | = Howto = |
+ | # Пишем свои Java MXBean для выдачи нужных данных | ||
+ | # Кладём jar-файл в либы Access и Accounting | ||
+ | # Прописываем bean-ы в inet_access.xml и inet_accounting.xml | ||
+ | # Включаем jmx для Access и Accounting | ||
+ | # Тестируем через jconsole | ||
+ | # Template для Zabbix 2.0 | ||
+ | |||
+ | === MXBeans === | ||
+ | <p>MXBeans tutorial:[http://docs.oracle.com/javase/tutorial/jmx/mbeans/mxbeans.html]</p> | ||
+ | <p>Обратите внимание, что механизм получения статистики по активным сессиям различается для Access и Accounting, поэтому нужно 2 реализации:</p> | ||
+ | <p>Готовый jar-файл для 5.2-сборка 1158 от 08.04.2013 : | ||
+ | |||
+ | [[Файл:mxradstatus.zip]] | ||
+ | </p> | ||
+ | ==== Access ==== | ||
+ | ===== Интерфейс ===== | ||
+ | <source lang="java"> | ||
+ | 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(); | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ===== Реализация ===== | ||
+ | <source lang="java"> | ||
+ | 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; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | ==== Accounting ==== | ||
+ | ===== Интерфейс ===== | ||
+ | <source lang="java"> | ||
+ | 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(); | ||
+ | } | ||
+ | </source> | ||
+ | ===== Реализация ===== | ||
+ | <source lang="java"> | ||
+ | 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; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | === Установка === | ||
+ | * Копируем mxradstatus.jar в lib/ext для Access и Accounting | ||
+ | * Прописываем в inet_access.xml: | ||
+ | <source lang="xml"> | ||
+ | ... | ||
+ | <context name="radius"> | ||
+ | |||
+ | <!-- Создание MXBean для мониторинга радиуса --> | ||
+ | <bean name="radiusStatusAccess" class="ru.dsi.bgbilling.modules.inet.mxbean.RadiusStatusAccess"> | ||
+ | <param name="access">access</param> | ||
+ | </bean> | ||
+ | ... | ||
+ | </source> | ||
+ | |||
+ | * Прописываем в inet_accounting.xml: | ||
+ | <source lang="xml"> | ||
+ | <context name="radius"> | ||
+ | <!-- Создание MXBean для мониторинга радиуса --> | ||
+ | <bean name="radiusStatusAccounting" class="ru.dsi.bgbilling.modules.inet.mxbean.RadiusStatusAccounting"> | ||
+ | <param name="accounting">accounting</param> | ||
+ | </bean> | ||
+ | |||
+ | ... | ||
+ | </source> | ||
+ | |||
+ | === Включаем JMX === | ||
+ | * Создаём файлы jmx.access: | ||
+ | <source lang="text"> | ||
+ | admin readwrite | ||
+ | monitor readonly | ||
+ | </source> | ||
+ | * и jmx.password: | ||
+ | <source lang="text"> | ||
+ | admin 12345 | ||
+ | monitor qwerty | ||
+ | </source> | ||
+ | * Помещаем их в корень Access и Accounting | ||
+ | * Задаём права: | ||
+ | <source lang="bash"> | ||
+ | chown bill:bill jmx.* | ||
+ | chmod 600 jmx.* | ||
+ | </source> | ||
+ | * Выбираем свободные порты для jmx. Например, 1616 и 1617 | ||
+ | * Прописываем в access.sh | ||
+ | <source lang="bash"> | ||
+ | ... | ||
+ | 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 | ||
+ | |||
+ | ... | ||
+ | </source> | ||
+ | * Прописываем в accounting.sh: | ||
+ | <source lang="bash"> | ||
+ | ... | ||
+ | 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 | ||
+ | ... | ||
+ | </source> | ||
+ | * Рестартуем Access и Accounting, убеждаемся, что ничего не упало. | ||
+ | |||
+ | === Подключаемся через Jconsole === | ||
+ | * Запускаем на клиентском компе jconsole (ищем в директории с JDK - в bin). | ||
+ | * Указываем ip, порт 1616 или 1617, логин и пароль из jmx.password | ||
+ | * Смотрим показания приборов на вкладке MBeans: [[Файл:mbean.png]] | ||
+ | |||
+ | === Настраиваем Zabbix === | ||
+ | * Шаблоны для Zabbix 2.0.4: [[Файл:templates.zip]] | ||
+ | * Настройки хоста: [[Файл:zabbix-host.png]] [[Файл:zabbix-macros.png]] | ||
+ | |||
+ | = Ссылки = | ||
+ | https://github.com/Cromeshnic/BGTools/tree/master/inet/monitoring/mxbeans | ||
+ | |||
+ | --[[Участник:Cromeshnic|Cromeshnic]] 07:44, 7 июня 2013 (UTC) |
Текущая версия на 04:29, 1 августа 2013
Содержание |
Описание
Будем мониторить по 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
- Настройки хоста:
Ссылки
https://github.com/Cromeshnic/BGTools/tree/master/inet/monitoring/mxbeans
--Cromeshnic 07:44, 7 июня 2013 (UTC)