001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 * 
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.oozie.service;
019
020import org.apache.oozie.util.Instrumentation;
021import org.apache.oozie.util.XLog;
022import org.apache.oozie.ErrorCode;
023
024import java.util.Map;
025
026
027/**
028 * This service provides an {@link Instrumentation} instance configured to support samplers. <p/> This service depends
029 * on the {@link SchedulerService}. <p/> The {@link #CONF_LOGGING_INTERVAL} configuration property indicates how often
030 * snapshots of the instrumentation should be logged.
031 */
032public class InstrumentationService implements Service {
033    private static final String JVM_INSTRUMENTATION_GROUP = "jvm";
034
035    public static final String CONF_PREFIX = Service.CONF_PREFIX + "InstrumentationService.";
036
037    public static final String CONF_LOGGING_INTERVAL = CONF_PREFIX + "logging.interval";
038
039    private final XLog log = XLog.getLog("oozieinstrumentation");
040
041    private Instrumentation instrumentation;
042
043    /**
044     * Initialize the instrumentation service.
045     *
046     * @param services services instance.
047     */
048    public void init(Services services) throws ServiceException {
049        instrumentation = new Instrumentation();
050        log.info("*********** Startup ***********");
051        log.info("Java System Properties: {E}{0}", mapToString(instrumentation.getJavaSystemProperties()));
052        log.info("OS Env: {E}{0}", mapToString(instrumentation.getOSEnv()));
053        SchedulerService schedulerService = services.get(SchedulerService.class);
054        if (schedulerService != null) {
055            instrumentation.setScheduler(schedulerService.getScheduler());
056            int interval = services.getConf().getInt(CONF_LOGGING_INTERVAL, 60);
057            if (interval > 0) {
058                Runnable instrumentationLogger = new Runnable() {
059                    public void run() {
060                        try {
061                            log.info("\n" + instrumentation.toString());
062                        }
063                        catch (Throwable ex) {
064                            log.warn("Instrumentation logging error", ex);
065                        }
066                    }
067                };
068                schedulerService.schedule(instrumentationLogger, interval, interval, SchedulerService.Unit.SEC);
069            }
070        }
071        else {
072            throw new ServiceException(ErrorCode.E0100, getClass().getName(), "SchedulerService unavailable");
073        }
074        instrumentation.addVariable(JVM_INSTRUMENTATION_GROUP, "free.memory", new Instrumentation.Variable<Long>() {
075            public Long getValue() {
076                return Runtime.getRuntime().freeMemory();
077            }
078        });
079        instrumentation.addVariable(JVM_INSTRUMENTATION_GROUP, "max.memory", new Instrumentation.Variable<Long>() {
080            public Long getValue() {
081                return Runtime.getRuntime().maxMemory();
082            }
083        });
084        instrumentation.addVariable(JVM_INSTRUMENTATION_GROUP, "total.memory", new Instrumentation.Variable<Long>() {
085            public Long getValue() {
086                return Runtime.getRuntime().totalMemory();
087            }
088        });
089    }
090
091    private String mapToString(Map<String, String> map) {
092        String E = System.getProperty("line.separator");
093        StringBuilder sb = new StringBuilder();
094        for (Map.Entry<String, String> entry : map.entrySet()) {
095            sb.append("    ").append(entry.getKey()).append(" = ").append(entry.getValue()).append(E);
096        }
097        return sb.toString();
098    }
099
100    /**
101     * Destroy the instrumentation service.
102     */
103    public void destroy() {
104        instrumentation = null;
105    }
106
107    /**
108     * Return the public interface for instrumentation service.
109     *
110     * @return {@link InstrumentationService}.
111     */
112    public Class<? extends Service> getInterface() {
113        return InstrumentationService.class;
114    }
115
116    /**
117     * Return the instrumentation instance used by the service.
118     *
119     * @return the instrumentation instance.
120     */
121    public Instrumentation get() {
122        return instrumentation;
123    }
124
125}