You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/05/29 19:22:12 UTC
[19/27] incubator-brooklyn git commit: Adds performance counters
Adds performance counters
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/fbb4ce9c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/fbb4ce9c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/fbb4ce9c
Branch: refs/heads/master
Commit: fbb4ce9ca9f0077c19a88b8dc1410f69d0d56dd5
Parents: 902f97e
Author: Martin Harris <gi...@nakomis.com>
Authored: Wed May 13 08:58:30 2015 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Thu May 28 17:27:35 2015 +0100
----------------------------------------------------------------------
.../windows/WindowsPerformanceCounterFeed.java | 142 ++++++++++++++-----
.../WindowsPerformanceCounterPollConfig.java | 1 +
.../basic/VanillaWindowsProcessWinRmDriver.java | 3 +-
.../winrm/WindowsPerformanceCounterSensors.java | 74 ++++++++++
4 files changed, 181 insertions(+), 39 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fbb4ce9c/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java b/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
index 468af57..35ffa93 100644
--- a/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
+++ b/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
@@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.math.BigInteger;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
@@ -38,30 +39,35 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
import brooklyn.entity.basic.ConfigKeys;
import brooklyn.entity.basic.EntityInternal;
import brooklyn.entity.basic.EntityLocal;
import brooklyn.entity.effector.EffectorTasks;
import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
import brooklyn.event.feed.AbstractFeed;
import brooklyn.event.feed.PollHandler;
import brooklyn.event.feed.Poller;
import brooklyn.event.feed.ssh.SshPollValue;
import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.location.basic.WinRmMachineLocation;
import brooklyn.management.ExecutionContext;
import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.guava.Maybe;
import brooklyn.util.task.ssh.SshTasks;
import brooklyn.util.task.system.ProcessTaskFactory;
import brooklyn.util.task.system.ProcessTaskWrapper;
import brooklyn.util.time.Duration;
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.reflect.TypeToken;
@@ -98,10 +104,11 @@ public class WindowsPerformanceCounterFeed extends AbstractFeed {
// This pattern matches CSV line(s) with the date in the first field, and at least one further field.
protected static final Pattern lineWithPerfData = Pattern.compile("^\"[\\d:/\\-. ]+\",\".*\"$", Pattern.MULTILINE);
private static final Joiner JOINER_ON_SPACE = Joiner.on(' ');
+ private static final Joiner JOINER_ON_COMMA = Joiner.on(',');
@SuppressWarnings("serial")
- public static final ConfigKey<Set<WindowsPerformanceCounterPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
- new TypeToken<Set<WindowsPerformanceCounterPollConfig<?>>>() {},
+ public static final ConfigKey<List<WindowsPerformanceCounterPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
+ new TypeToken<List<WindowsPerformanceCounterPollConfig<?>>>() {},
"polls");
public static Builder builder() {
@@ -133,7 +140,7 @@ public class WindowsPerformanceCounterFeed extends AbstractFeed {
return this;
}
public Builder period(Duration period) {
- period = checkNotNull(period, "period");
+ this.period = checkNotNull(period, "period");
return this;
}
public Builder period(long millis) {
@@ -166,7 +173,7 @@ public class WindowsPerformanceCounterFeed extends AbstractFeed {
}
protected WindowsPerformanceCounterFeed(Builder builder) {
- Set<WindowsPerformanceCounterPollConfig<?>> polls = Sets.newLinkedHashSet();
+ List<WindowsPerformanceCounterPollConfig<?>> polls = Lists.newArrayList();
for (WindowsPerformanceCounterPollConfig<?> config : builder.polls) {
@SuppressWarnings({ "unchecked", "rawtypes" })
WindowsPerformanceCounterPollConfig<?> configCopy = new WindowsPerformanceCounterPollConfig(config);
@@ -179,50 +186,50 @@ public class WindowsPerformanceCounterFeed extends AbstractFeed {
@Override
protected void preStart() {
- Set<WindowsPerformanceCounterPollConfig<?>> polls = getConfig(POLLS);
+ List<WindowsPerformanceCounterPollConfig<?>> polls = getConfig(POLLS);
long minPeriod = Integer.MAX_VALUE;
- SortedSet<String> performanceCounterNames = Sets.newTreeSet();
+ List<String> performanceCounterNames = Lists.newArrayList();
for (WindowsPerformanceCounterPollConfig<?> config : polls) {
minPeriod = Math.min(minPeriod, config.getPeriod());
performanceCounterNames.add(config.getPerformanceCounterName());
}
- SshMachineLocation machine = EffectorTasks.getSshMachine(getEntity());
Iterable<String> allParams = ImmutableList.<String>builder()
- .add("typeperf")
- .addAll(Iterables.transform(performanceCounterNames, QuoteStringFunction.INSTANCE))
- .add("-sc")
- .add("1")
+ .add("Get-Counter")
+ .add("-Counter")
+ .add(JOINER_ON_COMMA.join(Iterables.transform(performanceCounterNames, QuoteStringFunction.INSTANCE)))
+ .add("-SampleInterval")
+ .add("2") // TODO: This should be a config key
.build();
- String command = JOINER_ON_SPACE.join(allParams);
+ String command = String.format("(%s).CounterSamples.CookedValue", JOINER_ON_SPACE.join(allParams));
log.debug("Windows performance counter poll command will be: {}", command);
-
- final ProcessTaskFactory<Integer> taskFactory = SshTasks.newSshExecTaskFactory(machine, command)
- .allowingNonZeroExitCode()
- .runAsCommand();
-
- final Callable<SshPollValue> queryForCounterValues = new Callable<SshPollValue>() {
- public SshPollValue call() throws Exception {
- ProcessTaskWrapper<Integer> taskWrapper = taskFactory.newTask();
- final ExecutionContext executionContext =
- ((EntityInternal) entity).getManagementSupport().getExecutionContext();
- executionContext.submit(taskWrapper);
- taskWrapper.block();
- Optional<Integer> exitCode = Optional.fromNullable(taskWrapper.getExitCode());
- return new SshPollValue(null, exitCode.or(-1), taskWrapper.getStdout(), taskWrapper.getStderr());
- }
- };
- getPoller().scheduleAtFixedRate(
- new CallInEntityExecutionContext<SshPollValue>(entity, queryForCounterValues),
- new SendPerfCountersToSensors(entity, polls),
- minPeriod);
+ getPoller().scheduleAtFixedRate(new GetPerformanceCountersJob<WinRmToolResponse>(getEntity(), command),
+ new SendPerfCountersToSensors(getEntity(), getConfig(POLLS)), 100L);
+ }
+
+ private static class GetPerformanceCountersJob<T> implements Callable<T> {
+
+ private final Entity entity;
+ private final String command;
+
+ GetPerformanceCountersJob(Entity entity, String command) {
+ this.entity = entity;
+ this.command = command;
+ }
+
+ @Override
+ public T call() throws Exception {
+ WinRmMachineLocation machine = EffectorTasks.getWinRmMachine(entity);
+ WinRmToolResponse response = machine.executePsScript(command);
+ return (T)response;
+ }
}
@SuppressWarnings("unchecked")
- protected Poller<SshPollValue> getPoller() {
- return (Poller<SshPollValue>) super.getPoller();
+ protected Poller<WinRmToolResponse> getPoller() {
+ return (Poller<WinRmToolResponse>) super.getPoller();
}
/**
@@ -251,10 +258,71 @@ public class WindowsPerformanceCounterFeed extends AbstractFeed {
}
}
+ private static class SendPerfCountersToSensors implements PollHandler<WinRmToolResponse> {
+
+ private final EntityLocal entity;
+ private final List<WindowsPerformanceCounterPollConfig<?>> polls;
+
+ public SendPerfCountersToSensors(EntityLocal entity, List<WindowsPerformanceCounterPollConfig<?>> polls) {
+ this.entity = entity;
+ this.polls = polls;
+ }
+
+ @Override
+ public boolean checkSuccess(WinRmToolResponse val) {
+ if (val.getStatusCode() != 0) return false;
+ String stderr = val.getStdErr();
+ if (stderr == null || stderr.length() != 0) return false;
+ String out = val.getStdOut();
+ if (out == null || out.length() == 0) return false;
+ return true;
+ }
+
+ @Override
+ public void onSuccess(WinRmToolResponse val) {
+ String[] values = val.getStdOut().split("\r\n");
+ for (int i = 0; i < polls.size(); i++) {
+ Class<?> clazz = polls.get(i).getSensor().getType();
+ Maybe<? extends Object> maybeValue = TypeCoercions.tryCoerce(values[i], TypeToken.of(clazz));
+ Object value = maybeValue.isAbsent() ? null : maybeValue.get();
+ AttributeSensor<Object> attribute = (AttributeSensor<Object>) Sensors.newSensor(clazz, polls.get(i).getSensor().getName(), polls.get(i).getDescription());
+ entity.setAttribute(attribute, value);
+ }
+ }
+
+ @Override
+ public void onFailure(WinRmToolResponse val) {
+ log.error("Windows Performance Counter query did not respond as expected. exitcode={} stdout={} stderr={}",
+ new Object[]{val.getStatusCode(), val.getStdOut(), val.getStdErr()});
+ for (WindowsPerformanceCounterPollConfig<?> config : polls) {
+ entity.setAttribute(Sensors.newSensor(config.getSensor().getClass(), config.getPerformanceCounterName(), config.getDescription()), null);
+ }
+ }
+
+ @Override
+ public void onException(Exception exception) {
+ log.error("Detected exception while retrieving Windows Performance Counters from entity " +
+ entity.getDisplayName(), exception);
+ for (WindowsPerformanceCounterPollConfig<?> config : polls) {
+ entity.setAttribute(Sensors.newSensor(config.getSensor().getClass(), config.getPerformanceCounterName(), config.getDescription()), null);
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "" + polls;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString()+"["+getDescription()+"]";
+ }
+ }
+
/**
* A poll handler that takes the result of the <tt>typeperf</tt> invocation and sets the appropriate sensors.
*/
- private static class SendPerfCountersToSensors implements PollHandler<SshPollValue> {
+ private static class SendPerfCountersToSensors2 implements PollHandler<SshPollValue> {
private static final Set<? extends Class<? extends Number>> INTEGER_TYPES
= ImmutableSet.of(Integer.class, Long.class, Byte.class, Short.class, BigInteger.class);
@@ -262,7 +330,7 @@ public class WindowsPerformanceCounterFeed extends AbstractFeed {
private final EntityLocal entity;
private final SortedMap<String, AttributeSensor> sensorMap;
- public SendPerfCountersToSensors(EntityLocal entity, Set<WindowsPerformanceCounterPollConfig<?>> polls) {
+ public SendPerfCountersToSensors2(EntityLocal entity, List<WindowsPerformanceCounterPollConfig<?>> polls) {
this.entity = entity;
sensorMap = Maps.newTreeMap();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fbb4ce9c/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterPollConfig.java b/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterPollConfig.java
index a5d2abd..77681ea 100644
--- a/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterPollConfig.java
+++ b/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterPollConfig.java
@@ -31,6 +31,7 @@ public class WindowsPerformanceCounterPollConfig<T> extends PollConfig<Object, T
@SuppressWarnings({ "unchecked", "rawtypes" })
public WindowsPerformanceCounterPollConfig(AttributeSensor<T> sensor) {
super(sensor);
+ description(sensor.getDescription());
onSuccess((Function)Functions.identity());
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fbb4ce9c/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
index a5c91db..4e66180 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
@@ -19,7 +19,6 @@
package brooklyn.entity.basic;
import brooklyn.location.basic.WinRmMachineLocation;
-import brooklyn.util.time.Duration;
public class VanillaWindowsProcessWinRmDriver extends AbstractSoftwareProcessWinRmDriver implements VanillaWindowsProcessDriver {
@@ -47,7 +46,7 @@ public class VanillaWindowsProcessWinRmDriver extends AbstractSoftwareProcessWin
@Override
public boolean isRunning() {
return executeCommand(VanillaWindowsProcess.CHECK_RUNNING_COMMAND,
- VanillaWindowsProcess.CHECK_RUNNING_POWERSHELL_COMMAND, false);
+ VanillaWindowsProcess.CHECK_RUNNING_POWERSHELL_COMMAND, false).getStatusCode() == 0;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fbb4ce9c/software/base/src/main/java/brooklyn/entity/software/winrm/WindowsPerformanceCounterSensors.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/winrm/WindowsPerformanceCounterSensors.java b/software/base/src/main/java/brooklyn/entity/software/winrm/WindowsPerformanceCounterSensors.java
new file mode 100644
index 0000000..e36d285
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/software/winrm/WindowsPerformanceCounterSensors.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.entity.software.winrm;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.proxying.EntityInitializer;
+import brooklyn.event.basic.Sensors;
+import brooklyn.event.feed.windows.WindowsPerformanceCounterFeed;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.text.Strings;
+
+import com.google.common.reflect.TypeToken;
+
+public class WindowsPerformanceCounterSensors implements EntityInitializer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(WindowsPerformanceCounterSensors.class);
+
+ public final static ConfigKey<Set<Map<String, String>>> PERFORMANCE_COUNTERS = ConfigKeys.newConfigKey(new TypeToken<Set<Map<String, String>>>(){}, "performance.counters");
+
+ protected final Set<Map<String, String>> sensors;
+
+ public WindowsPerformanceCounterSensors(ConfigBag params) {
+ sensors = params.get(PERFORMANCE_COUNTERS);
+ }
+
+ public WindowsPerformanceCounterSensors(Map<String, String> params) {
+ this(ConfigBag.newInstance(params));
+ }
+
+ @Override
+ public void apply(EntityLocal entity) {
+ WindowsPerformanceCounterFeed.Builder builder = WindowsPerformanceCounterFeed.builder()
+ .entity(entity);
+ for (Map<String, String> sensorConfig : sensors) {
+ String sensorType = sensorConfig.get("sensorType");
+ Class<?> clazz;
+ try {
+ clazz = Strings.isNonEmpty(sensorType) ?
+ ((EntityInternal)entity).getManagementContext().getCatalog().getRootClassLoader().loadClass(sensorType) : String.class;
+ } catch (ClassNotFoundException e) {
+ LOG.warn("Could not load type {} for sensor {}", sensorType, sensorConfig.get("name"));
+ clazz = String.class;
+ }
+ builder.addSensor(sensorConfig.get("counter"), Sensors.newSensor(clazz, sensorConfig.get("name"), sensorConfig.get("description")));
+ }
+ builder.build();
+ }
+
+}