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 }