You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by vj...@apache.org on 2023/07/29 01:37:49 UTC
[phoenix] branch 5.1 updated: PHOENIX-6989 Expose server side metrics for DDL operations (#1649)
This is an automated email from the ASF dual-hosted git repository.
vjasani pushed a commit to branch 5.1
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/5.1 by this push:
new 7657bb605f PHOENIX-6989 Expose server side metrics for DDL operations (#1649)
7657bb605f is described below
commit 7657bb605f108f09a8ff521357036585511cc7db
Author: Jing Yu <yu...@salesforce.com>
AuthorDate: Fri Jul 28 21:37:43 2023 -0400
PHOENIX-6989 Expose server side metrics for DDL operations (#1649)
---
.../apache/phoenix/monitoring/IndexMetricsIT.java | 6 +-
.../phoenix/monitoring/MetadataMetricsIT.java | 154 +++++++++++++++++++++
.../phoenix/coprocessor/MetaDataEndpointImpl.java | 66 ++++++++-
.../index/metrics/MetricsIndexerSourceFactory.java | 2 +-
.../schema/metrics/MetricsMetadataSource.java | 122 ++++++++++++++++
.../metrics/MetricsMetadataSourceFactory.java | 40 ++++++
.../schema/metrics/MetricsMetadataSourceImpl.java | 123 ++++++++++++++++
7 files changed, 505 insertions(+), 8 deletions(-)
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/monitoring/IndexMetricsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/monitoring/IndexMetricsIT.java
index 36c8dd934d..d6ea8145f6 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/monitoring/IndexMetricsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/monitoring/IndexMetricsIT.java
@@ -191,17 +191,17 @@ public class IndexMetricsIT extends ParallelStatsDisabledIT {
registry, ageOfUnverifiedRow);
}
- private void verifyHistogram(String counterName, DynamicMetricsRegistry registry) {
+ public static void verifyHistogram(String counterName, DynamicMetricsRegistry registry) {
verifyHistogram(counterName, registry, TIME_VAL);
}
- private void verifyHistogram(String counterName,
+ public static void verifyHistogram(String counterName,
DynamicMetricsRegistry registry, long max) {
MutableHistogram histogram = registry.getHistogram(counterName);
assertEquals(max, histogram.getMax());
}
- private void verifyCounter(String counterName, DynamicMetricsRegistry registry) {
+ public static void verifyCounter(String counterName, DynamicMetricsRegistry registry) {
MutableFastCounter counter = registry.getCounter(counterName, 0);
assertEquals(1, counter.value());
}
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/monitoring/MetadataMetricsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/monitoring/MetadataMetricsIT.java
new file mode 100644
index 0000000000..62263e1265
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/monitoring/MetadataMetricsIT.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.phoenix.monitoring;
+
+import org.apache.hadoop.metrics2.lib.DynamicMetricsRegistry;
+import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
+import org.apache.phoenix.end2end.ParallelStatsDisabledTest;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.metrics.MetricsMetadataSource;
+import org.apache.phoenix.schema.metrics.MetricsMetadataSourceImpl;
+import org.apache.phoenix.thirdparty.com.google.common.collect.Maps;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.util.Map;
+
+@Category(ParallelStatsDisabledTest.class)
+public class MetadataMetricsIT extends ParallelStatsDisabledIT {
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ Map<String, String> props = Maps.newHashMapWithExpectedSize(3);
+ props.put(QueryServices.TASK_HANDLING_INITIAL_DELAY_MS_ATTRIB, Long.toString(Long.MAX_VALUE));
+ // disable renewing leases as this will force spooling to happen.
+ props.put(QueryServices.RENEW_LEASE_ENABLED, String.valueOf(false));
+ setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+ }
+
+ @Test
+ public void testCreateTableMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementCreateTableCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.CREATE_TABLE_COUNT, registry);
+ }
+
+ @Test
+ public void testCreateViewMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementCreateViewCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.CREATE_VIEW_COUNT, registry);
+ }
+
+ @Test
+ public void testCreateIndexMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementCreateIndexCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.CREATE_INDEX_COUNT, registry);
+ }
+
+ @Test
+ public void testCreateSchemaMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementCreateSchemaCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.CREATE_SCHEMA_COUNT, registry);
+ }
+
+ @Test
+ public void testCreateFunctionMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementCreateFunctionCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.CREATE_FUNCTION_COUNT, registry);
+ }
+
+ @Test
+ public void testAlterAddColumnsMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementAlterAddColumnCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.ALTER_ADD_COLUMN_COUNT, registry);
+ }
+
+ @Test
+ public void testAlterDropColumnsMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementAlterDropColumnCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.ALTER_DROP_COLUMN_COUNT, registry);
+ }
+
+ @Test
+ public void testDropTableMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementDropTableCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.DROP_TABLE_COUNT, registry);
+ }
+
+ @Test
+ public void testDropViewMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementDropViewCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.DROP_VIEW_COUNT, registry);
+ }
+
+ @Test
+ public void testDropIndexMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementDropIndexCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.DROP_INDEX_COUNT, registry);
+ }
+
+ @Test
+ public void testDropSchemaMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementDropSchemaCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.DROP_SCHEMA_COUNT, registry);
+ }
+
+ @Test
+ public void testDropFunctionMetrics() {
+ MetricsMetadataSourceImpl metadataSource = new MetricsMetadataSourceImpl();
+ DynamicMetricsRegistry registry = metadataSource.getMetricsRegistry();
+
+ metadataSource.incrementDropFunctionCount();
+ IndexMetricsIT.verifyCounter(MetricsMetadataSource.DROP_FUNCTION_COUNT, registry);
+ }
+}
\ No newline at end of file
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index b1ccb85571..b4bba44947 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -220,6 +220,8 @@ import org.apache.phoenix.schema.SequenceKey;
import org.apache.phoenix.schema.SequenceNotFoundException;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.schema.metrics.MetricsMetadataSource;
+import org.apache.phoenix.schema.metrics.MetricsMetadataSourceFactory;
import org.apache.phoenix.schema.task.SystemTaskParams;
import org.apache.phoenix.schema.task.Task;
import org.apache.phoenix.schema.types.PBinary;
@@ -556,6 +558,8 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
// before 4.15, so that we can rollback the upgrade to 4.15 if required
private boolean allowSplittableSystemCatalogRollback;
+ private MetricsMetadataSource metricsSource;
+
public static void setFailConcurrentMutateAddColumnOneTimeForTesting(boolean fail) {
failConcurrentMutateAddColumnOneTimeForTesting = fail;
}
@@ -596,6 +600,7 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
// Start the phoenix trace collection
Tracing.addTraceMetricsSource();
Metrics.ensureConfigured();
+ metricsSource = MetricsMetadataSourceFactory.getMetadataMetricsSource();
}
@Override
@@ -2181,6 +2186,9 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
builder.setTable(PTableImpl.toProto(newTable));
}
done.run(builder.build());
+
+ updateCreateTableDdlSuccessMetrics(tableType);
+ LOGGER.info("{} created successfully, tableName: {}", tableType, fullTableName);
} finally {
ServerUtil.releaseRowLocks(locks);
}
@@ -2191,6 +2199,16 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
}
}
+ private void updateCreateTableDdlSuccessMetrics(PTableType tableType) {
+ if (tableType == PTableType.TABLE || tableType == PTableType.SYSTEM) {
+ metricsSource.incrementCreateTableCount();
+ } else if (tableType == PTableType.VIEW) {
+ metricsSource.incrementCreateViewCount();
+ } else if (tableType == PTableType.INDEX) {
+ metricsSource.incrementCreateIndexCount();
+ }
+ }
+
private long getViewIndexSequenceValue(PhoenixConnection connection, String tenantIdStr, PTable parentTable, PName physicalName) throws SQLException {
int nSequenceSaltBuckets = connection.getQueryServices().getSequenceSaltBuckets();
@@ -2252,6 +2270,7 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
byte[] tenantIdBytes = rowKeyMetaData[PhoenixDatabaseMetaData.TENANT_ID_INDEX];
schemaName = rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX];
tableOrViewName = rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX];
+ String fullTableName = SchemaUtil.getTableName(schemaName, tableOrViewName);
PTableType pTableType = PTableType.fromSerializedValue(tableType);
// Disallow deletion of a system table
if (pTableType == PTableType.SYSTEM) {
@@ -2436,6 +2455,9 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
done.run(MetaDataMutationResult.toProto(result));
dropTableStats = true;
+
+ updateDropTableDdlSuccessMetrics(pTableType);
+ LOGGER.info("{} dropped successfully, tableName: {}", pTableType, fullTableName);
} finally {
ServerUtil.releaseRowLocks(locks);
if (dropTableStats) {
@@ -2453,6 +2475,16 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
}
}
+ private void updateDropTableDdlSuccessMetrics(PTableType pTableType) {
+ if (pTableType == PTableType.TABLE || pTableType == PTableType.SYSTEM) {
+ metricsSource.incrementDropTableCount();
+ } else if (pTableType == PTableType.VIEW) {
+ metricsSource.incrementDropViewCount();
+ } else if (pTableType == PTableType.INDEX) {
+ metricsSource.incrementDropIndexCount();
+ }
+ }
+
private static class StatsDeleteHandler implements Runnable {
PTable deletedTable;
List<byte[]> physicalTableNames;
@@ -3118,6 +3150,12 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
request.getClientVersion(), parentTable, addingColumns);
if (result != null) {
done.run(MetaDataMutationResult.toProto(result));
+
+ if (result.getMutationCode() == MutationCode.TABLE_ALREADY_EXISTS) {
+ metricsSource.incrementAlterAddColumnCount();
+ LOGGER.info("Column(s) added successfully, tableName: {}",
+ result.getTable().getTableName());
+ }
}
} catch (Throwable e) {
LOGGER.error("Add column failed: ", e);
@@ -3256,6 +3294,12 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
request.getClientVersion(), parentTable, true);
if (result != null) {
done.run(MetaDataMutationResult.toProto(result));
+
+ if (result.getMutationCode() == MutationCode.TABLE_ALREADY_EXISTS) {
+ metricsSource.incrementAlterDropColumnCount();
+ LOGGER.info("Column(s) dropped successfully, tableName: {}",
+ result.getTable().getTableName());
+ }
}
} catch (Throwable e) {
LOGGER.error("Drop column failed: ", e);
@@ -3324,6 +3368,10 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
if (result.getMutationCode() != MutationCode.TABLE_ALREADY_EXISTS) {
return result;
}
+ metricsSource.incrementDropIndexCount();
+ LOGGER.info("INDEX dropped successfully, tableName: {}",
+ result.getTable().getTableName());
+
// there should be no child links to delete since we are just dropping an index
if (!childLinksMutations.isEmpty()) {
LOGGER.error("Found unexpected child link mutations while dropping an index "
@@ -3985,7 +4033,10 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
builder.setReturnCode(MetaDataProtos.MutationCode.FUNCTION_NOT_FOUND);
builder.setMutationTime(currentTimeStamp);
done.run(builder.build());
- return;
+
+ metricsSource.incrementCreateFunctionCount();
+ LOGGER.info("FUNCTION created successfully, functionName: {}",
+ Bytes.toString(functionName));
} finally {
ServerUtil.releaseRowLocks(locks);
}
@@ -4038,7 +4089,10 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
}
done.run(MetaDataMutationResult.toProto(result));
- return;
+
+ metricsSource.incrementDropFunctionCount();
+ LOGGER.info("FUNCTION dropped successfully, functionName: {}",
+ Bytes.toString(functionName));
} finally {
ServerUtil.releaseRowLocks(locks);
}
@@ -4153,7 +4207,9 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
builder.setReturnCode(MetaDataProtos.MutationCode.SCHEMA_NOT_FOUND);
builder.setMutationTime(currentTimeStamp);
done.run(builder.build());
- return;
+
+ metricsSource.incrementCreateSchemaCount();
+ LOGGER.info("SCHEMA created successfully, schemaName: {}", schemaName);
} finally {
ServerUtil.releaseRowLocks(locks);
}
@@ -4197,7 +4253,9 @@ TABLE_FAMILY_BYTES, TABLE_SEQ_NUM_BYTES);
metaDataCache.put(ptr, newDeletedSchemaMarker(currentTime));
}
done.run(MetaDataMutationResult.toProto(result));
- return;
+
+ metricsSource.incrementDropSchemaCount();
+ LOGGER.info("SCHEMA dropped successfully, schemaName: {}", schemaName);
} finally {
ServerUtil.releaseRowLocks(locks);
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/metrics/MetricsIndexerSourceFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/metrics/MetricsIndexerSourceFactory.java
index b105290afc..baf27f4cf8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/metrics/MetricsIndexerSourceFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/metrics/MetricsIndexerSourceFactory.java
@@ -21,7 +21,7 @@ package org.apache.phoenix.hbase.index.metrics;
*/
public class MetricsIndexerSourceFactory {
private static final MetricsIndexerSourceFactory INSTANCE = new MetricsIndexerSourceFactory();
- private MetricsIndexerSource indexerSource;
+ private volatile MetricsIndexerSource indexerSource;
private GlobalIndexCheckerSource globalIndexCheckerSource;
private MetricsIndexerSourceFactory() {}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSource.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSource.java
new file mode 100644
index 0000000000..130b6c46f9
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSource.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.phoenix.schema.metrics;
+
+public interface MetricsMetadataSource {
+ // Metrics2 and JMX constants
+ String METRICS_NAME = "PhoenixMetadata";
+ String METRICS_CONTEXT = "phoenix";
+ String METRICS_DESCRIPTION = "Metrics about the Phoenix MetadataEndpoint";
+ String METRICS_JMX_CONTEXT = "RegionServer,sub=" + METRICS_NAME;
+
+ String CREATE_TABLE_COUNT = "createTableCount";
+ String CREATE_TABLE_COUNT_DESC = "Count of CREATE TABLE DDL statements";
+
+ String CREATE_VIEW_COUNT = "createViewCount";
+ String CREATE_VIEW_COUNT_DESC = "Count of CREATE VIEW DDL statements";
+
+ String CREATE_INDEX_COUNT = "createIndexCount";
+ String CREATE_INDEX_COUNT_DESC = "Count of CREATE INDEX DDL statements";
+
+ String CREATE_SCHEMA_COUNT = "createSchemaCount";
+ String CREATE_SCHEMA_COUNT_DESC = "Count of CREATE SCHEMA DDL statements";
+
+ String CREATE_FUNCTION_COUNT = "createFunctionCount";
+ String CREATE_FUNCTION_COUNT_DESC = "Count of CREATE FUNCTION DDL statements";
+
+ String ALTER_ADD_COLUMN_COUNT = "alterAddColumnCount";
+ String ALTER_ADD_COLUMN_COUNT_DESC = "Count of ALTER statements that add columns";
+
+ String ALTER_DROP_COLUMN_COUNT = "alterDropColumnCount";
+ String ALTER_DROP_COLUMN_COUNT_DESC = "Count of ALTER statements that drop columns";
+
+ String DROP_TABLE_COUNT = "dropTableCount";
+ String DROP_TABLE_COUNT_DESC = "Count of DROP TABLE DDL statements";
+
+ String DROP_VIEW_COUNT = "dropViewCount";
+ String DROP_VIEW_COUNT_DESC = "Count of DROP VIEW DDL statements";
+
+ String DROP_INDEX_COUNT = "dropIndexCount";
+ String DROP_INDEX_COUNT_DESC = "Count of DROP INDEX DDL statements";
+
+ String DROP_SCHEMA_COUNT = "dropSchemaCount";
+ String DROP_SCHEMA_COUNT_DESC = "Count of DROP SCHEMA DDL statements";
+
+ String DROP_FUNCTION_COUNT = "dropFunctionCount";
+ String DROP_FUNCTION_COUNT_DESC = "Count of DROP FUNCTION DDL statements";
+
+ /**
+ * Updates the count of successful CREATE TABLE DDL operations
+ */
+ void incrementCreateTableCount();
+
+ /**
+ * Updates the count of successful CREATE VIEW DDL operations
+ */
+ void incrementCreateViewCount();
+
+ /**
+ * Updates the count of successful CREATE INDEX DDL operations
+ */
+ void incrementCreateIndexCount();
+
+ /**
+ * Updates the count of successful CREATE SCHEMA DDL operations
+ */
+ void incrementCreateSchemaCount();
+
+ /**
+ * Updates the count of successful CREATE FUNCTION DDL operations
+ */
+ void incrementCreateFunctionCount();
+
+ /**
+ * Updates the count of successful ALTER DDL operations that add columns
+ */
+ void incrementAlterAddColumnCount();
+
+ /**
+ * Updates the count of successful ALTER DDL operations that drop columns
+ */
+ void incrementAlterDropColumnCount();
+
+ /**
+ * Updates the count of successful DROP TABLE DDL operations
+ */
+ void incrementDropTableCount();
+
+ /**
+ * Updates the count of successful DROP VIEW DDL operations
+ */
+ void incrementDropViewCount();
+
+ /**
+ * Updates the count of successful DROP INDEX DDL operations
+ */
+ void incrementDropIndexCount();
+
+ /**
+ * Updates the count of successful DROP SCHEMA DDL operations
+ */
+ void incrementDropSchemaCount();
+
+ /**
+ * Updates the count of successful DROP FUNCTION DDL operations
+ */
+ void incrementDropFunctionCount();
+}
\ No newline at end of file
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSourceFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSourceFactory.java
new file mode 100644
index 0000000000..d21e36abfd
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSourceFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.phoenix.schema.metrics;
+
+/**
+ * Factory class for creating {@link MetricsMetadataSource} instances
+ */
+public class MetricsMetadataSourceFactory {
+ private static final MetricsMetadataSourceFactory INSTANCE = new MetricsMetadataSourceFactory();
+
+ private volatile MetricsMetadataSource metricsMetadataSource;
+
+ private MetricsMetadataSourceFactory() {}
+
+ public static MetricsMetadataSourceFactory getInstance() {
+ return INSTANCE;
+ }
+
+ public static synchronized MetricsMetadataSource getMetadataMetricsSource() {
+ if (INSTANCE.metricsMetadataSource == null) {
+ INSTANCE.metricsMetadataSource = new MetricsMetadataSourceImpl();
+ }
+ return INSTANCE.metricsMetadataSource;
+ }
+}
\ No newline at end of file
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSourceImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSourceImpl.java
new file mode 100644
index 0000000000..33c8ddf527
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSourceImpl.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.phoenix.schema.metrics;
+
+import org.apache.hadoop.hbase.metrics.BaseSourceImpl;
+import org.apache.hadoop.metrics2.lib.MutableFastCounter;
+
+public class MetricsMetadataSourceImpl extends BaseSourceImpl implements MetricsMetadataSource {
+
+ private final MutableFastCounter createTableCount;
+ private final MutableFastCounter createViewCount;
+ private final MutableFastCounter createIndexCount;
+ private final MutableFastCounter createSchemaCount;
+ private final MutableFastCounter createFunctionCount;
+
+ private final MutableFastCounter alterAddColumnCount;
+ private final MutableFastCounter alterDropColumnCount;
+
+ private final MutableFastCounter dropTableCount;
+ private final MutableFastCounter dropViewCount;
+ private final MutableFastCounter dropIndexCount;
+ private final MutableFastCounter dropSchemaCount;
+ private final MutableFastCounter dropFunctionCount;
+
+ public MetricsMetadataSourceImpl() {
+ this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT);
+ }
+
+ public MetricsMetadataSourceImpl(String metricsName, String metricsDescription,
+ String metricsContext, String metricsJmxContext) {
+ super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
+
+ createTableCount = getMetricsRegistry().newCounter(CREATE_TABLE_COUNT,
+ CREATE_TABLE_COUNT_DESC, 0L);
+ createViewCount = getMetricsRegistry().newCounter(CREATE_VIEW_COUNT,
+ CREATE_VIEW_COUNT_DESC, 0L);
+ createIndexCount = getMetricsRegistry().newCounter(CREATE_INDEX_COUNT,
+ CREATE_INDEX_COUNT_DESC, 0L);
+ createFunctionCount = getMetricsRegistry().newCounter(CREATE_FUNCTION_COUNT,
+ CREATE_FUNCTION_COUNT_DESC, 0L);
+ createSchemaCount = getMetricsRegistry().newCounter(CREATE_SCHEMA_COUNT,
+ CREATE_SCHEMA_COUNT_DESC, 0L);
+
+ alterAddColumnCount = getMetricsRegistry().newCounter(ALTER_ADD_COLUMN_COUNT,
+ ALTER_ADD_COLUMN_COUNT_DESC, 0L);
+ alterDropColumnCount = getMetricsRegistry().newCounter(ALTER_DROP_COLUMN_COUNT,
+ ALTER_DROP_COLUMN_COUNT_DESC, 0L);
+
+ dropTableCount = getMetricsRegistry().newCounter(DROP_TABLE_COUNT,
+ DROP_TABLE_COUNT_DESC, 0L);
+ dropViewCount = getMetricsRegistry().newCounter(DROP_VIEW_COUNT,
+ DROP_VIEW_COUNT_DESC, 0L);
+ dropIndexCount = getMetricsRegistry().newCounter(DROP_INDEX_COUNT,
+ DROP_INDEX_COUNT_DESC, 0L);
+ dropSchemaCount = getMetricsRegistry().newCounter(DROP_SCHEMA_COUNT,
+ DROP_SCHEMA_COUNT_DESC, 0L);
+ dropFunctionCount = getMetricsRegistry().newCounter(DROP_FUNCTION_COUNT,
+ DROP_FUNCTION_COUNT_DESC, 0L);
+ }
+
+ @Override public void incrementCreateTableCount() {
+ createTableCount.incr();
+ }
+
+ @Override public void incrementCreateViewCount() {
+ createViewCount.incr();
+ }
+
+ @Override public void incrementCreateIndexCount() {
+ createIndexCount.incr();
+ }
+
+ @Override public void incrementCreateSchemaCount() {
+ createSchemaCount.incr();
+ }
+
+ @Override public void incrementCreateFunctionCount() {
+ createFunctionCount.incr();
+ }
+
+ @Override public void incrementAlterAddColumnCount() {
+ alterAddColumnCount.incr();
+ }
+
+ @Override public void incrementAlterDropColumnCount() {
+ alterDropColumnCount.incr();
+ }
+
+ @Override public void incrementDropTableCount() {
+ dropTableCount.incr();
+ }
+
+ @Override public void incrementDropViewCount() {
+ dropViewCount.incr();
+ }
+
+ @Override public void incrementDropIndexCount() {
+ dropIndexCount.incr();
+ }
+
+ @Override public void incrementDropSchemaCount() {
+ dropSchemaCount.incr();
+ }
+
+ @Override public void incrementDropFunctionCount() {
+ dropFunctionCount.incr();
+ }
+}
\ No newline at end of file