嵌入式SNMP4j日志访问失败并成功

时间:2016-01-19 11:39:01

标签: logging snmp4j

我正在使用SNMP4j在java中编写代理,并且进展顺利。我可以获得并设置有价值(仅限SNMPv1,但v3即将推出)。

我的下一个要求是专门登录我的应用程序日志(而不是SNMP4J日志)这三件事:

  1. 新用户从
  2. 登录
  3. 用户从
  4. 尝试的新连接失败
  5. SNMP SET用于通过from。
  6. 写入值

    我已经使用org.snmp4j.log.LogAdapter将SNMP4j日志管道传输到我的调试日志中,但这不是我想要的特定日志。

    我使用org.snmp4j.event.AuthenticationFailureListener来记录发生身份验证失败的时间。这似乎只是SNMPv3,并没有给我失败的用户名。

    有谁知道怎么做?听众的建议似乎部分到位,还有更多我找不到的东西吗?我可以使用源代码并在需要的地方添加我自己的日志记录,但这有什么许可证含义? SNMP使用Apache 2.0许可证

1 个答案:

答案 0 :(得分:1)

我执行了以下操作以完全访问请求和响应PDU:

对于身份验证失败日志记录:

  1. 扩展AuthenticationFailureEvent.class。在我的例子中,我将安全名称和状态信息添加到事件类的构造函数中。
  2. 扩展MessageDispatcherImpl.class并覆盖方法dispatchMessage()

    switch (status) {
      case SnmpConstants.SNMP_MP_UNSUPPORTED_SECURITY_MODEL :
      case SnmpConstants.SNMPv3_USM_AUTHENTICATION_FAILURE :
      case SnmpConstants.SNMPv3_USM_UNSUPPORTED_SECURITY_LEVEL :
      case SnmpConstants.SNMPv3_USM_UNKNOWN_SECURITY_NAME :
      case SnmpConstants.SNMPv3_USM_AUTHENTICATION_ERROR :
      case SnmpConstants.SNMPv3_USM_NOT_IN_TIME_WINDOW :
      case SnmpConstants.SNMPv3_USM_UNSUPPORTED_AUTHPROTOCOL :
      case SnmpConstants.SNMPv3_USM_UNKNOWN_ENGINEID :
      case SnmpConstants.SNMP_MP_WRONG_USER_NAME :
      case SnmpConstants.SNMPv3_TSM_INADEQUATE_SECURITY_LEVELS :
      case SnmpConstants.SNMP_MP_USM_ERROR : {
        // create an extended version of the failure event
        AuthenticationFailureEvent event = new ExtendedAuthenticationFailureEvent(this,incomingAddress,securityName.getValue(),sourceTransport, status, statusInfo, wholeMessage);
        fireAuthenticationFailure(event);
        break;
      }
    }
    
  3. 在您的代理类中覆盖initMessageDispatcher()方法:

    protected void initMessageDispatcher() {
      ...
      dispatcher = new ExtendedMessageDispatcherImpl();
      ...
    }
    
  4. 将您的日志记录类添加为此调度程序的侦听器(例如,在代理的finishInit()方法中):

    dispatcher.addAuthenticationFailureListener(loggingHandler);
    
  5. 对于请求日志记录:

    只需在日志记录类中实现CommandResponder接口并将其添加到会话中:

    getSession().addCommandResponder(loggingHandler);
    

    对于响应日志记录:

    1. 创建方法,例如您的日志记录类中的logResponsePdu(PDU pdu)

    2. 扩展MessageDispatcherImpl.class并覆盖方法returnResponsePdu()

      public int returnResponsePdu(int messageProcessingModel, int securityModel, byte[] securityName, int securityLevel, PDU pdu, int maxSizeResponseScopedPDU, StateReference stateReference, StatusInformation statusInformation) throws MessageException {
        int result = super.returnResponsePdu(messageProcessingModel, securityModel, securityName, securityLevel, pdu, maxSizeResponseScopedPDU, stateReference, statusInformation);
        // log response message
        loggingHandler.logResponsePdu(pdu);
        return result;
      }
      
    3. 我的案例中的结果是以以下形式登录:

        

      收到请求!来自:(ip删除),安全名称:(登录名),PDU   类型:SET,OID:1.3.6.1.2.1.1.5.0 ='测试名称'

           

      请求PDU:   SET [{contextEngineID =(删除数据),   contextName = private},requestID =(删除数据),errorStatus = 0,errorIndex = 0,   VBS [1.3.6.1.2.1.1.5.0 =测试名称]]

           

      发送回复!错误状态:成功,PDU类型:RESPONSE,OID:   1.3.6.1.2.1.1.5.0 ='测试名称'

           

      响应PDU! PDU:   RESPONSE [{contextEngineID =(删除数据),   contextName = private},requestID =(删除数据),errorStatus = 0,errorIndex = 0,   VBS [1.3.6.1.2.1.1.5.0 =测试名称]]

      也许这不是最好的方法,但它确实有效。我希望我可以帮助你。