Implementing nginx extension statistics reading logic

Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/2ccd5eb6
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/2ccd5eb6
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/2ccd5eb6

Branch: refs/heads/master
Commit: 2ccd5eb61679b04c431d800bd9f6547c540eb8e0
Parents: 2ff79b0
Author: Imesh Gunaratne <[email protected]>
Authored: Mon May 11 00:08:51 2015 +0530
Committer: Imesh Gunaratne <[email protected]>
Committed: Mon May 11 00:08:51 2015 +0530

----------------------------------------------------------------------
 .../load-balancer/nginx-extension/README.md     | 14 +++-
 .../src/main/conf/log4j.properties              |  2 +-
 .../nginx/extension/NginxConfigWriter.java      | 20 +++++-
 .../nginx/extension/NginxStatisticsReader.java  | 75 ++++++++++++++++++--
 4 files changed, 99 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/2ccd5eb6/extensions/load-balancer/nginx-extension/README.md
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/nginx-extension/README.md 
b/extensions/load-balancer/nginx-extension/README.md
index 3c606da..66ef238 100644
--- a/extensions/load-balancer/nginx-extension/README.md
+++ b/extensions/load-balancer/nginx-extension/README.md
@@ -9,8 +9,16 @@ tenant application signups and domain mapping information 
received from Stratos
 2. Configure and start an instance of Nginx.
 3. Listen to topology, application, application signup, domain mapping events.
 4. Reload Nginx instance with the new topology configuration.
+5. Periodically publish statistics to Complex Event Processor (CEP).
 
 ## Statistics publishing
-Live statistics monitoring module is not available in Nginx basic version, 
need to recompile Nginx from source
-with HttpStubStatusModule for enabling it. Therefore statistics publishing to 
CEP is not currently available in this
-extension.
+Set cep.stats.publisher.enabled to true in nginx-extension.sh file to enable 
statistics publishing. Please note that
+Nginx must be compiled with HttpStubStatusModule module to read statistics. 
Execute the following command to make
+ sure that HttpStubStatusModule module is installed:
+```
+nginx -V 2>&1 | grep -o with-http_stub_status_module
+```
+If HttpStubStatusModule is installed the following output will be given:
+```
+with-http_stub_status_module
+```
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/2ccd5eb6/extensions/load-balancer/nginx-extension/src/main/conf/log4j.properties
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/nginx-extension/src/main/conf/log4j.properties 
b/extensions/load-balancer/nginx-extension/src/main/conf/log4j.properties
index a8e73dd..ad6b80a 100644
--- a/extensions/load-balancer/nginx-extension/src/main/conf/log4j.properties
+++ b/extensions/load-balancer/nginx-extension/src/main/conf/log4j.properties
@@ -25,7 +25,7 @@ 
log4j.appender.CONSOLE_APPENDER=org.apache.log4j.ConsoleAppender
 
 # The standard error log where all the warnings, errors and fatal errors will 
be logged
 log4j.appender.FILE_APPENDER=org.apache.log4j.FileAppender
-log4j.appender.FILE_APPENDER.File=stratos-nginx-extension.log
+log4j.appender.FILE_APPENDER.File=logs/nginx-extension.log
 log4j.appender.FILE_APPENDER.layout=org.apache.log4j.PatternLayout
 log4j.appender.FILE_APPENDER.layout.ConversionPattern=%d{ISO8601} 
[%X{ip}-%X{host}] [%t] %5p %c{1} %m%n
 log4j.appender.FILE_APPENDER.threshold=DEBUG

http://git-wip-us.apache.org/repos/asf/stratos/blob/2ccd5eb6/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxConfigWriter.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxConfigWriter.java
 
b/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxConfigWriter.java
index 11803c4..a7adad8 100644
--- 
a/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxConfigWriter.java
+++ 
b/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxConfigWriter.java
@@ -115,10 +115,15 @@ public class NginxConfigWriter {
      *     server {
      *         listen <proxy-port>;
      *         server_name <cluster-hostname>;
-     *
      *         location / {
      *             proxy_pass    http://<cluster-hostname>
      *         }
+     *         location /nginx_status {
+     *            stub_status on;
+     *            access_log off;
+     *            allow 127.0.0.1;
+     *            deny all;
+     *         }
      *     }
      * }
      * @param cluster
