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