/* * Copyright 2014 Netflix, Inc. * * Licensed 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 com.netflix.servo.publish; import com.netflix.servo.Metric; import com.netflix.servo.annotations.DataSourceType; import com.netflix.servo.annotations.Monitor; import com.netflix.servo.annotations.MonitorTags; import com.netflix.servo.tag.BasicTagList; import com.netflix.servo.tag.StandardTagKeys; import com.netflix.servo.tag.Tag; import com.netflix.servo.tag.TagList; import com.netflix.servo.tag.Tags; import com.netflix.servo.util.Preconditions; import com.netflix.servo.util.Throwables; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * Helper class for metric observers that keeps track of the number of calls * and number of failures. */ public abstract class BaseMetricObserver implements MetricObserver { @MonitorTags private final TagList tags; private final String name; /** * Total number of times update has been called. */ @Monitor(name = "updateCount", type = DataSourceType.COUNTER) private final AtomicInteger updateCount = new AtomicInteger(0); /** * Number of times update failed with an exception. */ @Monitor(name = "updateFailureCount", type = DataSourceType.COUNTER) private final AtomicInteger failedUpdateCount = new AtomicInteger(0); /** * Creates a new instance with a given name. */ public BaseMetricObserver(String name) { final Tag id = Tags.newTag(StandardTagKeys.MONITOR_ID.getKeyName(), name); this.name = Preconditions.checkNotNull(name, "name"); this.tags = BasicTagList.of(id); } /** * Update method that should be defined by sub-classes. This method will * get invoked and counts will be maintained in the base observer. */ public abstract void updateImpl(List<Metric> metrics); /** * {@inheritDoc} */ public final void update(List<Metric> metrics) { Preconditions.checkNotNull(metrics, "metrics"); try { updateImpl(metrics); } catch (Throwable t) { failedUpdateCount.incrementAndGet(); throw Throwables.propagate(t); } finally { updateCount.incrementAndGet(); } } /** * {@inheritDoc} */ public final String getName() { return name; } /** * Can be used by sub-classes to increment the failed count if they handle * exception internally. */ protected final void incrementFailedCount() { failedUpdateCount.incrementAndGet(); } /** * Returns the total number of times update has been called. */ public int getUpdateCount() { return updateCount.get(); } /** * Returns the number of times update failed with an exception. */ public int getFailedUpdateCount() { return failedUpdateCount.get(); } }