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 */
018
019package org.apache.oozie.service;
020
021import org.apache.oozie.util.Instrumentation;
022import org.apache.oozie.util.XLog;
023import org.apache.oozie.ErrorCode;
024
025import java.util.Map;
026
027
028/**
029 * This service provides an {@link Instrumentation} instance configured to support samplers. <p> This service depends
030 * on the {@link SchedulerService}. <p> The {@link #CONF_LOGGING_INTERVAL} configuration property indicates how often
031 * snapshots of the instrumentation should be logged.
032 * @deprecated since 5.0.0
033 */
034@Deprecated
035public class InstrumentationService implements Service {
036    private static final String JVM_INSTRUMENTATION_GROUP = "jvm";
037
038    public static final String CONF_PREFIX = Service.CONF_PREFIX + "InstrumentationService.";
039
040    public static final String CONF_LOGGING_INTERVAL = CONF_PREFIX + "logging.interval";
041
042    private final XLog log = XLog.getLog(XLog.INSTRUMENTATION_LOG_NAME);
043
044    protected static Instrumentation instrumentation = null;
045
046    private static boolean isEnabled = false;
047
048    /**
049     * Initialize the instrumentation service.
050     *
051     * @param services services instance.
052     */
053    @Override
054    public void init(Services services) throws ServiceException {
055        final Instrumentation instr = new Instrumentation();
056        int interval = ConfigurationService.getInt(services.getConf(), CONF_LOGGING_INTERVAL);
057        initLogging(services, instr, interval);
058        instr.addVariable(JVM_INSTRUMENTATION_GROUP, "free.memory", new Instrumentation.Variable<Long>() {
059            @Override
060            public Long getValue() {
061                return Runtime.getRuntime().freeMemory();
062            }
063        });
064        instr.addVariable(JVM_INSTRUMENTATION_GROUP, "max.memory", new Instrumentation.Variable<Long>() {
065            @Override
066            public Long getValue() {
067                return Runtime.getRuntime().maxMemory();
068            }
069        });
070        instr.addVariable(JVM_INSTRUMENTATION_GROUP, "total.memory", new Instrumentation.Variable<Long>() {
071            @Override
072            public Long getValue() {
073                return Runtime.getRuntime().totalMemory();
074            }
075        });
076        instrumentation = instr;
077        isEnabled = true;
078    }
079
080    void initLogging(Services services, final Instrumentation instr, int interval) throws ServiceException {
081        log.info("*********** Startup ***********");
082        log.info("Java System Properties: {E}{0}", mapToString(instr.getJavaSystemProperties()));
083        log.info("OS Env: {E}{0}", mapToString(instr.getOSEnv()));
084        SchedulerService schedulerService = services.get(SchedulerService.class);
085        if (schedulerService != null) {
086            instr.setScheduler(schedulerService.getScheduler());
087            if (interval > 0) {
088                Runnable instrumentationLogger = new Runnable() {
089                    @Override
090                    public void run() {
091                        try {
092                            log.info("\n" + instr.toString());
093                        }
094                        catch (Throwable ex) {
095                            log.warn("Instrumentation logging error", ex);
096                        }
097                    }
098                };
099                schedulerService.schedule(instrumentationLogger, interval, interval, SchedulerService.Unit.SEC);
100            }
101        }
102        else {
103            throw new ServiceException(ErrorCode.E0100, getClass().getName(), "SchedulerService unavailable");
104        }
105    }
106
107    private String mapToString(Map<String, String> map) {
108        String E = System.getProperty("line.separator");
109        StringBuilder sb = new StringBuilder();
110
111        for (Map.Entry<String, String> entry : map.entrySet()) {
112            sb.append("    ").append(entry.getKey()).append(" = ").append(entry.getValue()).append(E);
113        }
114
115        return sb.toString();
116    }
117
118    /**
119     * Destroy the instrumentation service.
120     */
121    @Override
122    public void destroy() {
123        isEnabled = false;
124        instrumentation = null;
125    }
126
127    /**
128     * Return the public interface for instrumentation service.
129     *
130     * @return {@link InstrumentationService}.
131     */
132    @Override
133    public Class<? extends Service> getInterface() {
134        return InstrumentationService.class;
135    }
136
137    /**
138     * Return the instrumentation instance used by the service.
139     *
140     * @return the instrumentation instance.
141     */
142    public Instrumentation get() {
143        return instrumentation;
144    }
145
146    /**
147     * Returns if the InstrumentationService is enabled or not.
148     *
149     * @return true if the InstrumentationService is enabled; false if not
150     */
151    public static boolean isEnabled() {
152        return isEnabled;
153    }
154}