我正在使用SNMP4j在java中编写代理,并且进展顺利。我可以获得并设置有价值(仅限SNMPv1,但v3即将推出)。
我的下一个要求是专门登录我的应用程序日志(而不是SNMP4J日志)这三件事:
我已经使用org.snmp4j.log.LogAdapter将SNMP4j日志管道传输到我的调试日志中,但这不是我想要的特定日志。
我使用org.snmp4j.event.AuthenticationFailureListener来记录发生身份验证失败的时间。这似乎只是SNMPv3,并没有给我失败的用户名。
有谁知道怎么做?听众的建议似乎部分到位,还有更多我找不到的东西吗?我可以使用源代码并在需要的地方添加我自己的日志记录,但这有什么许可证含义? SNMP使用Apache 2.0许可证
答案 0 :(得分:1)
我执行了以下操作以完全访问请求和响应PDU:
对于身份验证失败日志记录:
AuthenticationFailureEvent.class
。在我的例子中,我将安全名称和状态信息添加到事件类的构造函数中。扩展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;
}
}
在您的代理类中覆盖initMessageDispatcher()
方法:
protected void initMessageDispatcher() {
...
dispatcher = new ExtendedMessageDispatcherImpl();
...
}
将您的日志记录类添加为此调度程序的侦听器(例如,在代理的finishInit()
方法中):
dispatcher.addAuthenticationFailureListener(loggingHandler);
对于请求日志记录:
只需在日志记录类中实现CommandResponder
接口并将其添加到会话中:
getSession().addCommandResponder(loggingHandler);
对于响应日志记录:
创建方法,例如您的日志记录类中的logResponsePdu(PDU pdu)
。
扩展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;
}
我的案例中的结果是以以下形式登录:
收到请求!来自:(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 =测试名称]]
也许这不是最好的方法,但它确实有效。我希望我可以帮助你。