Saturday 22 August 2015

Using gnuplot for trend analysis

I was looking for a simple tool to draw trend info for data collected from my servers, i have been using cacti effectively and it is serving me quite well, still i need to be able to run some ad-hoc graphs from time to to time.
I came across gnuplot and didn't consider using it, but now, i found those 3 great resources that will change my apporache:

http://linux.byexamples.com/archives/487/plot-your-graphs-with-command-line-gnuplot/

http://people.duke.edu/~hpgavin/gnuplot.html

Those 2 articles made it very easy for me to understand the tool and be able to use its demos at:

http://gnuplot.sourceforge.net/demo_4.6/


below is my test script:

test.data:

#month reading consumption
1   700          830
2   1120         1125
3   1400         1400
4   1790         1750
5   2100         2150
6   2450         2455
7   2900         2910
8   3210         3230
9   3300         3350
10  3780         3785
11  4090         4110
12  4550         4640
13  4550         4950
14  4550         5350









test.gp:

reset
set terminal png


#set xdata time
#set timefmt "%d/%m/%Y %H:%M:%S"
#set format x "%H:%M"
set xlabel "Month #"

set ylabel "Monthly Reading"
#set yrange [0:31]

set title "M7YC Performance per Month"
#set key reverse Left outside
set key bottom center outside
#set key bottom horizontal center outside
set grid

#set style data linespoints
#set style data impulses
#set style data boxes
set style data histogram
set style histogram cluster gap 2
set style fill solid border 0
set boxwidth 1


#Plot with different patterns in one command
#plot "./test.data" using 1:2 title "Monthly Reading" with linespoints, \
#"" using 1:3 title "Actual consumption" with boxes

#Plot with style setting
#plot "./test.data" using 1:2 title "Monthly Reading" , \
#"" using 1:3 title "Actual consumption"



#Plot a histo
plot "./test.data" using 2 title "Monthly Reading" , \
"" using 3 title "Actual consumption"


#




The above have a lot of potential to generate png graphs that can be embeded in HTML pages and serve as needed.
Also we can customize the graphs and use shell scripting to tune and manipulate the script and the data dynamically.

will explore more about this and post the works . .




Reporting JMX attributes from Tomcat using command line

We have run into an issue with number of tomcat active sessions that was causing us a memory bottleneck while doing performance testing.
So to track this we did a heap dump and a set of heap histograms to see what is the size of the Session object and current number of open sessions.
We managed to find the issue with the test scenario but, we found out that doing a heap histo would pause the JVM for a second or 2 which added to our performance issues.

So we need another command line way to report sessions.
Java does provide jconsole and JvisualVM with Mbean plugins but both tools are GUI tools not suitable for reporting from command line and automation.
We needed some way to automate this for doing a report across 9 nodes.

I have found some good command line tools but some of them are out of date and others are too complex for the job or requires an externally exposed JMX which is not allowed by our org. security.

So i needed to look for some java code to do this trick for me, i found out an oracle blog example code that would report JVM arguments, classpath, start time from JMX at the below link:

https://blogs.oracle.com/jmxetc/entry/how_to_retrieve_remote_jvm


The good thing about this code is it uses the Java tools to attache to the JVM locally so i didn't have to expose JVM externally which is forbidden by our security team.

One issue i faced it that i didn't know how to report the active sessions out of tomcat, so I asked my friend Bassem Zohdy who created a demo for me doing the needed functionality:

https://github.com/bassemZohdy/tomcatActiveSessionLocalJMXDemo


What i did is I updated the Oracle blog example code with what Bassem did and i got a cool running commandline tool that can report active sessions.
below is the java code:


                                                  

//package jvmruntime;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;                
import java.util.logging.Logger;            
import javax.management.remote.JMXServiceURL;
import com.sun.tools.attach.VirtualMachine; 
import com.sun.tools.attach.VirtualMachineDescriptor;
import java.lang.management.RuntimeMXBean;         
import java.util.ArrayList;                        
import java.util.List;                             
import javax.management.MBeanServerConnection;     
import javax.management.remote.JMXConnector;       
import javax.management.remote.JMXConnectorFactory;
import javax.management.ObjectName;                

public class JVMRuntimeClient {
                             
    private static final Logger LOG =
            Logger.getLogger(JVMRuntimeClient.class.getName());
                                                             
    public JVMRuntimeClient() {                              
    }                                                        

    public static class ConnectionArgs {
        private static final String CONNECTOR_ADDRESS =
          "com.sun.management.jmxremote.localConnectorAddress";
                                                             
                                                             
        public final JMXServiceURL jmxURL;                   
        final public String SYNTAX = "JVMRuntimeClient -url <jmx-url> " +
                "| -port <port-number> [-host <host-or-ip] " +         
                "| -pid <pid> | -help";                                
                                                                       
        public ConnectionArgs(String[] args) {                         
            jmxURL = parseArgs(args);                                  
        }                                                              
                                                                       
        public final JMXServiceURL getJMXServiceURL() {                
            return jmxURL;                                             
        }                                                              
                                                                       
        private JMXServiceURL parseArgs(String[] args) {               
                                                                       
            String host = null;                                        
            int port = 0;                                              
            String pid = null;                                         
            JMXServiceURL serviceURL = null;                           
                                                                       
            for (int i=0;i<args.length;i++) {                          
                                                                       
                if (args[i].startsWith("-url")) {                      
                // The '-url' option will let you specify a JMXServiceURL
                // on the command line. This is an URL that begins with
                // service:jmx:<protocol>                              
                //                                                     
                    if (host != null)                                  
                        throwSyntaxError(                              
                                "-url and -host are mutually exclusive");
                    if (pid != null)                                   
                        throwSyntaxError(                              
                                "-pid and -url are mutually exclusive");
                    if (port > 0)                                      
                        throwSyntaxError(                              
                                "-port and -url are mutually exclusive");
                    if (++i >= args.length)                            
                        throwSyntaxError(                              
                                "missing JMXServiceURL after -url");   
                                                                       
                    try {                                              
                        serviceURL = new JMXServiceURL(args[i]);       
                    } catch (Exception x) {                            
                        throwSyntaxError("bad JMXServiceURL after -url: " + x);
                    }                                                        
                    continue;                                                
                                                                             
                } else if (args[i].startsWith("-host")) {                    
                // The '-host' and '-port' options will let you specify a host
                // and port, and from that will construct the JMXServiceURL of
                // the default RMI connector, that is:                       
                // service:jmx:rmi:///jndi/rmi://<host>:<port>/jmxrmi"       
                //                                                           
                    if (serviceURL != null)                                  
                        throwSyntaxError("-url and -host are mutually exclusive");
                    if (pid != null)                                            
                        throwSyntaxError("-pid and -host are mutually exclusive");
                    if (++i >= args.length)                                     
                        throwSyntaxError("missing host after -host");           
                    try {                                                       
                        InetAddress.getByName(args[i]);                         
                        host = args[i];                                         
                    } catch (Exception x) {                                     
                        throwSyntaxError("bad host after -url: " + x);          
                    }                                                           
                                                                                
                } else if (args[i].startsWith("-port")) {                       
                // The '-host' and '-port' options will let you specify a host  
                // and port, and from that will construct the JMXServiceURL of  
                // the default RMI connector, that is:                          
                // service:jmx:rmi:///jndi/rmi://<host>:<port>/jmxrmi"          
                //                                                              
                    if (serviceURL != null)                                     
                        throwSyntaxError("-url and -port are mutually exclusive");
                    if (pid != null)                                            
                        throwSyntaxError("-pid and -port are mutually exclusive");
                    if (++i >= args.length)                                     
                        throwSyntaxError("missing port number after -port");    
                    try {                                                       
                        port = Integer.parseInt(args[i]);                       
                        if (port <= 0)                                          
                            throwSyntaxError("bad port number after -port: " +  
                                    "must be positive");                        
                    } catch (Exception x) {                                     
                        throwSyntaxError("bad port number after -port: " + x);  
                    }                                                           
                } else if (args[i].startsWith("-pid")) {                        
                // The '-pid' and option will let you specify the PID of the    
                // target VM you want to connect to. It will then use the       
                // attach API to dynamically launch the JMX agent in the target 
                // VM (if needed) and to find out the JMXServiceURL of the      
                // the default JMX Connector in that VM.                        
                //                                                              
                    if (serviceURL != null)                                     
                        throwSyntaxError("-url and -pid are mutually exclusive");
                    if (port > 0)                                               
                        throwSyntaxError("-port and -pid are mutually exclusive");
                    if (++i >= args.length)                                     
                        throwSyntaxError("missing pid after -pid");             
                    try {                                                       
                        pid = args[i];                                          
                    } catch (Exception x) {                                     
                        throwSyntaxError("bad pid after -pid: " + x);           
                    }                                                           
                } else if (args[i].startsWith("-help")) {                       
                    final List<String> vmlist = new ArrayList();                
                    for (VirtualMachineDescriptor vd : VirtualMachine.list()) { 
                        vmlist.add(vd.id());                                    
                    }                                                           
                    System.err.println(SYNTAX);                                 
                    System.err.println("Running JVMs are: "+vmlist);            
                    throw new IllegalArgumentException(SYNTAX);                 
                } else {                                                        
                    throwSyntaxError("Unknown argument: "+args[i]);             
                }                                                               
            }                                                                                                                                                      
            // A JMXServiceURL was given on the command line, just use this.    
            //                                                                  
            if (serviceURL != null)                                             
                return serviceURL;                                                           // A -host -port info was given on the command line.                
            // Construct the default RMI JMXServiceURL from this.               
            //                                                                  
            if (port > 0) {                                                     
                if (host == null)                                               
                    host = "localhost";                                           
                try {                                                           
                    return new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+  
                            host+":"+port+"/jmxrmi");                           
                } catch (Exception x) {                                         
                    throwSyntaxError("Bad host or port number: "+x);            
                }                                                               
            }                                                                   
                                                                                
