Мониторинг Inet-Radius через JMX

Материал из BiTel WiKi

(Различия между версиями)
Перейти к: навигация, поиск
 
(15 промежуточных версий не показаны.)
Строка 21: Строка 21:
<p>MXBeans tutorial:[http://docs.oracle.com/javase/tutorial/jmx/mbeans/mxbeans.html]</p>
<p>MXBeans tutorial:[http://docs.oracle.com/javase/tutorial/jmx/mbeans/mxbeans.html]</p>
<p>Обратите внимание, что механизм получения статистики по активным сессиям различается для Access и Accounting, поэтому нужно 2 реализации:</p>
<p>Обратите внимание, что механизм получения статистики по активным сессиям различается для Access и Accounting, поэтому нужно 2 реализации:</p>
 +
<p>Готовый jar-файл для 5.2-сборка 1158 от 08.04.2013 :
 +
 +
[[Файл:mxradstatus.zip]]
 +
</p>
==== Access ====
==== Access ====
===== Интерфейс =====
===== Интерфейс =====
Строка 453: Строка 457:
}
}
</source>
</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:

  • Счётчики пакетов в минуту по типам
  • Количество сессий по статусу
  • (ваши пожелания)

Файл:chart1.png

Файл:chart2.png

Howto

  1. Пишем свои Java MXBean для выдачи нужных данных
  2. Кладём jar-файл в либы Access и Accounting
  3. Прописываем bean-ы в inet_access.xml и inet_accounting.xml
  4. Включаем jmx для Access и Accounting
  5. Тестируем через jconsole
  6. 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: Файл:mbean.png

Настраиваем Zabbix

Ссылки

https://github.com/Cromeshnic/BGTools/tree/master/inet/monitoring/mxbeans

--Cromeshnic 07:44, 7 июня 2013 (UTC)

Личные инструменты