/*
* Copyright (c) 2012 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.management.jmx.logging;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Scanner;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AgentInitializationException;
public class LoggingOps {
private static final Logger log = LoggerFactory.getLogger(LoggingOps.class);
private static final String CONNECTOR_ADDRESS =
"com.sun.management.jmxremote.localConnectorAddress";
private static final String PID_PATTERN = "/var/run/storageos/%s.pid";
public static void setLevel(String logName, String level, int expirInMin, String scope)
throws IllegalStateException {
JMXConnector conn = initJMXConnector(logName);
try {
Object[] params = { level, expirInMin, scope };
String[] sigs = { "java.lang.String", "int", "java.lang.String" };
initMBeanServerConnection(conn).invoke(initObjectName(), LoggingMBean.OPERATION_SET,
params, sigs);
} catch (IOException e) {
throw new IllegalStateException("IOException", e);
} catch (MBeanException e) {
throw new IllegalStateException("MBeanException", e);
} catch (InstanceNotFoundException e) {
throw new IllegalStateException("InstanceNotFoundException", e);
} catch (ReflectionException e) {
throw new IllegalStateException("ReflectionException", e);
} finally {
close(conn);
}
}
public static String getLevel(String logName) throws IllegalStateException {
JMXConnector conn = initJMXConnector(logName);
try {
return (String) initMBeanServerConnection(conn).getAttribute(initObjectName(),
LoggingMBean.ATTRIBUTE_NAME);
} catch (IOException e) {
throw new IllegalStateException("IOException", e);
} catch (MBeanException e) {
throw new IllegalStateException("MBeanException", e);
} catch (AttributeNotFoundException e) {
throw new IllegalStateException("AttributeNotFoundException", e);
} catch (InstanceNotFoundException e) {
throw new IllegalStateException("InstanceNotFoundException", e);
} catch (ReflectionException e) {
throw new IllegalStateException("ReflectionException", e);
} finally {
close(conn);
}
}
private static ObjectName initObjectName() {
try {
return new ObjectName(LoggingMBean.MBEAN_NAME);
} catch (MalformedObjectNameException e) {
throw new IllegalStateException("Invalid object name", e);
}
}
private static JMXConnector initJMXConnector(String logName) throws IllegalStateException {
VirtualMachine vm = null;
Scanner scanner = null;
String logPidFileName = String.format(PID_PATTERN, logName);
try {
scanner = new Scanner(new File(logPidFileName));
int pid = scanner.nextInt();
log.debug("Got pid {} from pid file {}", pid, logPidFileName);
vm = VirtualMachine.attach(String.valueOf(pid));
String connectorAddress =
vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
if (connectorAddress == null) {
String agent = vm.getSystemProperties().getProperty("java.home") +
File.separator + "lib" + File.separator +
"management-agent.jar";
vm.loadAgent(agent);
connectorAddress =
vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
}
JMXServiceURL serviceURL = new JMXServiceURL(connectorAddress);
return JMXConnectorFactory.connect(serviceURL);
} catch (FileNotFoundException e) {
throw new IllegalStateException("Cannot find file " + logPidFileName, e);
} catch (MalformedURLException e) {
throw new IllegalStateException("MalformedURLException:", e);
} catch (IOException e) {
throw new IllegalStateException("IOException when getting the MBean server"
+ "connection:", e);
} catch (AttachNotSupportedException e) {
throw new IllegalStateException("Process cannot be attached:", e);
} catch (AgentLoadException e) {
throw new IllegalStateException("Failed to load agent:", e);
} catch (AgentInitializationException e) {
throw new IllegalStateException("Failed to initialize agent:", e);
} finally {
if (scanner != null) {
scanner.close();
}
if (vm != null) {
try {
vm.detach();
} catch (IOException e) {
throw new IllegalStateException("IOException when detaching vm:", e);
}
}
}
}
private static MBeanServerConnection initMBeanServerConnection(JMXConnector conn) {
if (conn == null) {
throw new IllegalStateException("null JMXConnector");
}
try {
MBeanServerConnection mbsc = conn.getMBeanServerConnection();
if (mbsc == null) {
throw new IllegalStateException("null MBeanServerConnection");
}
return mbsc;
} catch (IOException e) {
throw new IllegalStateException("Failed to get MBeanServerConnection:", e);
}
}
private static void close(JMXConnector conn) {
if (conn != null) {
try {
conn.close();
} catch (IOException e) {
log.error("IOException when closing JMX connector:", e);
}
}
}
}