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(XLog.INSTRUMENTATION_LOG_NAME); 040 041 protected static Instrumentation instrumentation = null; 042 043 private static boolean isEnabled = false; 044 045 /** 046 * Initialize the instrumentation service. 047 * 048 * @param services services instance. 049 */ 050 @Override 051 public void init(Services services) throws ServiceException { 052 final Instrumentation instr = new Instrumentation(); 053 int interval = services.getConf().getInt(CONF_LOGGING_INTERVAL, 60); 054 initLogging(services, instr, interval); 055 instr.addVariable(JVM_INSTRUMENTATION_GROUP, "free.memory", new Instrumentation.Variable<Long>() { 056 @Override 057 public Long getValue() { 058 return Runtime.getRuntime().freeMemory(); 059 } 060 }); 061 instr.addVariable(JVM_INSTRUMENTATION_GROUP, "max.memory", new Instrumentation.Variable<Long>() { 062 @Override 063 public Long getValue() { 064 return Runtime.getRuntime().maxMemory(); 065 } 066 }); 067 instr.addVariable(JVM_INSTRUMENTATION_GROUP, "total.memory", new Instrumentation.Variable<Long>() { 068 @Override 069 public Long getValue() { 070 return Runtime.getRuntime().totalMemory(); 071 } 072 }); 073 instrumentation = instr; 074 isEnabled = true; 075 } 076 077 protected void initLogging(Services services, final Instrumentation instr, int interval) throws ServiceException { 078 log.info("*********** Startup ***********"); 079 log.info("Java System Properties: {E}{0}", mapToString(instr.getJavaSystemProperties())); 080 log.info("OS Env: {E}{0}", mapToString(instr.getOSEnv())); 081 SchedulerService schedulerService = services.get(SchedulerService.class); 082 if (schedulerService != null) { 083 instr.setScheduler(schedulerService.getScheduler()); 084 if (interval > 0) { 085 Runnable instrumentationLogger = new Runnable() { 086 @Override 087 public void run() { 088 try { 089 log.info("\n" + instr.toString()); 090 } 091 catch (Throwable ex) { 092 log.warn("Instrumentation logging error", ex); 093 } 094 } 095 }; 096 schedulerService.schedule(instrumentationLogger, interval, interval, SchedulerService.Unit.SEC); 097 } 098 } 099 else { 100 throw new ServiceException(ErrorCode.E0100, getClass().getName(), "SchedulerService unavailable"); 101 } 102 } 103 104 protected String mapToString(Map<String, String> map) { 105 String E = System.getProperty("line.separator"); 106 StringBuilder sb = new StringBuilder(); 107 for (Map.Entry<String, String> entry : map.entrySet()) { 108 sb.append(" ").append(entry.getKey()).append(" = ").append(entry.getValue()).append(E); 109 } 110 return sb.toString(); 111 } 112 113 /** 114 * Destroy the instrumentation service. 115 */ 116 @Override 117 public void destroy() { 118 isEnabled = false; 119 instrumentation = null; 120 } 121 122 /** 123 * Return the public interface for instrumentation service. 124 * 125 * @return {@link InstrumentationService}. 126 */ 127 @Override 128 public Class<? extends Service> getInterface() { 129 return InstrumentationService.class; 130 } 131 132 /** 133 * Return the instrumentation instance used by the service. 134 * 135 * @return the instrumentation instance. 136 */ 137 public Instrumentation get() { 138 return instrumentation; 139 } 140 141 /** 142 * Returns if the InstrumentationService is enabled or not. 143 * 144 * @return true if the InstrumentationService is enabled; false if not 145 */ 146 public static boolean isEnabled() { 147 return isEnabled; 148 } 149}