net.anotheria.moskito.extension.mongodb.MongodbMonitor Maven / Gradle / Ivy
package net.anotheria.moskito.extension.mongodb;
import com.mongodb.*;
import com.mongodb.client.MongoDatabase;
import com.mongodb.util.JSON;
import net.anotheria.moskito.core.dynamic.OnDemandStatsProducer;
import net.anotheria.moskito.core.dynamic.OnDemandStatsProducerException;
import net.anotheria.moskito.core.registry.ProducerRegistryFactory;
import net.anotheria.moskito.extension.mongodb.config.MongodbMonitorConfig;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Main class to monitor mongodb instance
*/
public class MongodbMonitor {
private final static Logger LOGGER = LoggerFactory.getLogger(MongodbMonitor.class);
private static final String DB_ADMIN = "admin";
private MongoClient mongoClient;
private static OnDemandStatsProducer producer;
public MongodbMonitor() {
producer = new OnDemandStatsProducer<>("MongoMonitor", "Monitor", "db", new MongodbStatsFactory());
ProducerRegistryFactory.getProducerRegistryInstance().registerProducer(producer);
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new UpdateTask(), 0,
MongodbMonitorConfig.getInstance().getUpdatePeriod(), TimeUnit.MINUTES);
}
public void updateStats() {
try {
mongoClient = createClient(MongodbMonitorConfig.getInstance());
MongoDatabase adminDb = mongoClient.getDatabase(DB_ADMIN);
updateMongoServerStats(adminDb);
} finally {
if (mongoClient != null) {
mongoClient.close();
}
}
}
private MongoClient createClient(MongodbMonitorConfig config) {
List mongoCredentials = createMongoCredentials(config);
if (mongoCredentials.size() == 0) {
return new MongoClient(config.getHost(), Integer.parseInt(config.getPort()));
} else {
return new MongoClient(new ServerAddress(config.getHost(), Integer.parseInt(config.getPort())), mongoCredentials);
}
}
private List createMongoCredentials(MongodbMonitorConfig config) {
List mongoCredentials = new ArrayList<>();
if (config.getLogin() == null) {
return mongoCredentials;
}
mongoCredentials.add(MongoCredential.createCredential(config.getLogin(), config.getDbName(), config.getPassword().toCharArray()));
return mongoCredentials;
}
private void updateMongoServerStats(MongoDatabase dbAdmin) {
DBObject serverStats = executeMongoCommand(dbAdmin, "serverStatus");
Map map = serverStats.toMap();
updateFlushing(map);
updateConnections(map);
}
private void updateFlushing(Map map) {
Map backgroundFlushing = ((Map) map.get("backgroundFlushing"));
MongodbStats stats = getProducerStats();
stats.getFlushes().setValueAsInt(((Integer) backgroundFlushing.get("flushes")));
stats.getTotal_ms_write().setValueAsInt(((Integer) backgroundFlushing.get("total_ms")));
stats.getAvg_ms_write().setValueAsDouble(((Double) backgroundFlushing.get("average_ms")));
stats.getLast_ms_write().setValueAsInt(((Integer) backgroundFlushing.get("last_ms")));
}
private void updateConnections(Map map) {
Map connections = ((Map) map.get("connections"));
MongodbStats stats = getProducerStats();
stats.getCurrent_connections().setValueAsInt(((Integer) connections.get("current")));
stats.getAvailable_connections().setValueAsInt(((Integer) connections.get("available")));
stats.getTotal_created_connections().setValueAsInt(((Integer) connections.get("totalCreated")));
}
private MongodbStats getProducerStats() {
try {
return producer.getStats("cumulated");
} catch (OnDemandStatsProducerException e) {
throw new IllegalStateException(e);
}
}
private DBObject executeMongoCommand(MongoDatabase db, String command) {
DBObject dbObject = null;
try {
dbObject = (DBObject) JSON.parse(db.runCommand(new Document(command, 1)).toJson());
} catch (MongoCommandException e) {
LOGGER.error("Couldn't execute mongo command", e);
}
return dbObject;
}
public static MongodbMonitor createMongodbMonitor() {
return new MongodbMonitor();
}
public static void destroyMongodbMonitor() {
ProducerRegistryFactory.getProducerRegistryInstance().unregisterProducer(producer);
}
private class UpdateTask implements Runnable {
@Override
public void run() {
updateStats();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy