<commit_before>/*******************************************************************************
 * (C) Copyright 2016 <NAME> and <NAME>
 *  
 *  This file is part of djigger
 *  
 *  djigger is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  djigger is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *  
 *  You should have received a copy of the GNU Affero General Public License
 *  along with djigger.  If not, see <http://www.gnu.org/licenses/>.
 *
 *******************************************************************************/
package io.djigger.agent;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.instrument.Instrumentation;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.smb.core.Message;

import io.djigger.monitoring.java.agent.JavaAgentMessageType;

public class Agent extends Thread {
	
	private final static Integer DEFAULT_PORT = 12121;

	private final boolean agentToClientConnection;
	
	private final Integer port;
	
	private final String clientHost;

	private AgentSession session;
	
	private final Instrumentation instrumentation;

	public static void agentmain(String agentArgs, Instrumentation inst) {
		premain(agentArgs, inst);
	}
	
	
	public static void premain(String agentArguments, Instrumentation instrumentation) {
		System.out.println("Starting agent. Arguments: " + agentArguments);
		
		Map<String,String> parameterMap = new HashMap<String,String>();
		try {
			
			if(agentArguments!=null) {
				String[] split = agentArguments.split(",");
				for(String argument:split) {
					Matcher matcher = Pattern.compile("(.+?):(.+?)$").matcher(argument);
					if(matcher.find()) {
						parameterMap.put(matcher.group(1), matcher.group(2));
					}
				}
			}

			String clientHost = parameterMap.get("host");
			Integer port = parameterMap.containsKey("port")?Integer.decode(parameterMap.get("port")):null;
			Agent agent = new Agent(instrumentation, clientHost, port);
			agent.start();
		} catch(Exception e) {
			System.out.println("Agent: an error occurred while trying to parse the agent parameters.");
			e.printStackTrace();
		}
	}
	
	protected Agent(Instrumentation instrumentation, String host, Integer port) {
		super();
		this.port = port!=null?port:DEFAULT_PORT;
		this.clientHost = host;
		this.instrumentation = instrumentation;
		this.agentToClientConnection = clientHost!=null;

		addCollectorToBootstrap(instrumentation);
	}

	private void addCollectorToBootstrap(Instrumentation instrumentation) {
		try {
			InputStream is = getClass().getClassLoader().getResourceAsStream("collector.jar");
			File collectorJar = File.createTempFile("collector-"+UUID.randomUUID(),".jar");
			System.out.println("Adding " + collectorJar + " to bootstrap search.");
			FileOutputStream os = new FileOutputStream(collectorJar);		
			byte[] buffer = new byte[1024];
            int bytesRead;
            while((bytesRead = is.read(buffer)) !=-1){
                os.write(buffer, 0, bytesRead);
            }
            is.close();
            os.flush();
            os.close();
            
			instrumentation.appendToBootstrapClassLoaderSearch(new JarFile(collectorJar));
		} catch (IOException e1) {
			e1.printStackTrace();<commit_msg>Implementing plugin feature for java agent<commit_after>/*******************************************************************************
 * (C) Copyright 2016 <NAME> and <NAME>
 *  
 *  This file is part of djigger
 *  
 *  djigger is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  djigger is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *  
 *  You should have received a copy of the GNU Affero General Public License
 *  along with djigger.  If not, see <http://www.gnu.org/licenses/>.
 *
 *******************************************************************************/
package io.djigger.agent;

import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.instrument.Instrumentation;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.smb.core.Message;

import io.djigger.monitoring.java.agent.JavaAgentMessageType;

public class Agent extends Thread {
	
	private final static Integer DEFAULT_PORT = 12121;

	private final boolean agentToClientConnection;
	
	private final Integer port;
	
	private final String clientHost;

	private AgentSession session;
	
	private final Instrumentation instrumentation;
	
	private File pluginFolder;

	public static void agentmain(String agentArgs, Instrumentation inst) {
		premain(agentArgs, inst);
	}
	
	
	public static void premain(String agentArguments, Instrumentation instrumentation) {
		System.out.println("Starting agent. Arguments: " + agentArguments);
		
		Map<String,String> parameterMap = new HashMap<String,String>();
		try {
			
			if(agentArguments!=null) {
				String[] split = agentArguments.split(",");
				for(String argument:split) {
					Matcher matcher = Pattern.compile("(.+?):(.+?)$").matcher(argument);
					if(matcher.find()) {
						parameterMap.put(matcher.group(1), matcher.group(2));
					}
				}
			}

			String clientHost = parameterMap.get("host");
			Integer port = parameterMap.containsKey("port")?Integer.decode(parameterMap.get("port")):null;
			File pluginFolder = parameterMap.containsKey("pluginFolder")?new File(parameterMap.get("pluginFolder")):null;
			Agent agent = new Agent(instrumentation, clientHost, port, pluginFolder);
			agent.start();
		} catch(Exception e) {
			System.out.println("Agent: an error occurred while trying to parse the agent parameters.");
			e.printStackTrace();
		}
	}
	
	protected Agent(Instrumentation instrumentation, String host, Integer port) {
		this(instrumentation, host, port, null);
	}
	
	protected Agent(Instrumentation instrumentation, String host, Integer port, File pluginFolder) {
		super();
		this.port = port!=null?port:DEFAULT_PORT;
		this.clientHost = host;
		this.instrumentation = instrumentation;
		this.agentToClientConnection = clientHost!=null;
		this.pluginFolder = pluginFolder;

		addCollectorToBootstrap(instrumentation);

		if(pluginFolder!=null) {
			if(pluginFolder.isDirectory()) {
				for(File file:pluginFolder.listFiles(new FileFilter() {
					@Override
					public boolean accept(File pathname) {
						return pathname.getName().endsWith(".jar");
					}
				})) {
					addJarToSystemClassLoaderSearch(instrumentation, file);
				}
			}
		}
	}

	private void addCollectorToBootstrap(Instrumentation instrumentation) {
		try {
			InputStream is = getClass().getClassLoader().getResourceAsStream("collector.jar");
			File collectorJar = File.createTempFile("collector-"+UUID.randomUUID(),".jar");
			FileOutputStream os = new FileOutputStream(collectorJar);		
			byte[] buffer = new byte[1024];
            int bytesRead;
            while((bytesRead = is.read(buffer)) !=-1){
                os.write(buffer, 0, bytesRead);
            }
            is.close();
            os.flush();
            os.close();
            
            addJarToBootstrapClassloader(instrumentation, collectorJar);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}


	private void addJarToBootstrapClassloader(Instrumentation instrumentation, File collectorJar) {
		System.out.println("Adding " + collectorJar + " to bootstrap search.");
		try {
			instrumentation.appendToBootstrapClassLoaderSearch(new JarFile(collectorJar));
		} catch (IOException e) {
			System.err.println("Agent: error while trying to add file "+collectorJar.getName()+" to bootstrap classloader");
			e.printStackTrace();
		}
	}
	
	private void addJarToSystemClassLoaderSearch(Instrumentation instrumentation, File collectorJar) {
		System.out.println("Adding " + collectorJar + " to system search.");
		try {
			instrumentation.appendToSystemClassLoaderSearch(new JarFile(collectorJar));
		} catch (IOException e) {
			System.err.println("Agent: error while trying to add file "+collectorJar.getName()+" to bootstrap classloader");
			e.printStackTrace();
{'fraction_non_alphanumeric': 0.13768115942028986, 'fraction_numerical': 0.004326195111399524, 'mean_word_length': 4.25099375354912, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5758862', 'n_tokens_mistral': 2854, 'n_tokens_neox': 2515, 'n_words': 692}