RANGER-2699 : JVM metrics for Ranger usersync and Ranger tagsync
Signed-off-by: Pradeep <pradeep@apache.org>
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerMetricsUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerMetricsUtil.java
new file mode 100644
index 0000000..f6eef2f
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerMetricsUtil.java
@@ -0,0 +1,189 @@
+/*
+ * 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.ranger.plugin.util;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.apache.ranger.plugin.model.RangerMetrics;
+
+import com.google.gson.Gson;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryType;
+import java.lang.management.MemoryUsage;
+
+/**
+ * Connect Worker system and runtime information.
+ */
+public class RangerMetricsUtil {
+
+ private static final Logger LOG = Logger.getLogger(RangerMetricsUtil.class);
+ private static final OperatingSystemMXBean OS;
+ private static final MemoryMXBean MEM_BEAN;
+ public static final String NL = System.getProperty("line.separator");
+
+ private static final RuntimeMXBean RUNTIME = ManagementFactory.getRuntimeMXBean();
+ private static final String JVM_MACHINE_ACTUAL_NAME = RUNTIME.getVmName();
+ private static final String VERSION = RUNTIME.getVmVersion();
+ private static final String JVM_MACHINE_REPRESENTATION_NAME = RUNTIME.getName();
+ private static final long UP_TIME_OF_JVM = RUNTIME.getUptime();
+ private static final String JVM_VENDOR_NAME = RUNTIME.getVmVendor();
+
+
+ static {
+ OS = ManagementFactory.getOperatingSystemMXBean();
+ MEM_BEAN = ManagementFactory.getMemoryMXBean();
+ }
+
+ public Map<String, Object> getValues() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerMetricsUtil.getValues()");
+ }
+
+ Map<String, Object> values = new LinkedHashMap<>();
+ values.put("os.spec", StringUtils.join(Arrays.asList(addSystemInfo()), ", "));
+ values.put("os.vcpus", String.valueOf(OS.getAvailableProcessors()));
+ values.put("memory", addMemoryDetails());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerMetricsUtil.getValues()" + values);
+ }
+
+ return values;
+ }
+
+ /**
+ * collect the pool division of java
+ */
+ protected Map<String, Object> getPoolDivision() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerMetricsUtil.getPoolDivision()");
+ }
+
+ Map<String, Object> poolDivisionValues = new LinkedHashMap<>();
+ for (MemoryPoolMXBean mpBean : ManagementFactory.getMemoryPoolMXBeans()) {
+ if (mpBean.getType() == MemoryType.HEAP) {
+ poolDivisionValues.put(mpBean.getName(), mpBean.getUsage());
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerMetricsUtil.getPoolDivision()" + poolDivisionValues);
+ }
+
+ return poolDivisionValues;
+ }
+
+ /**
+ * Add memory details
+ */
+ protected Map<String, Object> addMemoryDetails() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerMetricsUtil.addMemoryDetails()");
+ }
+
+ Map<String, Object> memory = new LinkedHashMap<>();
+ MemoryUsage memHeapUsage = MEM_BEAN.getHeapMemoryUsage();
+ MemoryUsage nonHeapUsage = MEM_BEAN.getNonHeapMemoryUsage();
+ memory.put("heapInit", String.valueOf(memHeapUsage.getInit()));
+ memory.put("heapMax", String.valueOf(memHeapUsage.getMax()));
+ memory.put("heapCommitted", String.valueOf(memHeapUsage.getCommitted()));
+ memory.put("heapUsed", String.valueOf(memHeapUsage.getUsed()));
+ memory.put("nonHeapInit", String.valueOf(nonHeapUsage.getInit()));
+ memory.put("nonHeapMax", String.valueOf(nonHeapUsage.getMax()));
+ memory.put("nonHeapCommitted", String.valueOf(nonHeapUsage.getCommitted()));
+ memory.put("nonHeapUsed", String.valueOf(nonHeapUsage.getUsed()));
+ memory.put("memory_pool_usages", getPoolDivision());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerMetricsUtil.addMemoryDetails()" + memory);
+ }
+
+ return memory;
+ }
+
+ /**
+ * Collect system information.
+ */
+ protected String[] addSystemInfo() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerMetricsUtil.addSystemInfo()");
+ }
+
+ String[] osInfo = { OS.getName(), OS.getArch(), OS.getVersion() };
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerMetricsUtil.addSystemInfo()" + osInfo);
+ }
+
+ return osInfo;
+ }
+
+ public RangerMetrics getVMStatus() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerMetricsUtil.getVMStatus()");
+ }
+
+ Map<String, Object> jvm = new LinkedHashMap<>();
+ Map<String, Object> vmDetails = new LinkedHashMap<>();
+ vmDetails.put("JVM Machine Actual Name", JVM_MACHINE_ACTUAL_NAME);
+ vmDetails.put("version", VERSION);
+ vmDetails.put("JVM Machine Representation Name", JVM_MACHINE_REPRESENTATION_NAME);
+ vmDetails.put("Up time of JVM", UP_TIME_OF_JVM);
+ vmDetails.put("JVM Vendor Name", JVM_VENDOR_NAME);
+ vmDetails.putAll(getValues());
+ jvm.put("jvm", vmDetails);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerMetricsUtil.getVMStatus() " + jvm);
+ }
+
+ return new RangerMetrics(jvm);
+ }
+
+ public void writeMetricsToFile(File filePath) throws Throwable {
+
+ RangerMetrics rangerMetrics = null;
+ rangerMetrics = getVMStatus();
+ if (null == rangerMetrics || null == filePath) {
+ LOG.debug("RangerMetrics or filePath can not be null)");
+ return;
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerMetricsUtil.writeMetricsToFIle() for path: "+ filePath);
+ }
+ Gson gson = new Gson();
+ try (FileWriter file = new FileWriter(filePath)) {
+ gson.toJson(rangerMetrics, file);
+ file.flush();
+ } catch (Exception e ) {
+ LOG.error("RangerMetricsUtil.writeMetricsToFile() got an error",e);
+ throw e;
+ }
+ }
+}
diff --git a/tagsync/conf/templates/installprop2xml.properties b/tagsync/conf/templates/installprop2xml.properties
index 510cd6f..55e015e 100644
--- a/tagsync/conf/templates/installprop2xml.properties
+++ b/tagsync/conf/templates/installprop2xml.properties
@@ -65,3 +65,8 @@
# TODO - What property in ranger-tagsync-site.xml should hadoop_conf map to??
hadoop_conf = hadoop_conf
+#JVM metrics related property
+JVM_METRICS_ENABLED=ranger.tagsync.metrics.enabled
+JVM_METRICS_FILENAME=ranger.tagsync.metrics.filename
+JVM_METRICS_FILEPATH=ranger.tagsync.metrics.filepath
+JVM_METRICS_FREQUENCY_TIME_IN_MILLIS=ranger.tagsync.metrics.frequencytimeinmillis
\ No newline at end of file
diff --git a/tagsync/conf/templates/ranger-tagsync-template.xml b/tagsync/conf/templates/ranger-tagsync-template.xml
index b8bfbf5..40bd3db 100644
--- a/tagsync/conf/templates/ranger-tagsync-template.xml
+++ b/tagsync/conf/templates/ranger-tagsync-template.xml
@@ -107,4 +107,20 @@
<name>ranger.tagsync.dest.ranger.session.cookie.name</name>
<value>RANGERADMINSESSIONID</value>
</property>
+ <property>
+ <name>ranger.tagsync.metrics.filepath</name>
+ <value></value>
+ </property>
+ <property>
+ <name>ranger.tagsync.metrics.filename</name>
+ <value></value>
+ </property>
+ <property>
+ <name>ranger.tagsync.metrics.frequencytimeinmillis</name>
+ <value></value>
+ </property>
+ <property>
+ <name>ranger.tagsync.metrics.enabled</name>
+ <value>false</value>
+ </property>
</configuration>
diff --git a/tagsync/scripts/install.properties b/tagsync/scripts/install.properties
index be33cc2..ae2e555 100644
--- a/tagsync/scripts/install.properties
+++ b/tagsync/scripts/install.properties
@@ -109,3 +109,22 @@
hadoop_conf=/etc/hadoop/conf
+
+# if you want to enable or disable jvm metrics for tagsync process
+# valid values: true, false
+# any value other than true would be treated as false
+# default value: false
+# if the value is false, jvm metrics is not created
+JVM_METRICS_ENABLED=
+
+# filename of jvm metrics created for tagsync process
+# default value: ranger_tagsync_metric.json
+JVM_METRICS_FILENAME=
+
+#file directory for jvm metrics
+# default value : logdir
+JVM_METRICS_FILEPATH=
+
+#frequency for jvm metrics to be updated
+# default value : 10000 milliseconds
+JVM_METRICS_FREQUENCY_TIME_IN_MILLIS=
diff --git a/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncConfig.java b/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncConfig.java
index c4173da..95c3482 100644
--- a/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncConfig.java
+++ b/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncConfig.java
@@ -31,6 +31,8 @@
import java.io.InputStream;
import java.net.URL;
import java.net.UnknownHostException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.Properties;
@@ -105,6 +107,14 @@
private static String LOCAL_HOSTNAME = "unknown";
+ private static final String TAGSYNC_METRICS_FILEPATH = "ranger.tagsync.metrics.filepath";
+ private static final String DEFAULT_TAGSYNC_METRICS_FILEPATH = "/tmp/";
+ private static final String TAGSYNC_METRICS_FILENAME = "ranger.tagsync.metrics.filename";
+ private static final String DEFAULT_TAGSYNC_METRICS_FILENAME = "ranger_tagsync_metric.json";
+ private static final String TAGSYNC_METRICS_FREQUENCY_TIME_IN_MILLIS_PARAM = "ranger.tagsync.metrics.frequencytimeinmillis";
+ private static final long DEFAULT_TAGSYNC_METRICS_FREQUENCY__TIME_IN_MILLIS = 10000L;
+ private static final String TAGSYNC_METRICS_ENABLED_PROP = "ranger.tagsync.metrics.enabled";
+
private Properties props;
static {
@@ -460,4 +470,48 @@
}
}
+ public String getTagSyncMetricsFileName() {
+ String val = getProperties().getProperty(TAGSYNC_METRICS_FILEPATH);
+ if (StringUtils.isBlank(val)) {
+ if (StringUtils.isBlank(System.getProperty("logdir"))) {
+ val = DEFAULT_TAGSYNC_METRICS_FILEPATH;
+ } else {
+ val = System.getProperty("logdir");
+ }
+ }
+
+ if (Files.notExists(Paths.get(val))) {
+ return null;
+ }
+
+ StringBuilder pathAndFileName = new StringBuilder(val);
+ if (!val.endsWith("/")) {
+ pathAndFileName.append("/");
+ }
+ String fileName = getProperties().getProperty(TAGSYNC_METRICS_FILENAME);
+ if (StringUtils.isBlank(fileName)) {
+ fileName = DEFAULT_TAGSYNC_METRICS_FILENAME;
+ }
+ pathAndFileName.append(fileName);
+ return pathAndFileName.toString();
+ }
+
+ public long getTagSyncMetricsFrequency() {
+ long ret = DEFAULT_TAGSYNC_METRICS_FREQUENCY__TIME_IN_MILLIS;
+ String val = getProperties().getProperty(TAGSYNC_METRICS_FREQUENCY_TIME_IN_MILLIS_PARAM);
+ if (StringUtils.isNotBlank(val)) {
+ try {
+ ret = Long.valueOf(val);
+ } catch (NumberFormatException exception) {
+ // Ignore
+ }
+ }
+ return ret;
+ }
+
+ public static boolean isTagSyncMetricsEnabled(Properties prop) {
+ String val = prop.getProperty(TAGSYNC_METRICS_ENABLED_PROP);
+ return "true".equalsIgnoreCase(StringUtils.trimToEmpty(val));
+ }
+
}
diff --git a/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncMetricsProducer.java b/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncMetricsProducer.java
new file mode 100644
index 0000000..dc6c8f1
--- /dev/null
+++ b/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSyncMetricsProducer.java
@@ -0,0 +1,89 @@
+package org.apache.ranger.tagsync.process;
+
+/*
+ * 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.
+ */
+import java.io.File;
+
+import org.apache.log4j.Logger;
+import org.apache.ranger.plugin.util.RangerMetricsUtil;
+
+public class TagSyncMetricsProducer implements Runnable {
+
+ private static final Logger LOG = Logger.getLogger(TagSyncMetricsProducer.class);
+ private boolean shutdownFlag = false;
+
+ public static void main(String[] args) {
+ TagSyncMetricsProducer tagSyncMetrics = new TagSyncMetricsProducer();
+ tagSyncMetrics.run();
+ // try { tagSyncMetrics.writeJVMMetrics(); } catch (Throwable e) { }
+ }
+
+ @Override
+ public void run() {
+ try {
+ TagSyncConfig config = TagSyncConfig.getInstance();
+ long sleepTimeBetweenCycleInMillis = config.getTagSyncMetricsFrequency();
+ String logFileNameWithPath = config.getTagSyncMetricsFileName();
+ LOG.info("Tagsync metrics frequency : " + sleepTimeBetweenCycleInMillis +" and metrics file : "+logFileNameWithPath );
+ if (null != logFileNameWithPath) {
+ while (!shutdownFlag) {
+ try {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Sleeping Tagsync metrics for [" + sleepTimeBetweenCycleInMillis
+ + "] milliSeconds");
+ }
+ Thread.sleep(sleepTimeBetweenCycleInMillis);
+ } catch (InterruptedException e) {
+ LOG.error("Failed to wait for [" + sleepTimeBetweenCycleInMillis
+ + "] milliseconds before attempting to tagsync metrics information", e);
+ }
+ try {
+ writeJVMMetrics(logFileNameWithPath);
+ } catch (Throwable t) {
+ LOG.error("Failed to write tagsync metrics into file. Error details: ", t);
+ }
+ }
+ } else {
+ LOG.info("No file directory found for tagsync metrics log ");
+ }
+ } catch (Throwable t) {
+ LOG.error("Failed to start Tagsync metrics. Error details: ", t);
+ } finally {
+ LOG.info("Shutting down the TagSync metrics thread");
+ }
+
+ }
+
+ private void writeJVMMetrics(String logFileNameWithPath) throws Throwable {
+ try {
+ File userMetricFile = null;
+ userMetricFile = new File(logFileNameWithPath);
+ if (!userMetricFile.exists()) {
+ userMetricFile.createNewFile();
+ }
+ RangerMetricsUtil rangerMetricsUtil = new RangerMetricsUtil();
+ rangerMetricsUtil.writeMetricsToFile(userMetricFile);
+
+ } catch (Throwable t) {
+ LOG.error("TagSyncMetricsProducer.writeJVMMetrics() failed to write metrics into file. Error details: ", t);
+ throw t;
+ }
+ }
+
+}
diff --git a/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSynchronizer.java b/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSynchronizer.java
index 8806c74..fefb6bf 100644
--- a/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSynchronizer.java
+++ b/tagsync/src/main/java/org/apache/ranger/tagsync/process/TagSynchronizer.java
@@ -19,6 +19,13 @@
package org.apache.ranger.tagsync.process;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
@@ -28,13 +35,6 @@
import org.apache.ranger.tagsync.model.TagSink;
import org.apache.ranger.tagsync.model.TagSource;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
public class TagSynchronizer {
private static final Logger LOG = Logger.getLogger(TagSynchronizer.class);
@@ -53,7 +53,6 @@
private volatile boolean isShutdownInProgress = false;
public static void main(String[] args) {
-
TagSynchronizer tagSynchronizer = new TagSynchronizer();
TagSyncConfig config = TagSyncConfig.getInstance();
@@ -134,6 +133,20 @@
try {
boolean threadsStarted = tagSink.start();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> starting TagSyncMetricsProducer with default metrics location : "+System.getProperty("logdir"));
+ }
+ //Start the tag sync metrics
+ boolean isTagSyncMetricsEnabled = TagSyncConfig.isTagSyncMetricsEnabled(properties);
+ if (isTagSyncMetricsEnabled) {
+ TagSyncMetricsProducer tagSyncMetricsProducer = new TagSyncMetricsProducer();
+ Thread tagSyncMetricsProducerThread = new Thread(tagSyncMetricsProducer);
+ tagSyncMetricsProducerThread.setName("TagSyncMetricsProducerThread");
+ tagSyncMetricsProducerThread.setDaemon(true);
+ tagSyncMetricsProducerThread.start();
+ } else {
+ LOG.info(" Ranger tagsync metrics is not enabled");
+ }
for (TagSource tagSource : tagSources) {
threadsStarted = threadsStarted && tagSource.start();
}
diff --git a/tagsync/src/main/resources/ranger-tagsync-site.xml b/tagsync/src/main/resources/ranger-tagsync-site.xml
index 0b9ef84..c0f2631 100644
--- a/tagsync/src/main/resources/ranger-tagsync-site.xml
+++ b/tagsync/src/main/resources/ranger-tagsync-site.xml
@@ -101,7 +101,22 @@
<name>ranger.tagsync.dest.ranger.session.cookie.name</name>
<value>RANGERADMINSESSIONID</value>
</property>
-
+ <property>
+ <name>ranger.tagsync.metrics.filepath</name>
+ <value></value>
+ </property>
+ <property>
+ <name>ranger.tagsync.metrics.filename</name>
+ <value></value>
+ </property>
+ <property>
+ <name>ranger.tagsync.metrics.frequencytimeinmillis</name>
+ <value></value>
+ </property>
+ <property>
+ <name>ranger.tagsync.metrics.enabled</name>
+ <value>false</value>
+ </property>
<!-- Ranger-tagsync uses the following two properties to derive name of Ranger Service in a Federated or non-Federated HDFS setup -->
<!-- service-name for HDFS in 'cl1' cluster, that services nameService 'ns1' in a Federated setup
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
index a041345..ae4e474 100644
--- a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
@@ -19,6 +19,10 @@
package org.apache.ranger.unixusersync.config;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -240,6 +244,14 @@
private static final String RANGER_ADMIN_COOKIE_NAME_PROPS = "ranger.usersync.dest.ranger.session.cookie.name";
+ private static final String UGSYNC_METRICS_FILEPATH = "ranger.usersync.metrics.filepath";
+ private static final String DEFAULT_UGSYNC_METRICS_FILEPATH = "/tmp/";
+ private static final String UGSYNC_METRICS_FILENAME = "ranger.usersync.metrics.filename";
+ private static final String DEFAULT_UGSYNC_METRICS_FILENAME = "ranger_usersync_metric.json";
+ private static final String UGSYNC_METRICS_FREQUENCY_TIME_IN_MILLIS_PARAM = "ranger.usersync.metrics.frequencytimeinmillis";
+ private static final long DEFAULT_UGSYNC_METRICS_FREQUENCY_TIME_IN_MILLIS = 10000L;
+ public static final String UGSYNC_METRICS_ENABLED_PROP = "ranger.usersync.metrics.enabled";
+
private Properties prop = new Properties();
private static volatile UserGroupSyncConfig me = null;
@@ -1056,6 +1068,59 @@
/* Used only for unit testing */
public void setGroupHierarchyLevel(int groupHierarchyLevel) {
- prop.setProperty(LGSYNC_GROUP_HIERARCHY_LEVELS, String.valueOf(groupHierarchyLevel));
- }
+ prop.setProperty(LGSYNC_GROUP_HIERARCHY_LEVELS, String.valueOf(groupHierarchyLevel));
+ }
+
+ public String getUserSyncMetricsFileName() throws IOException {
+ String val = prop.getProperty(UGSYNC_METRICS_FILEPATH);
+ if (StringUtils.isBlank(val)) {
+ if (StringUtils.isBlank(prop.getProperty("ranger.usersync.logdir"))) {
+ if (StringUtils.isBlank(System.getProperty("logdir"))) {
+ val = DEFAULT_UGSYNC_METRICS_FILEPATH;
+ } else {
+ val = System.getProperty("logdir");
+ }
+ } else {
+ val = prop.getProperty("ranger.usersync.logdir");
+ }
+ }
+
+ if (Files.notExists(Paths.get(val))) {
+ String current = new File(".").getCanonicalPath();
+ val = current + "/" + val;
+ if (Files.notExists(Paths.get(val))) {
+ return null;
+ }
+ }
+
+ StringBuilder pathAndFileName = new StringBuilder(val);
+ if (!val.endsWith("/")) {
+ pathAndFileName.append("/");
+ }
+
+ String fileName = prop.getProperty(UGSYNC_METRICS_FILENAME);
+ if (StringUtils.isBlank(fileName)) {
+ fileName = DEFAULT_UGSYNC_METRICS_FILENAME;
+ }
+ pathAndFileName.append(fileName);
+ return pathAndFileName.toString();
+ }
+
+ public long getUserSyncMetricsFrequency() {
+ long ret = DEFAULT_UGSYNC_METRICS_FREQUENCY_TIME_IN_MILLIS;
+ String val = prop.getProperty(UGSYNC_METRICS_FREQUENCY_TIME_IN_MILLIS_PARAM);
+ if (StringUtils.isNotBlank(val)) {
+ try {
+ ret = Long.valueOf(val);
+ } catch (NumberFormatException exception) {
+ // Ignore
+ }
+ }
+ return ret;
+ }
+
+ public boolean isUserSyncMetricsEnabled() {
+ String val = prop.getProperty(UGSYNC_METRICS_ENABLED_PROP);
+ return "true".equalsIgnoreCase(StringUtils.trimToEmpty(val));
+ }
}
diff --git a/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserSyncMetricsProducer.java b/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserSyncMetricsProducer.java
new file mode 100644
index 0000000..2d5b212
--- /dev/null
+++ b/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserSyncMetricsProducer.java
@@ -0,0 +1,92 @@
+/*
+ * 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.ranger.usergroupsync;
+
+import java.io.File;
+
+import org.apache.log4j.Logger;
+import org.apache.ranger.plugin.util.RangerMetricsUtil;
+import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
+
+public class UserSyncMetricsProducer implements Runnable {
+
+ private static final Logger LOG = Logger.getLogger(UserSyncMetricsProducer.class);
+ private boolean shutdownFlag = false;
+
+ public static void main(String[] args) {
+ UserSyncMetricsProducer userSyncMetrics = new UserSyncMetricsProducer();
+ userSyncMetrics.run();
+ /*
+ * try { userSyncMetrics.writeJVMMetrics(); } catch (Throwable e) { // TODO
+ * Auto-generated catch block e.printStackTrace(); }
+ */
+ }
+
+ @Override
+ public void run() {
+ try {
+ UserGroupSyncConfig config = UserGroupSyncConfig.getInstance();
+ long sleepTimeBetweenCycleInMillis = config.getUserSyncMetricsFrequency();
+ String logFileNameWithPath = config.getUserSyncMetricsFileName();
+ LOG.info("user sync metrics frequency : " + sleepTimeBetweenCycleInMillis + " and metrics file : "
+ + logFileNameWithPath);
+ if (null != logFileNameWithPath) {
+ while (!shutdownFlag) {
+ try {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Sleeping metrics for [" + sleepTimeBetweenCycleInMillis + "] milliSeconds");
+ }
+ Thread.sleep(sleepTimeBetweenCycleInMillis);
+ } catch (InterruptedException e) {
+ LOG.error("Failed to wait for [" + sleepTimeBetweenCycleInMillis
+ + "] milliseconds before attempting to fetch userSync metrics information", e);
+ }
+ try {
+ writeJVMMetrics(logFileNameWithPath);
+ } catch (Throwable t) {
+ LOG.error("Failed to write user sync metrics into file. Error details: ", t);
+ }
+ }
+ } else {
+ LOG.info("No file directory found for usersync metrics log ");
+ }
+ } catch (Throwable t) {
+ LOG.error("Failed to start user sync metrics. Error details: ", t);
+ } finally {
+ LOG.info("Shutting down the User Sync metrics producer thread");
+ }
+
+ }
+
+ private void writeJVMMetrics(String logFileNameWithPath) throws Throwable {
+ try {
+ File userMetricFile = null;
+ userMetricFile = new File(logFileNameWithPath);
+ if (!userMetricFile.exists()) {
+ userMetricFile.createNewFile();
+ }
+ RangerMetricsUtil rangerMetricsUtil = new RangerMetricsUtil();
+ rangerMetricsUtil.writeMetricsToFile(userMetricFile);
+ } catch (Throwable t) {
+ LOG.error("UserSyncMetricsProducer.writeJVMMetrics() failed to write metrics into file. Error details: ", t);
+ throw t;
+ }
+ }
+}
diff --git a/unixauthservice/scripts/install.properties b/unixauthservice/scripts/install.properties
index d4c6513..d805a99 100644
--- a/unixauthservice/scripts/install.properties
+++ b/unixauthservice/scripts/install.properties
@@ -217,3 +217,22 @@
SYNC_PAGED_RESULTS_SIZE=
#LDAP context referral could be ignore or follow
SYNC_LDAP_REFERRAL =ignore
+
+# if you want to enable or disable jvm metrics for usersync process
+# valid values: true, false
+# any value other than true would be treated as false
+# default value: false
+# if the value is false, jvm metrics is not created
+JVM_METRICS_ENABLED=
+
+# filename of jvm metrics created for usersync process
+# default value: ranger_usersync_metric.json
+JVM_METRICS_FILENAME=
+
+#file directory for jvm metrics
+# default value : logdir
+JVM_METRICS_FILEPATH=
+
+#frequency for jvm metrics to be updated
+# default value : 10000 milliseconds
+JVM_METRICS_FREQUENCY_TIME_IN_MILLIS=
\ No newline at end of file
diff --git a/unixauthservice/scripts/templates/installprop2xml.properties b/unixauthservice/scripts/templates/installprop2xml.properties
index fa342fb..e64ca3a 100644
--- a/unixauthservice/scripts/templates/installprop2xml.properties
+++ b/unixauthservice/scripts/templates/installprop2xml.properties
@@ -57,3 +57,8 @@
SYNC_LDAP_REFERRAL = ranger.usersync.ldap.referral
usersync_principal= ranger.usersync.kerberos.principal
usersync_keytab= ranger.usersync.kerberos.keytab
+#JVM metrics related property
+JVM_METRICS_ENABLED=ranger.usersync.metrics.enabled
+JVM_METRICS_FILENAME=ranger.usersync.metrics.filename
+JVM_METRICS_FILEPATH=ranger.usersync.metrics.filepath
+JVM_METRICS_FREQUENCY_TIME_IN_MILLIS=ranger.usersync.metrics.frequencytimeinmillis
\ No newline at end of file
diff --git a/unixauthservice/scripts/templates/ranger-ugsync-template.xml b/unixauthservice/scripts/templates/ranger-ugsync-template.xml
index 0cacc95..b5dd437 100644
--- a/unixauthservice/scripts/templates/ranger-ugsync-template.xml
+++ b/unixauthservice/scripts/templates/ranger-ugsync-template.xml
@@ -229,4 +229,20 @@
<name>ranger.usersync.dest.ranger.session.cookie.name</name>
<value>RANGERADMINSESSIONID</value>
</property>
+ <property>
+ <name>ranger.usersync.metrics.enabled</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>ranger.usersync.metrics.filepath</name>
+ <value></value>
+ </property>
+ <property>
+ <name>ranger.usersync.metrics.frequencytimeinmillis</name>
+ <value></value>
+ </property>
+ <property>
+ <name>ranger.usersync.metrics.filename</name>
+ <value></value>
+ </property>
</configuration>
diff --git a/unixauthservice/src/main/java/org/apache/ranger/authentication/UnixAuthenticationService.java b/unixauthservice/src/main/java/org/apache/ranger/authentication/UnixAuthenticationService.java
index 1ee5e21..fa146c2 100644
--- a/unixauthservice/src/main/java/org/apache/ranger/authentication/UnixAuthenticationService.java
+++ b/unixauthservice/src/main/java/org/apache/ranger/authentication/UnixAuthenticationService.java
@@ -46,20 +46,22 @@
import org.apache.log4j.Logger;
import org.apache.ranger.credentialapi.CredentialReader;
import org.apache.ranger.plugin.util.XMLUtils;
+import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
import org.apache.ranger.usergroupsync.UserGroupSync;
+import org.apache.ranger.usergroupsync.UserSyncMetricsProducer;
public class UnixAuthenticationService {
private static final Logger LOG = Logger.getLogger(UnixAuthenticationService.class);
-
+
private static final String serviceName = "UnixAuthenticationService";
-
+
private static final String SSL_ALGORITHM = "TLS";
private static final String REMOTE_LOGIN_AUTH_SERVICE_PORT_PARAM = "ranger.usersync.port";
-
+
private static final String SSL_KEYSTORE_PATH_PARAM = "ranger.usersync.keystore.file";
private static final String SSL_TRUSTSTORE_PATH_PARAM = "ranger.usersync.truststore.file";
-
+
private static final String SSL_KEYSTORE_PATH_PASSWORD_ALIAS = "usersync.ssl.key.password";
private static final String SSL_TRUSTSTORE_PATH_PASSWORD_ALIAS = "usersync.ssl.truststore.password";
@@ -123,11 +125,12 @@
LOG.info("Service: " + serviceName + " - STOPPED.");
}
}
-
+
private void startUnixUserGroupSyncProcess() {
//
// Start the synchronization service ...
//
+ LOG.info("Start : startUnixUserGroupSyncProcess " );
UserGroupSync syncProc = new UserGroupSync();
Thread newSyncProcThread = new Thread(syncProc);
newSyncProcThread.setName("UnixUserSyncThread");
@@ -135,13 +138,27 @@
// Therefore this is marked as non-daemon thread. Don't change the following line
newSyncProcThread.setDaemon(false);
newSyncProcThread.start();
+ LOG.info("UnixUserSyncThread started");
+ LOG.info("creating UserSyncMetricsProducer thread with default metrics location : "+System.getProperty("logdir"));
+ //Start the user sync metrics
+ boolean isUserSyncMetricsEnabled = UserGroupSyncConfig.getInstance().isUserSyncMetricsEnabled();
+ if (isUserSyncMetricsEnabled) {
+ UserSyncMetricsProducer userSyncMetricsProducer = new UserSyncMetricsProducer();
+ Thread userSyncMetricsProducerThread = new Thread(userSyncMetricsProducer);
+ userSyncMetricsProducerThread.setName("UserSyncMetricsProducerThread");
+ userSyncMetricsProducerThread.setDaemon(false);
+ userSyncMetricsProducerThread.start();
+ LOG.info("UserSyncMetricsProducer started");
+ } else {
+ LOG.info(" Ranger userSync metrics is not enabled");
+ }
}
-
+
//TODO: add more validation code
private void init() throws Throwable {
Properties prop = new Properties();
-
+
for (String fn : UGSYNC_CONFIG_XML_FILES ) {
XMLUtils.loadConfig(fn, prop);
}