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);
                }

Reply via email to