Package org.voltdb.client

Source Code of org.voltdb.client.ClientStatsSqlLoader

/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* VoltDB 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.
*
* VoltDB 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 VoltDB.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.voltdb.client;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;

import org.apache.log4j.Logger;
import org.voltdb.VoltTable;

import edu.brown.catalog.CatalogUtil;

/**
* Polls a Distributer instance for IO and procedure invocation information and ELTs the results
* to a database via JDBC.
*
*/
public class ClientStatsSqlLoader implements ClientStatsLoader {
    private static final Logger LOG = Logger.getLogger(ClientStatsSqlLoader.class);
   
    private final StatsUploaderSettings m_settings;
    private final Connection m_conn;
    private final String m_applicationName;
    private final String m_subApplicationName;
    private final int m_pollInterval;
    private final Distributer m_distributer;
    private int m_instanceId = -1;
    private final Thread m_loadThread = new Thread(new Loader(), "Client stats loader");

    private static final String tablePrefix = ""; // "ma_";

    private static final String instancesTable = tablePrefix + "clientInstances";
    private static final String connectionStatsTable = tablePrefix + "clientConnectionStats";
    private static final String procedureStatsTable = tablePrefix + "clientProcedureStats";

    private static final String createInstanceStatement = "insert into " + instancesTable +
            " ( clusterStartTime, clusterLeaderAddress, applicationName, subApplicationName, " +
            " numHosts, numSites, numPartitions) " +
            "values ( ?, ?, ?, ?, ?, ?, ? );";

    private static final String insertConnectionStatsStatement = "insert into " + connectionStatsTable +
            " ( instanceId, tsEvent, hostname, connectionId, serverHostId, serverHostname, " +
            " serverConnectionId, numInvocations, numAborts, numFailures, numThrottled, numBytesRead, " +
            " numMessagesRead, numBytesWritten, numMessagesWritten) " +
            "values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );";

    private static final String insertProcedureStatsStatement = "insert into " + procedureStatsTable +
            " ( instanceId, tsEvent, hostname, connectionId, serverHostId, serverHostname, " +
            " serverConnectionId, procedureName, roundtripAvg, roundtripMin, roundtripMax, " +
            " clusterRoundtripAvg, clusterRoundtripMin, clusterRoundtripMax, " +
            " numInvocations, numAborts, numFailures, numRestarts) " +
            "values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );";

    private PreparedStatement insertConnectionStatsStmt;
    private PreparedStatement insertProcedureStatsStmt;

    public ClientStatsSqlLoader(
            StatsUploaderSettings settings,
            Distributer distributer) {
        if (LOG.isDebugEnabled())
            LOG.debug("Creating new connection to stats database [" + settings.databaseURL + "]");
        try {
            if (settings.databaseJDBC != null && settings.databaseJDBC.isEmpty() == false) {
                Class.forName(settings.databaseJDBC);
            }
           
            m_conn = DriverManager.getConnection(settings.databaseURL,
                                               settings.databaseUser,
                                               settings.databasePass);
            m_conn.setAutoCommit(false);
            m_conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
        }
        catch (Exception e) {
            String msg = "Failed to connect to SQL reporting server with message:\n    ";
            msg += e.getMessage();
            throw new RuntimeException(msg);
        }
       
        m_settings = settings;
        m_applicationName = settings.applicationName;
        m_subApplicationName = settings.subApplicationName;
        m_pollInterval = settings.pollInterval;
        m_distributer = distributer;
    }

