/*
* Copyright 2013 Eediom Inc.
*
* Licensed 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.araqne.logdb.jmx;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXServiceURL;
import org.araqne.log.api.AbstractLogger;
import org.araqne.log.api.Log;
import org.araqne.log.api.LoggerFactory;
import org.araqne.log.api.LoggerSpecification;
import org.araqne.log.api.Reconfigurable;
import org.araqne.log.api.SimpleLog;
public class RemoteJmxLogger extends AbstractLogger implements Reconfigurable {
private final org.slf4j.Logger slog = org.slf4j.LoggerFactory.getLogger(RemoteJmxLogger.class);
private String user;
private String password;
private JMXServiceURL url;
private ObjectName objName;
private String[] attrNames;
public RemoteJmxLogger(LoggerSpecification spec, LoggerFactory factory) throws IOException {
super(spec, factory);
init(spec.getConfig());
}
private void init(Map<String, String> c) throws IOException {
String[] attrNames = null;
String s = c.get("attr_names");
if (s != null) {
ArrayList<String> l = new ArrayList<String>();
for (String t : s.split(",")) {
t = t.trim();
if (!t.isEmpty())
l.add(t);
}
attrNames = l.toArray(new String[0]);
}
ObjectName objName;
try {
objName = new ObjectName(c.get("obj_name"));
} catch (Exception e) {
throw new IOException("invalid jmx object name: " + c.get("obj_name"), e);
}
this.url = JmxHelper.getURL(c.get("host"), Integer.parseInt(c.get("port")));
this.user = c.get("user");
this.password = c.get("password");
this.attrNames = attrNames;
this.objName = objName;
}
@Override
public void onConfigChange(Map<String, String> oldConfigs, Map<String, String> newConfigs) {
try {
init(newConfigs);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
@Override
protected void runOnce() {
JMXConnector jmxConnector = null;
try {
jmxConnector = JmxHelper.connect(url, user, password);
MBeanServerConnection mbeanConn = jmxConnector.getMBeanServerConnection();
String[] names = attrNames;
if (names == null)
names = JmxHelper.getAttributeNames(mbeanConn, objName);
AttributeList attrs = mbeanConn.getAttributes(objName, names);
Log log = buildLog(attrs);
write(log);
setTemporaryFailure(null);
} catch (Throwable t) {
setTemporaryFailure(t);
slog.error("araqne log api: remote jmx failed, logger " + getFullName(), t);
} finally {
if (jmxConnector != null) {
try {
jmxConnector.close();
} catch (IOException e) {
}
}
}
}
private Log buildLog(AttributeList attrs) {
Map<String, Object> data = new HashMap<String, Object>();
for (Attribute attr : attrs.asList()) {
Object value = attr.getValue();
if (value instanceof Boolean || value instanceof Long || value instanceof Integer || value instanceof Short
|| value instanceof Float || value instanceof Double || value instanceof String) {
data.put(attr.getName(), value);
} else if (value != null) {
data.put(attr.getName(), value.toString());
} else {
data.put(attr.getName(), null);
}
}
return new SimpleLog(new Date(), getFullName(), data);
}
}