@@ -148,10 +153,19 @@ public class NginxConfigWriter {
                 text.append(TAB).append("server {").append(NEW_LINE);
                 text.append(TAB).append(TAB).append("listen 
").append(port.getProxy()).append(";").append(NEW_LINE);
                 text.append(TAB).append(TAB).append("server_name 
").append(hostname).append(";").append(NEW_LINE);
-                text.append(NEW_LINE);
+
                 text.append(TAB).append(TAB).append("location / 
{").append(NEW_LINE);
-                
text.append(TAB).append(TAB).append(TAB).append("proxy_pass").append(TAB).append("http://";).append(hostname).append(";").append(NEW_LINE);
+                
text.append(TAB).append(TAB).append(TAB).append("proxy_pass").append(TAB)
+                        
.append("http://";).append(hostname).append(";").append(NEW_LINE);
                 text.append(TAB).append(TAB).append("}").append(NEW_LINE);
+
+                text.append(TAB).append(TAB).append("location /nginx_status 
{").append(NEW_LINE);
+                text.append(TAB).append(TAB).append(TAB).append("stub_status 
on;").append(NEW_LINE);
+                text.append(TAB).append(TAB).append(TAB).append("access_log 
off;").append(NEW_LINE);
+                text.append(TAB).append(TAB).append(TAB).append("allow 
127.0.0.1;").append(NEW_LINE);
+                text.append(TAB).append(TAB).append(TAB).append("deny 
all;").append(NEW_LINE);
+                text.append(TAB).append(TAB).append("}").append(NEW_LINE);
+
                 text.append(TAB).append("}").append(NEW_LINE);
                 // End server block
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/2ccd5eb6/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxStatisticsReader.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxStatisticsReader.java
 
b/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxStatisticsReader.java
index b8cc5e7..569f67b 100644
--- 
a/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxStatisticsReader.java
+++ 
b/extensions/load-balancer/nginx-extension/src/main/java/org/apache/stratos/nginx/extension/NginxStatisticsReader.java
@@ -21,11 +21,22 @@ package org.apache.stratos.nginx.extension;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.conn.HttpHostConnectException;
+import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.stratos.load.balancer.common.domain.Cluster;
+import org.apache.stratos.load.balancer.common.domain.Port;
+import org.apache.stratos.load.balancer.common.domain.Service;
 import 
org.apache.stratos.load.balancer.common.statistics.LoadBalancerStatisticsReader;
 import org.apache.stratos.load.balancer.common.topology.TopologyProvider;
 
-import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Nginx statistics reader.
@@ -34,18 +45,72 @@ public class NginxStatisticsReader implements 
LoadBalancerStatisticsReader {
 
     private static final Log log = 
LogFactory.getLog(NginxStatisticsReader.class);
 
-    private String scriptsPath;
-    private String statsSocketFilePath;
     private TopologyProvider topologyProvider;
 
     public NginxStatisticsReader(TopologyProvider topologyProvider) {
-        this.scriptsPath = NginxContext.getInstance().getScriptsPath();
-        this.statsSocketFilePath = 
NginxContext.getInstance().getStatsSocketFilePath();
         this.topologyProvider = topologyProvider;
     }
 
     @Override
     public int getInFlightRequestCount(String clusterId) {
+        Cluster cluster = topologyProvider.getClusterByClusterId(clusterId);
+        if(cluster != null) {
+            String serviceName = cluster.getServiceName();
+            Service service = 
topologyProvider.getTopology().getService(serviceName);
+            if(service != null) {
+                int inFlightRequestCount = 0;
+                for(Port port : service.getPorts()) {
+                    inFlightRequestCount += findWritingCount(port.getProxy());
+                }
+                if(log.isDebugEnabled()) {
+                    log.debug(String.format("In-flight request count: 
[cluster-id] %s [value] %d",
+                            clusterId, inFlightRequestCount));
+                }
+                return inFlightRequestCount;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Make a http request to http://127.0.0.1:<proxy-port>/nginx_status and 
find writing count.
+     * @param proxyPort
+     * @return
+     */
+    private int findWritingCount(int proxyPort) {
+        try {
+            URL url = new URL("http", "127.0.0.1", proxyPort, "/nginx_status");
+            DefaultHttpClient httpClient = new DefaultHttpClient();
+            HttpUriRequest request = new HttpGet(url.toURI());
+            HttpResponse response = httpClient.execute(request);
+            if (response.getStatusLine().getStatusCode() != 200) {
+                throw new RuntimeException("http://127.0.0.1:"; + proxyPort + 
"/nginx_status was not found");
+            }
+            BufferedReader reader = new BufferedReader(new InputStreamReader(
+                    (response.getEntity().getContent())));
+            String output, result = "";
+            while ((output = reader.readLine()) != null) {
+                result += output;
+            }
+            Pattern pattern = Pattern.compile("(Writing: )([0-1]*)");
+            Matcher matcher = pattern.matcher(result);
+            if (matcher.find()) {
+                // Deduct one to remove the above request
+                int writingCount = Integer.parseInt(matcher.group(2)) - 1;
+                if(log.isDebugEnabled()) {
+                    log.debug(String.format("Writing count: [proxy] %d [value] 
%d", proxyPort, writingCount));
+                }
+                return writingCount;
+            }
+            throw new RuntimeException("Writing block was not found in 
nginx_status response");
+        } catch (HttpHostConnectException ignore) {
+            if(ignore.getMessage().contains("Connection refused")) {
+                log.warn("Could not find in-flight request count, connection 
refused: " +
+                        "http://127.0.0.1:"; + proxyPort + "/nginx_status");
+            }
+        } catch (Exception e) {
+            log.error("Could not find in-flight request count: 
http://127.0.0.1:"; + proxyPort + "/nginx_status", e);
+        }
         return 0;
     }
 

Reply via email to