diff --git a/rdb/src/main/java/com/instana/agent/sensorsdk/semconv/SemanticAttributes.java b/rdb/src/main/java/com/instana/agent/sensorsdk/semconv/SemanticAttributes.java index 3875088..3962bd1 100644 --- a/rdb/src/main/java/com/instana/agent/sensorsdk/semconv/SemanticAttributes.java +++ b/rdb/src/main/java/com/instana/agent/sensorsdk/semconv/SemanticAttributes.java @@ -80,4 +80,7 @@ private SemanticAttributes() { public static final AttributeKey DB_CACHE_READ_RATIO = AttributeKey.longKey("db.cache.read.ratio"); public static final AttributeKey DB_CACHE_WRITE_RATIO = AttributeKey.longKey("db.cache.write.ratio"); public static final AttributeKey DB_LRU_WRITES = AttributeKey.longKey("db.lru.writes"); + public static final AttributeKey TOTAL_KB = AttributeKey.stringKey("total_kb"); + public static final AttributeKey USED_KB = AttributeKey.stringKey("used_kb"); + public static final AttributeKey TABLE_UTILIZATION = AttributeKey.stringKey("table_utilization"); } diff --git a/rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixDc.java b/rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixDc.java index 176d763..0bd4dfb 100644 --- a/rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixDc.java +++ b/rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixDc.java @@ -54,15 +54,13 @@ public class InformixDc extends AbstractDbDc { private static final Logger LOGGER = Logger.getLogger(InformixDc.class.getName()); private static final int DEFAULT_ELAPSED_TIME = 900; private String tableSpaceSizeQuery; - private String tableSpaceUsedQuery; - private String tableSpaceUtilizationQuery; - private String tableSpaceMaxQuery; private String sequentialScanQuery; private String sequentialScanTableQuery; private String sqlElapsedTimeQuery; private boolean customPollRateEnabled = true; private ScheduledExecutorService executorService; private final BasicDataSource dataSource; + private final MetricsDataQueryConfig metricDataQueryConfig; private final MetricsCollector metricCollector; @@ -76,6 +74,8 @@ public InformixDc(Map properties, String dbSystem, String dbDriv setDbConnUrl(); dataSource = getDataSource(); + metricDataQueryConfig = new MetricsDataQueryConfig(tableSpaceSizeQuery,List.class,this.dataSource,SemanticAttributes.TOTAL_KB.getKey(),DB_TABLESPACE_SIZE_KEY,SemanticAttributes.USED_KB.getKey(),SemanticAttributes.TABLE_UTILIZATION.getKey()); + if (getServiceInstanceId() == null) { setServiceInstanceId(getDbAddress() + ":" + getDbPort() + "@" + getDbName()); } @@ -103,13 +103,13 @@ private BasicDataSource getDataSource() { private void registerMetricsMetadata() { //Metrics via SQL MetricsDataConfigRegister.subscribeMetricDataConfig(DB_TABLESPACE_SIZE_NAME, - new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_SIZE_KEY)); + new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL,List.class,DB_TABLESPACE_SIZE_KEY)); MetricsDataConfigRegister.subscribeMetricDataConfig(DB_TABLESPACE_USED_NAME, - new MetricDataConfig(tableSpaceUsedQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_USED_KEY)); + new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_USED_KEY)); MetricsDataConfigRegister.subscribeMetricDataConfig(DB_TABLESPACE_UTILIZATION_NAME, - new MetricDataConfig(tableSpaceUtilizationQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_UTILIZATION_KEY)); + new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_UTILIZATION_KEY)); MetricsDataConfigRegister.subscribeMetricDataConfig(DB_TABLESPACE_MAX_NAME, - new MetricDataConfig(tableSpaceMaxQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_MAX_KEY)); + new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_MAX_KEY)); MetricsDataConfigRegister.subscribeMetricDataConfig(DB_SQL_ELAPSED_TIME_NAME, new MetricDataConfig(sqlElapsedTimeQuery, MetricCollectionMode.SQL, List.class, DB_SQL_ELAPSED_TIME_KEY, SemanticAttributes.SQL_TEXT.getKey())); MetricsDataConfigRegister.subscribeMetricDataConfig(DB_INSTANCE_COUNT_NAME, @@ -240,9 +240,6 @@ private void parseCustomAttributes(Map properties) { sequentialScanQuery = String.format(InformixUtil.DB_SEQ_SCAN_SQL, databaseName, sequentialScanCount); sequentialScanTableQuery = String.format(InformixUtil.DB_SEQ_SCAN_TABLE_SQL, databaseName, sequentialScanCount); tableSpaceSizeQuery = String.format(InformixUtil.TABLESPACE_SIZE_SQL, databaseName); - tableSpaceUsedQuery = String.format(InformixUtil.TABLESPACE_USED_SQL, databaseName); - tableSpaceUtilizationQuery = String.format(InformixUtil.TABLESPACE_UTILIZATION_SQL, databaseName); - tableSpaceMaxQuery = String.format(InformixUtil.TABLESPACE_MAX_SQL, databaseName); sqlElapsedTimeQuery = String.format(InformixUtil.SQL_ELAPSED_TIME_SQL, elapsedTimeFrame, databaseName); } @@ -326,10 +323,12 @@ private void shortPollingInterval() { @SuppressWarnings("unchecked") private void longPollingInterval() { - getRawMetric(DB_TABLESPACE_SIZE_NAME).setValue((List) metricCollector.collectMetrics(DB_TABLESPACE_SIZE_NAME)); - getRawMetric(DB_TABLESPACE_USED_NAME).setValue((List) metricCollector.collectMetrics(DB_TABLESPACE_USED_NAME)); - getRawMetric(DB_TABLESPACE_UTILIZATION_NAME).setValue((List) metricCollector.collectMetrics(DB_TABLESPACE_UTILIZATION_NAME)); - getRawMetric(DB_TABLESPACE_MAX_NAME).setValue((List) metricCollector.collectMetrics(DB_TABLESPACE_MAX_NAME)); + //TODO: A method to execute the query, store it in object, call that object in subsequent lines + metricDataQueryConfig.fetchQueryResults(); + getRawMetric(DB_TABLESPACE_SIZE_NAME).setValue((List) metricDataQueryConfig.getResults(SemanticAttributes.TOTAL_KB.getKey())); + getRawMetric(DB_TABLESPACE_USED_NAME).setValue((List) metricDataQueryConfig.getResults(SemanticAttributes.USED_KB.getKey())); + getRawMetric(DB_TABLESPACE_UTILIZATION_NAME).setValue((List) metricDataQueryConfig.getResults(SemanticAttributes.TABLE_UTILIZATION.getKey())); + getRawMetric(DB_TABLESPACE_MAX_NAME).setValue((List) metricDataQueryConfig.getResults(SemanticAttributes.TOTAL_KB.getKey())); getRawMetric(DB_DATABASE_LOG_ENABLED_NAME).setValue((List) metricCollector.collectMetrics(DB_DATABASE_LOG_ENABLED_NAME)); getRawMetric(DB_DATABASE_BUFF_LOG_ENABLED_NAME).setValue((List) metricCollector.collectMetrics(DB_DATABASE_BUFF_LOG_ENABLED_NAME)); getRawMetric(DB_DATABASE_ANSI_COMPLAINT_NAME).setValue((List) metricCollector.collectMetrics(DB_DATABASE_ANSI_COMPLAINT_NAME)); diff --git a/rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixUtil.java b/rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixUtil.java index fede7f2..98f8754 100644 --- a/rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixUtil.java +++ b/rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixUtil.java @@ -33,7 +33,7 @@ private InformixUtil() { public static final String TRANSACTION_COUNT_SQL = "SELECT COUNT(1) FROM SYSTRANS;"; public static final String SQL_ELAPSED_TIME_SQL = "SELECT SQL_RUNTIME * 1000 AS ELAPSED_TIME_MILLIS, SQL_ID AS SQL_ID, SQL_STATEMENT AS SQL_TEXT FROM INFORMIX.SYSSQLTRACE WHERE SQL_FINISHTIME >= (DBINFO('UTC_CURRENT') - %s) AND SQL_DATABASE = %s ORDER BY ELAPSED_TIME_MILLIS DESC LIMIT 20;"; //Table Space Queries - public static final String TABLESPACE_SIZE_SQL = "SELECT (PT.NPTOTAL * PT.PAGESIZE) * 1024 AS TOTAL_KB, TABNAME FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;"; + public static final String TABLESPACE_SIZE_SQL = "SELECT (PT.NPTOTAL * PT.PAGESIZE) * 1024 AS TOTAL_KB,TABNAME,(PT.NPUSED * PT.PAGESIZE) * 1024 AS USED_KB,CASE WHEN (PT.NPTOTAL > 0) THEN ((PT.NPUSED) / PT.NPTOTAL) * 100 ELSE 0 END AS TABLE_UTILIZATION FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;"; public static final String TABLESPACE_USED_SQL = "SELECT (PT.NPUSED * PT.PAGESIZE) * 1024 AS USED_KB, TABNAME FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;"; public static final String TABLESPACE_UTILIZATION_SQL = "SELECT CASE WHEN (PT.NPTOTAL > 0) THEN ((PT.NPUSED) / PT.NPTOTAL) * 100 ELSE 0 END AS TABLE_UTILIZATION, TABNAME FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;"; public static final String TABLESPACE_MAX_SQL = "SELECT (PT.NPTOTAL * PT.PAGESIZE) * 1024 AS TOTAL_KB, TABNAME FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;"; diff --git a/rdb/src/main/java/com/instana/dc/rdb/impl/informix/metric/collection/MetricsDataQueryConfig.java b/rdb/src/main/java/com/instana/dc/rdb/impl/informix/metric/collection/MetricsDataQueryConfig.java new file mode 100644 index 0000000..214aaa2 --- /dev/null +++ b/rdb/src/main/java/com/instana/dc/rdb/impl/informix/metric/collection/MetricsDataQueryConfig.java @@ -0,0 +1,108 @@ +/* + * (c) Copyright IBM Corp. 2024 + * (c) Copyright Instana Inc. + */ + +package com.instana.dc.rdb.impl.informix.metric.collection; +import static com.instana.dc.rdb.DbDcUtil.getMetricWithSql; +import static com.instana.dc.rdb.DbDcUtil.getSimpleMetricWithSql; +import com.instana.dc.SimpleQueryResult; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.commons.dbcp2.BasicDataSource; +import java.sql.Connection; +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.sql.SQLException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; + +/** + * This class which holds the meta data of a given metrics + */ +public class MetricsDataQueryConfig { + + private static final Logger logger = Logger.getLogger(MetricsDataQueryConfig.class.getName()); + private String query; + private final Class returnType; + private String metricKey; + private String scriptName; + private final BasicDataSource dataSource; + private ResultSet rs; + private String[] attr; + + private HashMap> results; + + + public MetricsDataQueryConfig(String query, Class returnType, BasicDataSource dataSource, String... attr) { + this.query = query; + this.returnType = returnType; + this.attr = attr; + this.dataSource = dataSource; + this.results = new HashMap>(); + for (int attrIndex = 0;attrIndex()); + } + } + + public void fetchQueryResults() { + try (Connection connection = this.dataSource.getConnection()) { + + ResultSet rs = executeQuery(connection, this.query); + if (rs.isClosed()) { + logger.severe("getMetricWithSql: ResultSet is closed"); + } + while (rs.next()) { + Object obj = rs.getObject(2); + if (obj == null) { + obj = "null"; + } + if (obj instanceof String) { + obj = ((String) obj).trim(); + } + for(int attrIndex = 0;attrIndex ls = this.results.get(this.attr[attrIndex]); + ls.add(result); + this.results.put(this.attr[attrIndex],ls); + } + } + } + catch (SQLException exp) { + logger.log(Level.SEVERE, "Unable to execute the sql command, Exception: " + exp); + } + } + + public static ResultSet executeQuery(Connection connection, String query) throws SQLException { + Statement statement = connection.createStatement(); + return statement.executeQuery(query); + } + + + public String getMetricKey() { + return metricKey; + } + + public String[] getAttr() { + return attr; + } + + public String getQuery() { + return query; + } + + public Class getReturnType() { + return returnType; + } + + public List getResults(String key) { + return this.results.get(key); + } +}