    public void start(long startTime, int leaderAddress) throws SQLException {
        Timestamp timestamp = new Timestamp(startTime);
        if (LOG.isDebugEnabled())
            LOG.debug(String.format("Cluster Start Time: %s [%d]", timestamp, startTime));
       
        PreparedStatement instanceStmt =
            m_conn.prepareStatement(
                    createInstanceStatement,
                    PreparedStatement.RETURN_GENERATED_KEYS);
        insertConnectionStatsStmt = m_conn.prepareStatement(insertConnectionStatsStatement);
        insertProcedureStatsStmt = m_conn.prepareStatement(insertProcedureStatsStatement);
        instanceStmt.setTimestamp( 1, timestamp);
        instanceStmt.setInt( 2, leaderAddress);
        instanceStmt.setString( 3, m_applicationName);
        if (m_subApplicationName != null) {
            instanceStmt.setString( 4, m_subApplicationName);
        } else {
            instanceStmt.setNull( 4, Types.VARCHAR);
        }
        instanceStmt.setInt(5, CatalogUtil.getNumberOfHosts(m_settings.getCatalog()));
        instanceStmt.setInt(6, CatalogUtil.getNumberOfSites(m_settings.getCatalog()));
        instanceStmt.setInt(7, CatalogUtil.getNumberOfPartitions(m_settings.getCatalog()));
        instanceStmt.execute();
        ResultSet results = instanceStmt.getGeneratedKeys();
        while (results.next()) {
            m_instanceId = results.getInt( 1 );
        }
        results.close();
        instanceStmt.close();
        if (m_instanceId < 0) {
            throw new SQLException("Unable to generate an instance id to identify this client");
        }
        insertConnectionStatsStmt.setInt( 1, m_instanceId);
        insertProcedureStatsStmt.setInt( 1, m_instanceId);
        m_conn.commit();
        m_loadThread.setDaemon(true);
        m_loadThread.start();
        if (LOG.isDebugEnabled())
            LOG.debug("ClientStatsLoader has been started");
    }

    public synchronized void stop() throws InterruptedException {
        m_shouldStop = true;
        notifyAll();
        while (!m_stopped) {
            wait();
        }
    }

    private boolean m_shouldStop = false;
    private boolean m_stopped = false;