            // A PID was given on the command line.                             
            // Use the attach API to find the target's connector address, and   
            // start it if needed.                                              
            //                                                                  
            if (pid != null) {                                                  
                try {                                                           
                    return getURLForPid(pid);                                   
                } catch (Exception x) {                                         
                    throwSyntaxError("cannot attach to target vm "+pid+": "+x); 
                }                                                               
            }                                                                   
                                                                                
            final List<String> vmlist = new ArrayList();                        
            for (VirtualMachineDescriptor vd : VirtualMachine.list()) {         
                vmlist.add(vd.id());                                            
            }                                                                   
            throwSyntaxError("missing argument: "+ "-port | -url | -pid | -list"
                    +"\\n\\tRunning VMs are: "+vmlist);                         
                                                                                
            // Unreachable.                                                     
            return null;                                                        
        }                                                                       
                                                                                
                                                                                
        private void throwSyntaxError(String msg) {                             
            System.err.println(msg);                                            
            System.err.println(SYNTAX);                                         
            throw new IllegalArgumentException(msg);                            
        }                                                                       

        private JMXServiceURL getURLForPid(String pid) throws Exception {
                                                                       
            // attach to the target application                        
            final VirtualMachine vm = VirtualMachine.attach(pid);      
                                                                       
            // get the connector address                               
            String connectorAddress =                                  
                    vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
                                                                         
            // no connector address, so we start the JMX agent           
            if (connectorAddress == null) {                              
                String agent = vm.getSystemProperties().getProperty("java.home") +
                        File.separator + "lib" + File.separator + "management-agent.jar";
                vm.loadAgent(agent);                                                   
                                                                                       
                // agent is started, get the connector address                         
                connectorAddress =                                                     
                        vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);        
                assert connectorAddress != null;                                       
            }                                                                          
            return new JMXServiceURL(connectorAddress);                                
        }                                                                              
    }                                                                                  
                                                                                       
     // @param args the command line arguments:                                        
     //             must be -url <jmx-url>,                                            
     //             or -port <port-number> [-host <host-or-ip],                        
     //             or -pid <pid>,                                                     
     //             or -help                                                           
     //                                                                                
    public static void main(String[] args) throws Exception {                          
        // Parse arguments.
        final ConnectionArgs cArgs = new ConnectionArgs(args);

        // Get target's URL
        final JMXServiceURL target = cArgs.getJMXServiceURL();

        // Connect to target (assuming no security)
        final JMXConnector connector = JMXConnectorFactory.connect(target);

        // Get an MBeanServerConnection on the remote VM.
        final MBeanServerConnection remote =
                connector.getMBeanServerConnection();

        final RuntimeMXBean remoteRuntime =
                ManagementFactory.newPlatformMXBeanProxy(
                    remote,
                    ManagementFactory.RUNTIME_MXBEAN_NAME,
                    RuntimeMXBean.class);

        //Bassem's code
        final ObjectName objectName = new ObjectName(
                                "Catalina:type=Manager,host=localhost,context="+"/");

        System.out.println("ActiveSession = "
                                + remote.getAttribute(objectName, "activeSessions"));
        //END of Bassem's code

        //System.out.println("Target VM is: "+remoteRuntime.getName());
        //System.out.println("Started since: "+remoteRuntime.getUptime());
        //System.out.println("With Classpath: "+remoteRuntime.getClassPath());
        //System.out.println("And args: "+remoteRuntime.getInputArguments());


        connector.close();
    }

}



To compile and run this code you need to do:

javac -classpath /usr/java/jdk1.8.0_25/lib/tools.jar: ./JVMRuntimeClient.java

java -classpath /usr/java/jdk1.8.0_25/lib/tools.jar: JVMRuntimeClient -pid 3689



Thursday 6 August 2015

Wget Recrusively with password encryption

This is a good script to download folders from a website.
Tweek the cut dirs to suit ur needs

[root]# cat svnget.sh

MyPASS=$(echo "ULLLjhsPpssjFGsmyMVpwtLwhdjdhjdhjLLDLDi9e##nsBBPPs=" |openssl enc -desx -base64 -d)

wget --user=sherif--password=${MyPASS} \
-e robots=off --cut-dirs=4 \
-nH \
--reject="index.html*"  --no-parent \
--recursive  $1

MyPASS=0
[root]#