public void collect()

in hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/snmp/SnmpCollectImpl.java [104:259]


    public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
        long startTime = System.currentTimeMillis();
        SnmpProtocol snmpProtocol = metrics.getSnmp();
        int timeout = CollectUtil.getTimeout(snmpProtocol.getTimeout());
        int snmpVersion = getSnmpVersion(snmpProtocol.getVersion());
        Snmp snmpService = null;
        try {
            SnmpBuilder snmpBuilder = new SnmpBuilder();
            snmpService = getSnmpService(snmpVersion, snmpBuilder);
            snmpService.listen();
            Target<?> target;
            Address targetAddress = GenericAddress.parse(DEFAULT_PROTOCOL + ":" + snmpProtocol.getHost()
                    + "/" + snmpProtocol.getPort());
            TargetBuilder<?> targetBuilder = snmpBuilder.target(targetAddress);
            if (snmpVersion == SnmpConstants.version3) {
                TargetBuilder.PrivProtocol privatePasswordEncryption = getPrivPasswordEncryption(snmpProtocol.getPrivPasswordEncryption());
                TargetBuilder.AuthProtocol authPasswordEncryption = getAuthPasswordEncryption(snmpProtocol.getAuthPasswordEncryption());
                target = targetBuilder
                        .user(snmpProtocol.getUsername())
                        .auth(authPasswordEncryption).authPassphrase(snmpProtocol.getAuthPassphrase())
                        .priv(privatePasswordEncryption).privPassphrase(snmpProtocol.getPrivPassphrase())
                        .done()
                        .timeout(timeout).retries(1)
                        .build();
                USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
                SecurityModels.getInstance().addSecurityModel(usm);
                snmpService.getUSM().addUser(
                        new OctetString(snmpProtocol.getUsername()),
                        new UsmUser(new OctetString(snmpProtocol.getUsername()),
                                AuthMD5.ID,
                                new OctetString(snmpProtocol.getAuthPassphrase()),
                                PrivDES.ID,
                                new OctetString(snmpProtocol.getPrivPassphrase()))
                );
            } else if (snmpVersion == SnmpConstants.version1) {
                target = targetBuilder
                        .v1()
                        .community(new OctetString(snmpProtocol.getCommunity()))
                        .timeout(timeout).retries(1)
                        .build();
                target.setSecurityModel(SecurityModel.SECURITY_MODEL_SNMPv1);
            } else {
                target = targetBuilder
                        .v2c()
                        .community(new OctetString(snmpProtocol.getCommunity()))
                        .timeout(timeout).retries(1)
                        .build();
                target.setSecurityModel(SecurityModel.SECURITY_MODEL_SNMPv2c);
            }
            String operation = snmpProtocol.getOperation();
            operation = StringUtils.hasText(operation) ? operation : OPERATION_GET;
            if (OPERATION_GET.equalsIgnoreCase(operation)) {
                String contextName = getContextName(snmpProtocol.getContextName());
                PDU pdu = targetBuilder.pdu().type(PDU.GET).oids(snmpProtocol.getOids().values().toArray(new String[0])).contextName(contextName).build();
                SnmpCompletableFuture snmpRequestFuture = SnmpCompletableFuture.send(snmpService, target, pdu);
                List<VariableBinding> vbs = snmpRequestFuture.get().getAll();
                long responseTime = System.currentTimeMillis() - startTime;
                Map<String, String> oidsMap = snmpProtocol.getOids();
                Map<String, String> oidsValueMap = new HashMap<>(oidsMap.size());
                for (VariableBinding binding : vbs) {
                    if (binding == null) {
                        continue;
                    }
                    Variable variable = binding.getVariable();
                    if (variable instanceof TimeTicks timeTicks) {
                        String value = timeTicks.toString(FORMAT_PATTERN);
                        oidsValueMap.put(binding.getOid().toDottedString(), value);
                    } else {
                        oidsValueMap.put(binding.getOid().toDottedString(), binding.toValueString());
                    }
                }
                CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
                for (String alias : metrics.getAliasFields()) {
                    if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
                        valueRowBuilder.addColumn(Long.toString(responseTime));
                    } else {
                        String oid = oidsMap.get(alias);
                        String value = oidsValueMap.get(oid);
                        valueRowBuilder.addColumn(Objects.requireNonNullElse(value, CommonConstants.NULL_VALUE));
                    }
                }
                builder.addValueRow(valueRowBuilder.build());
            } else if (OPERATION_WALK.equalsIgnoreCase(operation)) {
                Map<String, String> oidMap = snmpProtocol.getOids();
                Assert.notEmpty(oidMap, "snmp oids is required when operation is walk.");
                TableUtils tableUtils = new TableUtils(snmpService, new DefaultPDUFactory(PDU.GETBULK));
                OID[] oids = oidMap.values().stream().map(OID::new).toArray(OID[]::new);
                List<TableEvent> tableEvents = tableUtils.getTable(target, oids, null, null);
                Assert.notNull(tableEvents, "snmp walk response empty content.");
                long responseTime = System.currentTimeMillis() - startTime;
                for (TableEvent tableEvent : tableEvents) {
                    if (tableEvent == null || tableEvent.isError()) {
                        continue;
                    }
                    VariableBinding[] varBindings = tableEvent.getColumns();
                    Map<String, String> oidsValueMap = new HashMap<>(varBindings.length);
                    for (VariableBinding binding : varBindings) {
                        if (binding == null) {
                            continue;
                        }
                        Variable variable = binding.getVariable();
                        if (variable instanceof TimeTicks timeTicks) {
                            String value = timeTicks.toString(FORMAT_PATTERN);
                            oidsValueMap.put(binding.getOid().trim().toDottedString(), value);
                        } else {
                            oidsValueMap.put(binding.getOid().trim().toDottedString(), bingdingHexValueToString(binding));
                        }
                    }
                    // when too many empty value field, ignore
                    if (oidsValueMap.size() < metrics.getAliasFields().size() / 2) {
                        continue;
                    }
                    CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
                    for (String alias : metrics.getAliasFields()) {
                        if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
                            valueRowBuilder.addColumn(Long.toString(responseTime));
                        } else {
                            String oid = oidMap.get(alias);
                            String value = oidsValueMap.get(oid);
                            if (value == null) {
                                // get leaf
                                for (String key : oidsValueMap.keySet()) {
                                    if (key.startsWith(oid)) {
                                        value = oidsValueMap.get(key);
                                        break;
                                    }
                                }
                            }
                            valueRowBuilder.addColumn(Objects.requireNonNullElse(value, CommonConstants.NULL_VALUE));
                        }
                    }
                    builder.addValueRow(valueRowBuilder.build());
                }
            }
        } catch (ExecutionException | InterruptedException ex) {
            String errorMsg = CommonUtil.getMessageFromThrowable(ex);
            log.warn("[snmp collect] error: {}", errorMsg);
            builder.setCode(CollectRep.Code.UN_CONNECTABLE);
            builder.setMsg(errorMsg);
        } catch (Exception e) {
            String errorMsg = CommonUtil.getMessageFromThrowable(e);
            log.warn("[snmp collect] error: {}", errorMsg, e);
            builder.setCode(CollectRep.Code.FAIL);
            builder.setMsg(errorMsg);
        } finally {
            if (snmpService != null) {
                if (snmpVersion == SnmpConstants.version3) {
                    try {
                        snmpClose(snmpService, SnmpConstants.version3);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }