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