    private class Loader implements Runnable {
        @Override
        public void run() {
            long sleepLess = 0;
            synchronized (ClientStatsSqlLoader.this) {
                try {
                    while (true) {
                        if (m_shouldStop) {
                            break;
                        }
                        try {
                            if (m_pollInterval - sleepLess > 0) {
                                ClientStatsSqlLoader.this.wait(m_pollInterval
                                        - sleepLess);
                            }
                        } catch (InterruptedException e) {
                            return;
                        }

                        final long startTime = System.currentTimeMillis();
                        final VoltTable ioStats = m_distributer
                                .getConnectionStats(true);
                        final VoltTable procedureStats = m_distributer
                                .getProcedureStats(true);

                        try {
                            while (ioStats.advanceRow()) {
                                int index = 1;
                                insertConnectionStatsStmt.setInt(index++,
                                        m_instanceId);
                                insertConnectionStatsStmt.setTimestamp(index++,
                                        new Timestamp(ioStats.getLong("TIMESTAMP")));
                                insertConnectionStatsStmt.setString(index++,
                                        ioStats.getString("HOSTNAME"));
                                insertConnectionStatsStmt.setLong(index++,
                                        ioStats.getLong("CONNECTION_ID"));
                                insertConnectionStatsStmt
                                        .setInt(index++, (int) ioStats
                                                .getLong("SERVER_HOST_ID"));
                                insertConnectionStatsStmt.setString(index++,
                                        ioStats.getString("SERVER_HOSTNAME"));
                                insertConnectionStatsStmt
                                        .setLong(
                                                index++,
                                                ioStats
                                                        .getLong("SERVER_CONNECTION_ID"));
                                insertConnectionStatsStmt
                                        .setLong(
                                                index++,
                                                ioStats
                                                        .getLong("INVOCATIONS_COMPLETED"));
                                insertConnectionStatsStmt.setLong(index++,
                                        ioStats.getLong("INVOCATIONS_ABORTED"));
                                insertConnectionStatsStmt.setLong(index++,
                                        ioStats.getLong("INVOCATIONS_FAILED"));
                                insertConnectionStatsStmt.setLong(index++,
                                        ioStats.getLong("INVOCATIONS_THROTTLED"));
                                insertConnectionStatsStmt.setLong(index++,
                                        ioStats.getLong("BYTES_READ"));
                                insertConnectionStatsStmt.setLong(index++,
                                        ioStats.getLong("MESSAGES_READ"));
                                insertConnectionStatsStmt.setLong(index++,
                                        ioStats.getLong("BYTES_WRITTEN"));
                                insertConnectionStatsStmt.setLong(index++,
                                        ioStats.getLong("MESSAGES_WRITTEN"));
                                insertConnectionStatsStmt.addBatch();
                            }
                            insertConnectionStatsStmt.executeBatch();
                        } catch (SQLException e) {
                            if (e.getCause() instanceof InterruptedException) {
                                return;
                            }
                            e.printStackTrace();
                        }

                        try {
                            while (procedureStats.advanceRow()) {
                                int index = 1;
                                insertProcedureStatsStmt.setInt(index++,
                                        m_instanceId);
                                insertProcedureStatsStmt.setTimestamp(index++,
                                        new Timestamp(procedureStats.getLong("TIMESTAMP")));
                                insertProcedureStatsStmt.setString(index++,
                                        procedureStats.getString("HOSTNAME"));
                                insertProcedureStatsStmt
                                        .setLong(index++, procedureStats
                                                .getLong("CONNECTION_ID"));
                                insertProcedureStatsStmt.setInt(index++,
                                        (int) procedureStats
                                                .getLong("SERVER_HOST_ID"));
                                insertProcedureStatsStmt.setString(index++,
                                        procedureStats
                                                .getString("SERVER_HOSTNAME"));
                                insertProcedureStatsStmt
                                        .setLong(
                                                index++,
                                                procedureStats
                                                        .getLong("SERVER_CONNECTION_ID"));
                                insertProcedureStatsStmt.setString(index++,
                                        procedureStats
                                                .getString("PROCEDURE_NAME"));
                                insertProcedureStatsStmt.setInt(index++,
                                        (int) procedureStats
                                                .getLong("ROUNDTRIPTIME_AVG"));
                                insertProcedureStatsStmt.setInt(index++,
                                        (int) procedureStats
                                                .getLong("ROUNDTRIPTIME_MIN"));
                                insertProcedureStatsStmt.setInt(index++,
                                        (int) procedureStats
                                                .getLong("ROUNDTRIPTIME_MAX"));
                                insertProcedureStatsStmt
                                        .setInt(
                                                index++,
                                                (int) procedureStats
                                                        .getLong("CLUSTER_ROUNDTRIPTIME_AVG"));
                                insertProcedureStatsStmt
                                        .setInt(
                                                index++,
                                                (int) procedureStats
                                                        .getLong("CLUSTER_ROUNDTRIPTIME_MIN"));
                                insertProcedureStatsStmt
                                        .setInt(
                                                index++,
                                                (int) procedureStats
                                                        .getLong("CLUSTER_ROUNDTRIPTIME_MAX"));
                                insertProcedureStatsStmt
                                        .setLong(
                                                index++,
                                                procedureStats
                                                        .getLong("INVOCATIONS_COMPLETED"));
                                insertProcedureStatsStmt
                                        .setLong(index++, procedureStats
                                                .getLong("INVOCATIONS_ABORTED"));
                                insertProcedureStatsStmt.setLong(index++,
                                        procedureStats
                                                .getLong("INVOCATIONS_FAILED"));
                                insertProcedureStatsStmt.setLong(index++,
                                        procedureStats
                                                .getLong("TIMES_RESTARTED"));
                                insertProcedureStatsStmt.addBatch();
                            }
                            insertProcedureStatsStmt.executeBatch();
                        } catch (SQLException e) {
                            if (e.getCause() instanceof InterruptedException) {
                                return;
                            }
                            e.printStackTrace();
                        }
                        try {
                            m_conn.commit();
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                        final long endTime = System.currentTimeMillis();
                        sleepLess = endTime - startTime;
                    }
                } finally {
                    m_stopped = true;
                    ClientStatsSqlLoader.this.notifyAll();
                }
            }
        }
    }
}
TOP

Related Classes of org.voltdb.client.ClientStatsSqlLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.