This is an automated email from the ASF dual-hosted git repository.
pradeep pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 1eec98e RANGER-2699 : JVM metrics for Ranger usersync and Ranger
tagsync
1eec98e is described below
commit 1eec98e4739e47f139776c1ec0ccee57ecb7dd73
Author: Dineshkumar Yadav <[email protected]>
AuthorDate: Wed Feb 5 15:31:25 2020 +0530
RANGER-2699 : JVM metrics for Ranger usersync and Ranger tagsync
Signed-off-by: Pradeep <[email protected]>
---
.../ranger/plugin/util/RangerMetricsUtil.java | 189 +++++++++++++++++++++
tagsync/conf/templates/installprop2xml.properties | 5 +
tagsync/conf/templates/ranger-tagsync-template.xml | 16 ++
tagsync/scripts/install.properties | 19 +++
.../ranger/tagsync/process/TagSyncConfig.java | 54 ++++++
.../tagsync/process/TagSyncMetricsProducer.java | 89 ++++++++++
.../ranger/tagsync/process/TagSynchronizer.java | 29 +++-
tagsync/src/main/resources/ranger-tagsync-site.xml | 17 +-
.../unixusersync/config/UserGroupSyncConfig.java | 69 +++++++-
.../usergroupsync/UserSyncMetricsProducer.java | 92 ++++++++++
unixauthservice/scripts/install.properties | 19 +++
.../scripts/templates/installprop2xml.properties | 5 +
.../scripts/templates/ranger-ugsync-template.xml | 16 ++
.../authentication/UnixAuthenticationService.java | 31 +++-
14 files changed, 632 insertions(+), 18 deletions(-)
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 @@ tagsync_keytab = ranger.tagsync.kerberos.keytab
# 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 @@ tagsync_keytab=
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.IOException;
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 @@ public class TagSyncConfig extends Configuration {
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 class TagSyncConfig extends Configuration {
}
}
+ 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.log4j.Logger;
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 @@ public class TagSynchronizer {
private volatile boolean isShutdownInProgress = false;
public static void main(String[] args) {
-
TagSynchronizer tagSynchronizer = new TagSynchronizer();
TagSyncConfig config = TagSyncConfig.getInstance();
@@ -134,6 +133,20 @@ public class TagSynchronizer {
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 @@ public class UserGroupSyncConfig {
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 @@ public class UserGroupSyncConfig {
/* 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_ENABLED=
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 @@ AUTH_SSL_ENABLED = ranger.usersync.enabled
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 javax.net.ssl.TrustManagerFactory;
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 @@ public class UnixAuthenticationService {
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 @@ public class UnixAuthenticationService {
// 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);
}