Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SAP HANA DB Metrics Collector #11

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rdb/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies {

implementation("mysql:mysql-connector-java:5.1.46")
implementation(files("libs/DmJdbcDriver18.jar"))
implementation(files("libs/ngdbc-2.4.64.jar"))
}

application {
Expand Down
17 changes: 17 additions & 0 deletions rdb/config/config-hana.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#Database properties:
db.system: hana
db.driver: com.sap.db.jdbc.Driver
instances:
- db.address: 9.42.129.183
db.port: 30015
db.username: D4MON
db.password: UGVyZjBybS4=
db.connection.url: jdbc:sap://9.42.129.183:30015
db.name: ML4
#Data collector properties:
poll.interval: 30
callback.interval: 20
otel.backend.url: http://127.0.0.1:4317
#otel.backend.using.http: true
#OTel properties:
otel.service.name: SAPHana
Binary file added rdb/libs/ngdbc-2.4.64.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class DbDcRegistry {
private final Map<String, Class<? extends AbstractDbDc>> map = new HashMap<String, Class<? extends AbstractDbDc>>() {{
put("DAMENG", DamengDc.class);
put("OCEANBASE4", Oceanbase4Dc.class);
put("HANA", HanaDc.class);
}};

public Class<? extends AbstractDbDc> findDatabaseDc(String dbSystem) throws DcException {
Expand Down
87 changes: 87 additions & 0 deletions rdb/src/main/java/com/instana/dc/rdb/impl/HanaDc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* (c) Copyright IBM Corp. 2023
* (c) Copyright Instana Inc.
*/
package com.instana.dc.rdb.impl;

import com.instana.dc.CalculationMode;
import com.instana.dc.DcUtil;
import com.instana.dc.rdb.AbstractDbDc;
import com.instana.dc.rdb.DbDcUtil;
import io.opentelemetry.api.OpenTelemetry;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import static com.instana.agent.sensorsdk.semconv.SemanticAttributes.*;
import static com.instana.dc.rdb.DbDcUtil.*;

import static com.instana.dc.rdb.impl.HanaUtil.*;


public class HanaDc extends AbstractDbDc {

private static final Logger logger = Logger.getLogger(HanaDc.class.getName());

public HanaDc(Map<String, String> properties, String dbSystem, String dbDriver) throws SQLException {
super(properties, dbSystem, dbDriver);
setDbPassword(DcUtil.base64Decode(getDbPassword()));
findDbNameAndVersion();
if (getServiceInstanceId() == null) {
setServiceInstanceId(getDbAddress() + ":" + getDbPort() + "@" + getDbName());
}
}

@Override
public void registerMetrics() {
super.registerMetrics();
getRawMetric(DB_TRANSACTION_RATE_NAME).setCalculationMode(CalculationMode.RATE);
getRawMetric(DB_SQL_RATE_NAME).setCalculationMode(CalculationMode.RATE);
getRawMetric(DB_IO_READ_RATE_NAME).setCalculationMode(CalculationMode.RATE);
getRawMetric(DB_IO_WRITE_RATE_NAME).setCalculationMode(CalculationMode.RATE);
}

private void findDbNameAndVersion() throws SQLException {
try (Connection connection = getConnection()) {
ResultSet rs = DbDcUtil.executeQuery(connection, DB_NAME_VERSION_SQL);
rs.next();
if (getDbName() == null)
setDbName(rs.getString(1));
setDbVersion(rs.getString(2));
}
}

@Override
public void collectData() {
logger.info("Start to collect metrics");
try (Connection conn = getConnection()) {

getRawMetric(DB_STATUS_NAME).setValue(1);
getRawMetric(DB_INSTANCE_COUNT_NAME).setValue(getSimpleMetricWithSql(conn, INSTANCE_COUNT_SQL));
getRawMetric(DB_INSTANCE_ACTIVE_COUNT_NAME).setValue(getSimpleMetricWithSql(conn, INSTANCE_ACTIVE_COUNT_SQL));

getRawMetric(DB_SESSION_COUNT_NAME).setValue(getSimpleMetricWithSql(conn, SESSION_COUNT_SQL));
getRawMetric(DB_SESSION_ACTIVE_COUNT_NAME).setValue(getSimpleMetricWithSql(conn, SESSION_ACTIVE_COUNT_SQL));
getRawMetric(DB_TRANSACTION_COUNT_NAME).setValue(getSimpleMetricWithSql(conn, TRANSACTION_COUNT_SQL));
getRawMetric(DB_TRANSACTION_RATE_NAME).setValue(getSimpleMetricWithSql(conn, TRANSACTION_RATE_SQL));
getRawMetric(DB_TRANSACTION_LATENCY_NAME).setValue(getSimpleMetricWithSql(conn, TRANSACTION_LATENCY_SQL));
getRawMetric(DB_SQL_COUNT_NAME).setValue(getSimpleMetricWithSql(conn, SQL_COUNT_SQL));
getRawMetric(DB_SQL_RATE_NAME).setValue(getSimpleMetricWithSql(conn, SQL_RATE_SQL));
getRawMetric(DB_IO_READ_RATE_NAME).setValue(getSimpleMetricWithSql(conn, IO_READ_COUNT_SQL));
getRawMetric(DB_IO_WRITE_RATE_NAME).setValue(getSimpleMetricWithSql(conn, IO_WRITE_COUNT_SQL));
getRawMetric(DB_TASK_WAIT_COUNT_NAME).setValue(getSimpleMetricWithSql(conn, TASK_WAIT_COUNT_SQL));
getRawMetric(DB_TASK_AVG_WAIT_TIME_NAME).setValue(getSimpleMetricWithSql(conn, TASK_AVG_WAIT_TIME_SQL));
getRawMetric(DB_CPU_UTILIZATION_NAME).setValue(getSimpleMetricWithSql(conn, CPU_UTILIZATION_SQL));
getRawMetric(DB_MEM_UTILIZATION_NAME).setValue(getSimpleMetricWithSql(conn, MEMORY_UTILIZATION));
}catch (Exception e) {
logger.log(Level.SEVERE, "Failed to update metric with exception", e);
getRawMetric(DB_STATUS_NAME).setValue(0);
}

}
}
27 changes: 27 additions & 0 deletions rdb/src/main/java/com/instana/dc/rdb/impl/HanaUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.instana.dc.rdb.impl;

public class HanaUtil {

public static final String DB_NAME_VERSION_SQL = "select DATABASE_NAME, VERSION from SYS.M_DATABASE";
public static final String TRANSACTION_COUNT_SQL = "SELECT COUNT(*) AS transaction_count from M_TRANSACTIONS";

public static final String TRANSACTION_RATE_SQL = "SELECT CURRENT_TRANSACTION_RATE FROM SYS.M_WORKLOAD";
public static final String TRANSACTION_LATENCY_SQL = "SELECT SUM(floor( mod( (seconds_between(START_TIME,END_TIME)) , 3600) / 60 ) ) AS TOTAL_TRANSACTION_LATENCY_SECONDS FROM M_TRANSACTIONS";

public static final String SQL_COUNT_SQL = "SELECT COUNT(*) AS sql_statement_count FROM M_SQL_PLAN_CACHE";
public static final String SQL_RATE_SQL = "SELECT SUM(AVG_EXECUTION_FETCH_TIME) As latency FROM M_SQL_PLAN_CACHE";

public static final String IO_READ_COUNT_SQL = "SELECT EXECUTION_COUNT FROM SYS.M_WORKLOAD";
public static final String IO_WRITE_COUNT_SQL = "SELECT EXECUTION_COUNT FROM SYS.M_WORKLOAD";
public static final String TASK_WAIT_COUNT_SQL = "SELECT EXECUTION_COUNT FROM SYS.M_WORKLOAD";
public static final String TASK_AVG_WAIT_TIME_SQL = "SELECT TOTAL_LOCK_WAIT_TIME FROM M_LOCK_WAITS_STATISTICS";

public static final String SESSION_COUNT_SQL = "SELECT COUNT(*) as TOTAL_SESSIONS FROM M_SESSION_CONTEXT";

public static final String SESSION_ACTIVE_COUNT_SQL = "SELECT COUNT(*) as TOTAL_SESSIONS FROM M_SESSION_CONTEXT";
public static final String INSTANCE_COUNT_SQL = "SELECT COUNT(*) FROM SYS.M_SYSTEM_OVERVIEW where Name = 'All Started'";
public static final String INSTANCE_ACTIVE_COUNT_SQL = "SELECT COUNT(*) FROM SYS.M_SYSTEM_OVERVIEW where Name = 'All Started'";
public static final String CPU_UTILIZATION_SQL = "SELECT TOTAL_CPU_SYSTEM_TIME FROM SYS.M_HOST_RESOURCE_UTILIZATION";
public static final String MEMORY_UTILIZATION = "SELECT USED_PHYSICAL_MEMORY FROM SYS.M_HOST_RESOURCE_UTILIZATION";

}