FtpMonitoring.java
/*
* This file is part of Waarp Project (named also Waarp or GG).
*
* Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
* tags. See the COPYRIGHT.txt in the distribution for a full listing of
* individual contributors.
*
* All Waarp Project is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Waarp . If not, see <http://www.gnu.org/licenses/>.
*/
package org.waarp.gateway.ftp.snmp;
import io.netty.handler.traffic.TrafficCounter;
import org.waarp.common.command.ReplyCode;
import org.waarp.common.database.DbPreparedStatement;
import org.waarp.common.database.DbSession;
import org.waarp.common.database.data.AbstractDbData.UpdatedInfo;
import org.waarp.common.database.exception.WaarpDatabaseException;
import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
import org.waarp.common.database.exception.WaarpDatabaseSqlException;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
import org.waarp.gateway.ftp.config.FileBasedConfiguration;
import org.waarp.gateway.ftp.database.DbConstantFtp;
import org.waarp.gateway.ftp.database.data.DbTransferLog;
import org.waarp.gateway.ftp.snmp.FtpPrivateMib.MibLevel;
import org.waarp.gateway.ftp.snmp.FtpPrivateMib.WaarpDetailedValuesIndex;
import org.waarp.gateway.ftp.snmp.FtpPrivateMib.WaarpErrorValuesIndex;
import org.waarp.gateway.ftp.snmp.FtpPrivateMib.WaarpGlobalValuesIndex;
import org.waarp.snmp.WaarpSnmpAgent;
import org.waarp.snmp.interf.WaarpInterfaceMonitor;
/**
* SNMP Monitoring class for FTP Exec
*/
public class FtpMonitoring implements WaarpInterfaceMonitor {
/**
* Internal Logger
*/
private static final WaarpLogger logger =
WaarpLoggerFactory.getLogger(FtpMonitoring.class);
public WaarpSnmpAgent agent;
// global informations
public long nbNetworkConnection;
public long nbThread;
// Internal data
private final DbSession dbSession;
private final TrafficCounter trafficCounter =
FileBasedConfiguration.fileBasedConfiguration.getFtpInternalConfiguration()
.getGlobalTrafficShapingHandler()
.trafficCounter();
public long nbCountInfoUnknown;
public long nbCountInfoNotUpdated;
public long nbCountInfoInterrupted;
public long nbCountInfoToSubmit;
public long nbCountInfoError;
public long nbCountInfoRunning;
public long nbCountInfoDone;
public long nbInActiveTransfer;
public long nbOutActiveTransfer;
public long lastInActiveTransfer = System.currentTimeMillis();
public long lastOutActiveTransfer = System.currentTimeMillis();
public long nbInTotalTransfer;
public long nbOutTotalTransfer;
public long nbInErrorTransfer;
public long nbOutErrorTransfer;
public long nbCountAllTransfer;
// Info for other reasons than transfers
private final long[] replyInfoNotransfers =
new long[WaarpDetailedValuesIndex.reply_350.ordinal() + 1];
// Error for other reasons than transfers
private final long[] replyErrorNotransfers =
new long[WaarpErrorValuesIndex.reply_553.ordinal() + 1];
{
for (int i = 0; i <= WaarpDetailedValuesIndex.reply_350.ordinal(); i++) {
replyInfoNotransfers[i] = 0;
}
for (int i = 0; i <= WaarpErrorValuesIndex.reply_553.ordinal(); i++) {
replyErrorNotransfers[i] = 0;
}
}
// Overall status including past, future and current transfers
private DbPreparedStatement countInfo;
// Current situation of all transfers, running or not
private DbPreparedStatement countInActiveTransfer;
private DbPreparedStatement countOutActiveTransfer;
private DbPreparedStatement countInTotalTransfer;
private DbPreparedStatement countOutTotalTransfer;
private DbPreparedStatement countInErrorTransfer;
private DbPreparedStatement countOutErrorTransfer;
private DbPreparedStatement countAllTransfer;
// Error Status on all transfers
private DbPreparedStatement countStatus;
/**
* @param session
*/
public FtpMonitoring(final DbSession session) {
if (session != null) {
dbSession = session;
} else {
dbSession = DbConstantFtp.gatewayAdmin.getSession();
}
initialize();
}
@Override
public final void setAgent(final WaarpSnmpAgent agent) {
this.agent = agent;
lastInActiveTransfer = this.agent.getUptimeSystemTime();
lastOutActiveTransfer = this.agent.getUptimeSystemTime();
}
@Override
public final void initialize() {
logger.debug("Initialize monitoring");
try {
// Overall status including past, future and current transfers
countInfo = DbTransferLog.getCountInfoPrepareStatement(dbSession);
// Count of Active/All In/Out transfers
countInActiveTransfer =
DbTransferLog.getCountInOutRunningPrepareStatement(dbSession, true,
true);
countOutActiveTransfer =
DbTransferLog.getCountInOutRunningPrepareStatement(dbSession, false,
true);
countInTotalTransfer =
DbTransferLog.getCountInOutRunningPrepareStatement(dbSession, true,
false);
countOutTotalTransfer =
DbTransferLog.getCountInOutRunningPrepareStatement(dbSession, false,
false);
countInErrorTransfer =
DbTransferLog.getCountInOutErrorPrepareStatement(dbSession, true);
countOutErrorTransfer =
DbTransferLog.getCountInOutErrorPrepareStatement(dbSession, false);
// All
countAllTransfer = DbTransferLog.getCountAllPrepareStatement(dbSession);
// Error Status on all transfers
countStatus = DbTransferLog.getCountStatusPrepareStatement(dbSession);
} catch (final WaarpDatabaseException ignored) {
// nothing
}
}
@Override
public final void releaseResources() {
try {
logger.debug("Release monitoring");
// Overall status including past, future and current transfers
countInfo.realClose();
countInActiveTransfer.realClose();
countOutActiveTransfer.realClose();
countInTotalTransfer.realClose();
countOutTotalTransfer.realClose();
countInErrorTransfer.realClose();
countOutErrorTransfer.realClose();
countAllTransfer.realClose();
// Error Status on all transfers
countStatus.realClose();
} catch (final NullPointerException ignored) {
// nothing
}
}
private static final int REF421 =
ReplyCode.REPLY_421_SERVICE_NOT_AVAILABLE_CLOSING_CONTROL_CONNECTION.ordinal();
/**
* Update the reply code counter for other operations than a transfer
*
* @param code
*/
public final void updateCodeNoTransfer(final ReplyCode code) {
int i = code.ordinal();
if (i >= REF421) {
i -= REF421;
replyErrorNotransfers[i]++;
} else {
replyInfoNotransfers[i]++;
}
}
/**
* Update the last InBound connection time
*/
public final void updateLastInBound() {
lastInActiveTransfer = System.currentTimeMillis();
}
/**
* Update the last OutBound connection time
*/
public final void updateLastOutBand() {
lastOutActiveTransfer = System.currentTimeMillis();
}
/**
* Update the value for one particular MIB entry
*
* @param type
* @param entry
*/
public final void run(final int type, final int entry) {
final long nbMs =
FileBasedConfiguration.fileBasedConfiguration.getAgentSnmp()
.getUptime() + 100;
final MibLevel level = MibLevel.values()[type];
switch (level) {
case globalInfo:// Global
if (((FtpPrivateMib) agent.getMib()).rowGlobal != null) {
run(nbMs, WaarpGlobalValuesIndex.values()[entry]);
}
return;
case detailedInfo:// Detailed
if (((FtpPrivateMib) agent.getMib()).rowDetailed != null) {
run(nbMs, WaarpDetailedValuesIndex.values()[entry]);
}
return;
case errorInfo:// Error
if (((FtpPrivateMib) agent.getMib()).rowError != null) {
run(nbMs, WaarpErrorValuesIndex.values()[entry]);
}
return;
default:
break;
}
}
/**
* Update a value in Global MIB part
*
* @param rank
* @param value
*/
protected final void updateGlobalValue(final int rank, final long value) {
((FtpPrivateMib) agent.getMib()).rowGlobal.setValue(rank, value);
}
/**
* Update a value in Detailed MIB part
*
* @param rank
* @param value
*/
protected final void updateDetailedValue(final int rank, final long value) {
((FtpPrivateMib) agent.getMib()).rowDetailed.setValue(rank, value);
}
/**
* Update a value in Error MIB part
*
* @param rank
* @param value
*/
protected final void updateErrorValue(final int rank, final long value) {
((FtpPrivateMib) agent.getMib()).rowError.setValue(rank, value);
}
/**
* Update a value in Global MIB part
*
* @param nbMs
* @param entry
*/
protected final void run(final long nbMs,
final WaarpGlobalValuesIndex entry) {
synchronized (trafficCounter) {
long val;
final long limitDate = System.currentTimeMillis() - nbMs;
// Global
try {
switch (entry) {
case applUptime:
case applOperStatus:
case applLastChange:
case memoryTotal:
case memoryFree:
case memoryUsed:
return;
case applInboundAssociations:
DbTransferLog.finishSelectOrCountPrepareStatement(
countInActiveTransfer, limitDate);
nbInActiveTransfer = DbTransferLog.getResultCountPrepareStatement(
countInActiveTransfer);
updateGlobalValue(entry.ordinal(), nbInActiveTransfer);
return;
case applOutboundAssociations:
DbTransferLog.finishSelectOrCountPrepareStatement(
countOutActiveTransfer, limitDate);
nbOutActiveTransfer = DbTransferLog.getResultCountPrepareStatement(
countOutActiveTransfer);
updateGlobalValue(entry.ordinal(), nbOutActiveTransfer);
return;
case applAccumInboundAssociations:
DbTransferLog.finishSelectOrCountPrepareStatement(
countInTotalTransfer, limitDate);
nbInTotalTransfer = DbTransferLog.getResultCountPrepareStatement(
countInTotalTransfer);
updateGlobalValue(entry.ordinal(), nbInTotalTransfer);
return;
case applAccumOutboundAssociations:
DbTransferLog.finishSelectOrCountPrepareStatement(
countOutTotalTransfer, limitDate);
nbOutTotalTransfer = DbTransferLog.getResultCountPrepareStatement(
countOutTotalTransfer);
updateGlobalValue(entry.ordinal(), nbOutTotalTransfer);
return;
case applLastInboundActivity:
val = (lastInActiveTransfer - agent.getUptimeSystemTime()) / 10;
if (val < 0) {
val = 0;
}
updateGlobalValue(entry.ordinal(), val);
return;
case applLastOutboundActivity:
val = (lastOutActiveTransfer - agent.getUptimeSystemTime()) / 10;
if (val < 0) {
val = 0;
}
updateGlobalValue(entry.ordinal(), val);
return;
case applRejectedInboundAssociations:
DbTransferLog.finishSelectOrCountPrepareStatement(
countInErrorTransfer, limitDate);
nbInErrorTransfer = DbTransferLog.getResultCountPrepareStatement(
countInErrorTransfer);
updateGlobalValue(entry.ordinal(), nbInErrorTransfer);
return;
case applFailedOutboundAssociations:
DbTransferLog.finishSelectOrCountPrepareStatement(
countOutErrorTransfer, limitDate);
nbOutErrorTransfer = DbTransferLog.getResultCountPrepareStatement(
countOutErrorTransfer);
updateGlobalValue(entry.ordinal(), nbOutErrorTransfer);
return;
case applInboundBandwidthKBS:
val = trafficCounter.lastReadThroughput() >> 10;// B/s -> KB/s
updateGlobalValue(entry.ordinal(), val);
return;
case applOutboundBandwidthKBS:
val = trafficCounter.lastWriteThroughput() >> 10;
updateGlobalValue(entry.ordinal(), val);
return;
case nbInfoUnknown:
nbCountInfoUnknown =
DbTransferLog.getResultCountPrepareStatement(countInfo,
UpdatedInfo.UNKNOWN,
limitDate);
updateGlobalValue(entry.ordinal(), nbCountInfoUnknown);
return;
case nbInfoNotUpdated:
nbCountInfoNotUpdated =
DbTransferLog.getResultCountPrepareStatement(countInfo,
UpdatedInfo.NOTUPDATED,
limitDate);
updateGlobalValue(entry.ordinal(), nbCountInfoNotUpdated);
return;
case nbInfoInterrupted:
nbCountInfoInterrupted =
DbTransferLog.getResultCountPrepareStatement(countInfo,
UpdatedInfo.INTERRUPTED,
limitDate);
updateGlobalValue(entry.ordinal(), nbCountInfoInterrupted);
return;
case nbInfoToSubmit:
nbCountInfoToSubmit =
DbTransferLog.getResultCountPrepareStatement(countInfo,
UpdatedInfo.TOSUBMIT,
limitDate);
updateGlobalValue(entry.ordinal(), nbCountInfoToSubmit);
return;
case nbInfoError:
nbCountInfoError =
DbTransferLog.getResultCountPrepareStatement(countInfo,
UpdatedInfo.INERROR,
limitDate);
updateGlobalValue(entry.ordinal(), nbCountInfoError);
return;
case nbInfoRunning:
nbCountInfoRunning =
DbTransferLog.getResultCountPrepareStatement(countInfo,
UpdatedInfo.RUNNING,
limitDate);
updateGlobalValue(entry.ordinal(), nbCountInfoRunning);
return;
case nbInfoDone:
nbCountInfoDone =
DbTransferLog.getResultCountPrepareStatement(countInfo,
UpdatedInfo.DONE,
limitDate);
updateGlobalValue(entry.ordinal(), nbCountInfoDone);
return;
case nbAllTransfer:
DbTransferLog.finishSelectOrCountPrepareStatement(countAllTransfer,
limitDate);
nbCountAllTransfer =
DbTransferLog.getResultCountPrepareStatement(countAllTransfer);
updateGlobalValue(entry.ordinal(), nbCountAllTransfer);
return;
case nbThreads:
nbThread = Thread.activeCount();
updateGlobalValue(entry.ordinal(), nbThread);
return;
case nbNetworkConnection:
nbNetworkConnection =
FileBasedConfiguration.fileBasedConfiguration.getFtpInternalConfiguration()
.getNumberSessions();
updateGlobalValue(entry.ordinal(), nbNetworkConnection);
}
} catch (final WaarpDatabaseNoConnectionException ignored) {
// nothing
} catch (final WaarpDatabaseSqlException ignored) {
// nothing
}
}
}
/**
* Update a value in Detailed MIB part
*
* @param nbMs
* @param entry
*/
protected final void run(final long nbMs,
final WaarpDetailedValuesIndex entry) {
synchronized (trafficCounter) {
final long limitDate = System.currentTimeMillis() - nbMs;
// Detailed
final long value =
DbTransferLog.getResultCountPrepareStatement(countStatus, entry.code,
limitDate);
updateDetailedValue(entry.ordinal(),
value + replyInfoNotransfers[entry.ordinal()]);
}
}
/**
* Update a value in Error MIB part
*
* @param nbMs
* @param entry
*/
protected final void run(final long nbMs, final WaarpErrorValuesIndex entry) {
synchronized (trafficCounter) {
final long limitDate = System.currentTimeMillis() - nbMs;
// Error
final long value =
DbTransferLog.getResultCountPrepareStatement(countStatus, entry.code,
limitDate);
updateErrorValue(entry.ordinal(),
value + replyErrorNotransfers[entry.ordinal()]);
}
}
}